Skip to content

Refactor TcDeriv to validity-check less in anyclass/via deriving (#13154)

Ryan Scott requested to merge wip/T13154-take-two into master

Due to the way DerivEnv is currently structured, there is an invariant that every derived instance must consist of a class applied to a non-empty list of argument types, where the last argument must be an application of a type constructor to some arguments. This works for many cases, but there are also some design patterns in standalone anyclass/via deriving that are made impossible due to enforcing this invariant, as documented in #13154 (closed).

This fixes #13154 (closed) by refactoring TcDeriv and friends to perform fewer validity checks when using the anyclass or via strategies. The highlights are as followed:

  • Five fields of DerivEnv have been factored out into a new DerivInstTys data type. These fields only make sense for instances that satisfy the invariant mentioned above, so DerivInstTys is now only used in stock and newtype deriving, but not in other deriving strategies.
  • There is now a Note [DerivEnv and DerivSpecMechanism] describing the bullet point above in more detail, as well as explaining the exact requirements that each deriving strategy imposes.
  • I've refactored mkEqnHelp's call graph to be slightly less complicated. Instead of the previous mkDataTypeEqn/mkNewTypeEqn dichotomy, there is now a single entrypoint mk_eqn.
  • Various bits of code were tweaked so as not to use fields that are specific to DerivInstTys so that they may be used by all deriving strategies, since not all deriving strategies use DerivInstTys.
Edited by Ryan Scott

Merge request reports