Skip to content
  • Ryan Scott's avatar
    Refactor TcDeriv to validity-check less in anyclass/via deriving (#13154) · cd9b9459
    Ryan Scott authored and Marge Bot's avatar Marge Bot committed
    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.
    
    This fixes #13154 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`.
    cd9b9459