summaryrefslogtreecommitdiff
path: root/compiler/GHC/Rename/Env.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Rename/Env.hs')
-rw-r--r--compiler/GHC/Rename/Env.hs56
1 files changed, 48 insertions, 8 deletions
diff --git a/compiler/GHC/Rename/Env.hs b/compiler/GHC/Rename/Env.hs
index 0a1d7a08cd..f497792c33 100644
--- a/compiler/GHC/Rename/Env.hs
+++ b/compiler/GHC/Rename/Env.hs
@@ -1,5 +1,6 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE TypeApplications #-}
{-
(c) The GRASP/AQUA Project, Glasgow University, 1992-2006
@@ -1006,6 +1007,17 @@ lookup_demoted rdr_name
, text "instead of"
, quotes (ppr name) <> dot ]
+-- If the given RdrName can be promoted to the type level and its promoted variant is in scope,
+-- lookup_promoted returns the corresponding type-level Name.
+-- Otherwise, the function returns Nothing.
+-- See Note [Promotion] below.
+lookup_promoted :: RdrName -> RnM (Maybe Name)
+lookup_promoted rdr_name
+ | Just promoted_rdr <- promoteRdrName rdr_name
+ = lookupOccRn_maybe promoted_rdr
+ | otherwise
+ = return Nothing
+
badVarInType :: RdrName -> RnM Name
badVarInType rdr_name
= do { addErr (text "Illegal promoted term variable in a type:"
@@ -1041,6 +1053,26 @@ its namespace to DataName and do a second lookup.
The final result (after the renamer) will be:
HsTyVar ("Zero", DataName)
+
+Note [Promotion]
+~~~~~~~~~~~~~~~
+When the user mentions a type constructor or a type variable in a
+term-level context, then we report that a value identifier was expected
+instead of a type-level one. That makes error messages more precise.
+Previously, such errors contained only the info that a given value was out of scope (#18740).
+We promote the namespace of RdrName and look up after that
+(see the functions promotedRdrName and lookup_promoted).
+
+In particular, we have the following error message
+ • Illegal term-level use of the type constructor ‘Int’
+ imported from ‘Prelude’ (and originally defined in ‘GHC.Types’)
+ • In the first argument of ‘id’, namely ‘Int’
+ In the expression: id Int
+ In an equation for ‘x’: x = id Int
+
+when the user writes the following declaration
+
+ x = id Int
-}
lookupOccRnX_maybe :: (RdrName -> RnM (Maybe r)) -> (Name -> r) -> RdrName
@@ -1055,14 +1087,22 @@ lookupOccRn_maybe = lookupOccRnX_maybe lookupGlobalOccRn_maybe id
lookupOccRn_overloaded :: Bool -> RdrName
-> RnM (Maybe (Either Name [Name]))
-lookupOccRn_overloaded overload_ok
- = lookupOccRnX_maybe global_lookup Left
- where
- global_lookup :: RdrName -> RnM (Maybe (Either Name [Name]))
- global_lookup n =
- runMaybeT . msum . map MaybeT $
- [ lookupGlobalOccRn_overloaded overload_ok n
- , fmap Left . listToMaybe <$> lookupQualifiedNameGHCi n ]
+lookupOccRn_overloaded overload_ok rdr_name
+ = do { mb_name <- lookupOccRnX_maybe global_lookup Left rdr_name
+ ; case mb_name of
+ Nothing -> fmap @Maybe Left <$> lookup_promoted rdr_name
+ -- See Note [Promotion].
+ -- We try looking up the name as a
+ -- type constructor or type variable, if
+ -- we failed to look up the name at the term level.
+ p -> return p }
+
+ where
+ global_lookup :: RdrName -> RnM (Maybe (Either Name [Name]))
+ global_lookup n =
+ runMaybeT . msum . map MaybeT $
+ [ lookupGlobalOccRn_overloaded overload_ok n
+ , fmap Left . listToMaybe <$> lookupQualifiedNameGHCi n ]