diff options
Diffstat (limited to 'compiler/GHC/Rename/Env.hs')
-rw-r--r-- | compiler/GHC/Rename/Env.hs | 56 |
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 ] |