Enable -fdicts-strict and -fdicts-cheap in optics-tests
On my machine one inspection tests starts to pass with GHC-9.10 (EDIT: because of -fdicts-cheap), I'm curious about others.
I'm somewhat surprising how much effect these flags have. But on the other hand, the affected tests seems to be the ones which we have GHC-version conditionals on them. So this illustrates that we are sometimes on the edge of GHC heuristics.
I will go through these and check if these flags make more tests pass. If so, we could argue for -fdicts-strict being in -O and/or some mechanism to make -fdicts-cheap less experimental (E.g. allowing to annotate specific classes / instances as cheap).
Opionions on that? @adamgundry
Afaik there's been an attempt to include -fdicts-strict in -O, but ultimately it landed in -O2 (https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2575), not sure exactly why since there's a lot of comments in the MR.
@arybczak I'd say that -fdicts-cheap has more impact than -fdicts-strict.
I'm not sure what -fdicts-cheap does precisely, but it's different from -funfolding-dict-discount. I think it affects lambda-floating, e.g. one test which passes on GHC-9.6.5 with -fdicts-strict, but not without has following error:
LHS:
eta6lhs
= ... let { $dFunctor = $p1Applicative $dApplicative_a1uG7 } in
let { lvl_s2eyT = $fMonoidTraversed $dApplicative_a1uG7 } in
let { lvl_s2eyU = $fApplicativeConst lvl_s2eyT } in
let { lvl_s2eq0 = $fMonoidTraversed lvl_s2eyU } in
\ f1 ->
let {
g1
= ifoldMap
$dFoldableWithIndex_a1uG8
lvl_s2eq0
((\ i1 -> f1 i1) `cast` <Co:30> :: ...) } in
\ x -> <$ $dFunctor () ((g1 x) `cast` <Co:21> :: ...)
RHS:
eta6rhs
= ... \ f ->
let { $dFunctor = $p1Applicative $dApplicative_a1uG7 } in
let {
g1
= ifoldMap
$dFoldableWithIndex_a1uG8
($fMonoidTraversed
($fApplicativeConst ($fMonoidTraversed $dApplicative_a1uG7)))
((\ i1 -> f i1) `cast` <Co:30> :: ...) } in
\ x -> <$ $dFunctor () ((g1 x) `cast` <Co:21> :: ...)
Sadly I have no idea what version -fdicts-cheap produces, but I'd expect it's to b eclosed to the RHS above, maybe even with $dFunctor pushed down inside he lambda.
EDIT: it doesn't. With -fdicts-cheap the above test looks like
eta6lhs
= \ @f_a1dVI
@i_a1dVJ
@t_a1dVK
@a_a1dVL
@r_a1dVM
$dApplicative_a1dVN
$dFoldableWithIndex_a1dVO
eta_B0 ->
let { $dFunctor_s1XCx = $p1Applicative $dApplicative_a1dVN } in
let {
g1_s1XCz
= ifoldMap
$dFoldableWithIndex_a1dVO
($fMonoidTraversed
($fApplicativeConst ($fMonoidTraversed $dApplicative_a1dVN)))
((\ i1_aOy1 -> eta_B0 i1_aOy1) `cast` <Co:30> :: ...) } in
\ x_a1Xtu ->
<$ $dFunctor_s1XCx () ((g1_s1XCz x_a1Xtu) `cast` <Co:21> :: ...)
TL;DR, at least for eta-tests -fdicts-cheap makes more stuff succeed