Note [Inferring the instance context]
There are two sorts of 'deriving', as represented by the two constructors
for DerivContext:
* InferContext mb_wildcard: This can either be:
- The deriving clause for a data type.
(e.g, data T a = T1 a deriving( Eq ))
In this case, mb_wildcard = Nothing.
- A standalone declaration with an extra-constraints wildcard
(e.g., deriving instance _ => Eq (Foo a))
In this case, mb_wildcard = Just loc, where loc is the location
of the extra-constraints wildcard.
Here we must infer an instance context,
and generate instance declaration
instance Eq a => Eq (T a) where ...
* SupplyContext theta: standalone deriving
deriving instance Eq a => Eq (T a)
Here we only need to fill in the bindings;
the instance context (theta) is user-supplied
For the InferContext case, we must figure out the
instance context (inferConstraintsStock). Suppose we are inferring
the instance context for
C t1 .. tn (T s1 .. sm)
There are two cases
* (T s1 .. sm) :: * (the normal case)
Then we behave like Eq and guess (C t1 .. tn t)
for each data constructor arg of type t. More
details below.
* (T s1 .. sm) :: * -> * (the functor-like case)
Then we behave like Functor.
In both cases we produce a bunch of un-simplified constraints
and them simplify them in simplifyInstanceContexts; see
Note [Simplifying the instance context].
In the functor-like case, we may need to unify some kind variables with * in
order for the generated instance to be well-kinded. An example from #10524:
newtype Compose (f :: k2 -> *) (g :: k1 -> k2) (a :: k1)
= Compose (f (g a)) deriving Functor
Earlier in the deriving pipeline, GHC unifies the kind of Compose f g
(k1 -> *) with the kind of Functor's argument (* -> *), so k1 := *. But this
alone isn't enough, since k2 wasn't unified with *:
instance (Functor (f :: k2 -> *), Functor (g :: * -> k2)) =>
Functor (Compose f g) where ...
The two Functor constraints are ill-kinded. To ensure this doesn't happen, we:
1. Collect all of a datatype's subtypes which require functor-like
constraints.
2. For each subtype, create a substitution by unifying the subtype's kind
with (* -> *).
3. Compose all the substitutions into one, then apply that substitution to
all of the in-scope type variables and the instance types. References 1
- Simplifying the instance context GHC.Tc.Deriv.Infer
Referenced by 14
- GHC.Tc.Deriv.Infer call site ×6
- GHC.Tc.Deriv call site ×2
- GHC.Tc.Deriv.Utils call site ×2
- GHC.Tc.Types.Origin call site ×2
- Instantiating field types in stock deriving GHC.Tc.Deriv.Generate
- Language.Haskell.Syntax.Decls call site