Skip to content

Draft: deriving: Typecheck associated family instances before instance bindings

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

This is a significant overhaul of the way that deriving clauses and standalone deriving declarations are typechecked. The highlights:

  • Standalone deriving declarations are located in the new DerivInstD constructor of ClsInstDecl, rather than as part of the DerivD constructor of HsGroup. This move now means that standalone deriving instance declarations are located alongside other forms of instance declarations, which makes it easier to perform SCC analysis on them, as they are now part of a TyClGroup.

  • Now that everything deriving-related lives in TyClGroups, we now typecheck all of the associated type family instances that are generated from deriving clauses/declarations first (in tcTyClGroup) before typechecking any of the generated instance bindings, which happen after all of the TyClGroups have been processed. Doing so is essential to ensuring that these associated type instances are in scope when needed to typecheck other code in later TyClGroups, such as the failing examples seen in #23496. I have written an extensive Note [Staging of deriving] (previously Note [Staging of tcDeriving]) to describe how everything works.

The second bullet point above involves quite a bit of churn in the expected output of several test cases. This is for two reasons:

  1. The order in which things are printed with -ddump-deriv is now different, since deriving-related family instances are now generated earlier in the typechecker.

  2. If a test case errors out when typechecking a deriving-related family instance, then GHC will stop there before printing any errors involving the generated instance bindings. (Previously, both sorts of errors were printed simultaneously.) As such, some expected-to-fail test cases do not print out as many errors as before.

Fixes #23496.

Merge request reports