Skip to content

Redesign withDict (formerly magicDict), special-case it in the desugarer

Ryan Scott requested to merge wip/T16646-take-three into master

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 applies withDict at an incorrect type, the special-casing in dsHsWrapped will now throw an error message indicating what the user did incorrectly.
  • withDict can now work with classes that have multiple type arguments, such as Typeable @k a. This means that Data.Typeable.Internal.withTypeable can now be implemented in terms of withDict.
  • Since the special-casing for withDict no longer needs to match on the structure of the expression passed as an argument to withDict, it no longer cares about the presence or absence of Ticks. 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.

Edited by Ryan Scott

Merge request reports