Error message hints: use the env instead of the namespace
This ticket describes a problem related to RequiredTypeArguments
.
Background
When a type variable is used at the term level, GHC assumes the user might have made a typo and suggests a term variable with a similar name.
For example, if the user writes
f (Proxy :: Proxy nap) (Proxy :: Proxy gap) = nap (+1) [1,2,3]
then GHC will helpfully suggest map
instead of nap
• Illegal term-level use of the type variable ‘nap’
• Perhaps use ‘map’ (imported from Prelude)
Importantly, GHC does not suggest gap
, which is in scope.
-
Question: How does GHC know not to suggest
gap
? After all, the edit distance betweenmap
,nap
, andgap
is equally short. -
Answer: GHC takes the namespace into consideration.
gap
is atvName
, and GHC would only suggest avarName
at the term level.
In other words, the current hint infrastructure assumes that the namespace of an entity is a reliable indicator of its level
- term-level name <=> term-level entity
- type-level name <=> type-level entity
Problem
With RequiredTypeArguments
, the above assumption does not hold. Consider
bad :: forall a b -> ...
bad nap gap = nap
This use of nap
on the RHS is illegal because nap
stands for a type
variable. It cannot be returned as the result of a function. At the same time,
it is bound as a varName
, i.e. in the term-level namespace.
Unless we suppress hints, GHC gets awfully confused
• Illegal term-level use of the variable ‘nap’
• Perhaps use one of these:
‘nap’ (line 2), ‘gap’ (line 2), ‘map’ (imported from Prelude)
GHC shouldn't suggest gap
, which is also a type variable; using it would
result in the same error. And it especially shouldn't suggest using nap
instead of nap
, which is absurd.
Workaround
A simple workaround is to suppress the hints as long as RequiredTypeArguments
is enabled.
Naturally, this also means that error messages are less helpful with RequiredTypeArguments
,
so it's not a proper solution.
Solution
The proper solution is to overhaul the hint system to consider what a name stands for instead of looking at its namespace alone. This information is present in the type checking environment.
Plan
My plan is to go with the workaround in !11682 (closed) and implement the proper solution afterwards. This ticket is to track this task.