Redesign withDict (formerly magicDict), special-case it in the desugarer
This is an alternative to !5540 (closed) that special-cases withDict
in the desugarer rather than as a constant-folding rule. I'm opening this as a separate MR so that it can be compared to !5540 (closed), and when a preferred design is chosen, the other MR can be closed.
This gives a more precise type signature to magicDict
as proposed in #16646 (closed).
In addition, this replaces the constant-folding rule for magicDict
in
GHC.Core.Opt.ConstantFold
with a special case in the desugarer in
GHC.HsToCore.Expr.dsHsWrapped
. I have also renamed magicDict
to withDict
in light of the discussion in
https://mail.haskell.org/pipermail/ghc-devs/2021-April/019833.html.
All of this has the following benefits:
-
withDict
is now more type safe than before. Moreover, if a user applieswithDict
at an incorrect type, the special-casing indsHsWrapped
will now throw an error message indicating what the user did incorrectly. -
withDict
can now work with classes that have multiple type arguments, such asTypeable @k a
. This means thatData.Typeable.Internal.withTypeable
can now be implemented in terms ofwithDict
. - Since the special-casing for
withDict
no longer needs to match on the structure of the expression passed as an argument towithDict
, it no longer cares about the presence or absence ofTick
s. In effect, this obsoletes the fix for #19667 (closed).
The new T16646
test case demonstrates the new version of withDict
in
action, both in terms of base
functions defined in terms of withDict
as well as in terms of functions from the reflection
and singletons
libraries. The T16646Fail
test case demonstrates the error message that GHC
throws when withDict
is applied incorrectly.
This fixes #16646 (closed). By adding more tests for withDict
, this also
fixes #19673 (closed) as a side effect.