Note [Unobservably inferred type variables]
While GHC's parser allows the use of inferred type variables
(e.g., `forall {a}. <...>`) just about anywhere that type variable binders can
appear, there are some situations where the distinction between inferred and
specified type variables cannot be observed. For example, consider this
instance declaration:
instance forall {a}. Eq (T a) where ...
Making {a} inferred is pointless, as there is no way for user code to
"apply" an instance declaration in a way where the inferred/specified
distinction would make a difference. (Notably, there is no opportunity
for visible type application of an instance declaration.) Anyone who
writes such code is likely confused, so in an attempt to be helpful,
we emit an error message if a user writes code like this. The
checkInferredVars function is responsible for implementing this
restriction.
It turns out to be somewhat cumbersome to enforce this restriction in
certain cases. Specifically:
* Quantified constraints. In the type `f :: (forall {a}. C a) => Proxy Int`,
there is no way to observe that {a} is inferred. Nevertheless, actually
rejecting this code would be tricky, as we would need to reject
`forall {a}. <...>` as a constraint but *accept* other uses of
`forall {a}. <...>` as a type (e.g., `g :: (forall {a}. a -> a) -> b -> b`).
This is quite tedious to do in practice, so we don't bother.
* Default method type signatures (#18432). These are tricky because inferred
type variables can appear nested, e.g.,
class C a where
m :: forall b. a -> b -> forall c. c -> c
default m :: forall b. a -> b -> forall {c}. c -> c
m _ _ = id
Robustly checking for nested, inferred type variables ends up being a pain,
so we don't try to do this.
For now, we simply allow inferred quantifiers to be specified here,
even though doing so is pointless. All we lose is a warning.
Aside from the places where we already use checkInferredVars, most of
the other places where inferred vars don't make sense are in any case
already prohibited from having foralls /at all/. For example:
instance forall a. forall {b}. Eq (Either a b) where ...
Here the nested `forall {b}` is already prohibited. (See
Note [No nested foralls or contexts in instance types] in GHC.Hs.Type). References 1
- No nested foralls or contexts in instance types GHC.Hs.Type
Referenced by 1
- GHC.Rename.Utils call site