[Git][ghc/ghc][wip/ghc-18740-lookup-update] Fall back to types when looking up data constructors (#18740)
Danya Rogozin
gitlab at gitlab.haskell.org
Tue Sep 29 10:07:24 UTC 2020
Danya Rogozin pushed to branch wip/ghc-18740-lookup-update at Glasgow Haskell Compiler / GHC
Commits:
d79d03b6 by Daniel Rogozin at 2020-09-29T13:07:06+03:00
Fall back to types when looking up data constructors (#18740)
Before this patch, referring to a data constructor in a term-level
context led to a scoping error:
ghci> id Int
<interactive>:1:4: error: Data constructor not in scope: Int
After this patch, the renamer falls back to the type namespace
and successfully finds the Int. It is then rejected in the type
checker with a more useful error message:
<interactive>:1:4: error:
Type constructor 'Int' used where a value identifier was expected
We also do this for type variables.
- - - - -
12 changed files:
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Types/Name/Occurrence.hs
- compiler/GHC/Types/Name/Reader.hs
- testsuite/tests/module/mod132.stderr
- testsuite/tests/module/mod147.stderr
- testsuite/tests/rename/should_fail/RnStaticPointersFail02.stderr
- + testsuite/tests/rename/should_fail/T18740a.hs
- + testsuite/tests/rename/should_fail/T18740a.stderr
- + testsuite/tests/rename/should_fail/T18740b.hs
- + testsuite/tests/rename/should_fail/T18740b.stderr
- testsuite/tests/rename/should_fail/all.T
Changes:
=====================================
compiler/GHC/Rename/Env.hs
=====================================
@@ -5,7 +5,7 @@ GHC.Rename.Env contains functions which convert RdrNames into Names.
-}
-{-# LANGUAGE CPP, MultiWayIf, NamedFieldPuns #-}
+{-# LANGUAGE CPP, MultiWayIf, NamedFieldPuns, TypeApplications #-}
module GHC.Rename.Env (
newTopSrcBinder,
@@ -1005,6 +1005,14 @@ lookup_demoted rdr_name
, text "instead of"
, quotes (ppr name) <> dot ]
+-- 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:"
@@ -1040,6 +1048,23 @@ 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. 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
+ • Type constructor 'Int' used where a value identifier was expected
+
+when the user writes the following term
+
+ id Int
+
-}
lookupOccRnX_maybe :: (RdrName -> RnM (Maybe r)) -> (Name -> r) -> RdrName
@@ -1054,14 +1079,19 @@ 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].
+ 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 ]
=====================================
compiler/GHC/Tc/Gen/Head.hs
=====================================
@@ -768,6 +768,16 @@ tc_infer_id id_name
| otherwise
-> nonBidirectionalErr id_name
+ ATyVar name _
+ -> failWithTc $
+ text "Illegal term-level use of the type variable"
+ <+> quotes (ppr name)
+
+ ATcTyCon ty_con
+ -> failWithTc $
+ text "Illegal term-level use of the type constructor"
+ <+> quotes (ppr (tyConName ty_con))
+
_ -> failWithTc $
ppr thing <+> text "used where a value identifier was expected" }
where
@@ -1140,4 +1150,3 @@ addExprCtxt e thing_inside
exprCtxt :: HsExpr GhcRn -> SDoc
exprCtxt expr = hang (text "In the expression:") 2 (ppr (stripParensHsExpr expr))
-
=====================================
compiler/GHC/Types/Name/Occurrence.hs
=====================================
@@ -52,6 +52,7 @@ module GHC.Types.Name.Occurrence (
mkDFunOcc,
setOccNameSpace,
demoteOccName,
+ promoteOccName,
HasOccName(..),
-- ** Derived 'OccName's
@@ -215,6 +216,14 @@ demoteNameSpace DataName = Nothing
demoteNameSpace TvName = Nothing
demoteNameSpace TcClsName = Just DataName
+-- promoteNameSpace promotes the NameSpace as follows.
+-- See Note [Promotion] in GHC.Rename.Env
+promoteNameSpace :: NameSpace -> Maybe NameSpace
+promoteNameSpace DataName = Just TcClsName
+promoteNameSpace VarName = Just TvName
+promoteNameSpace TcClsName = Nothing
+promoteNameSpace TvName = Nothing
+
{-
************************************************************************
* *
@@ -336,12 +345,19 @@ mkClsOccFS :: FastString -> OccName
mkClsOccFS = mkOccNameFS clsName
-- demoteOccName lowers the Namespace of OccName.
--- see Note [Demotion]
+-- See Note [Demotion].
demoteOccName :: OccName -> Maybe OccName
demoteOccName (OccName space name) = do
space' <- demoteNameSpace space
return $ OccName space' name
+-- promoteOccName promotes the NameSpace of OccName.
+-- See Note [Promotion].
+promoteOccName :: OccName -> Maybe OccName
+promoteOccName (OccName space name) = do
+ space' <- promoteNameSpace space
+ return $ OccName space' name
+
-- Name spaces are related if there is a chance to mean the one when one writes
-- the other, i.e. variables <-> data constructors and type variables <-> type constructors
nameSpacesRelated :: NameSpace -> NameSpace -> Bool
=====================================
compiler/GHC/Types/Name/Reader.hs
=====================================
@@ -32,7 +32,7 @@ module GHC.Types.Name.Reader (
nameRdrName, getRdrName,
-- ** Destruction
- rdrNameOcc, rdrNameSpace, demoteRdrName,
+ rdrNameOcc, rdrNameSpace, demoteRdrName, promoteRdrName,
isRdrDataCon, isRdrTyVar, isRdrTc, isQual, isQual_maybe, isUnqual,
isOrig, isOrig_maybe, isExact, isExact_maybe, isSrcRdrName,
@@ -179,13 +179,21 @@ rdrNameSpace :: RdrName -> NameSpace
rdrNameSpace = occNameSpace . rdrNameOcc
-- demoteRdrName lowers the NameSpace of RdrName.
--- see Note [Demotion] in GHC.Types.Name.Occurrence
+-- See Note [Demotion] in GHC.Rename.Env
demoteRdrName :: RdrName -> Maybe RdrName
demoteRdrName (Unqual occ) = fmap Unqual (demoteOccName occ)
demoteRdrName (Qual m occ) = fmap (Qual m) (demoteOccName occ)
demoteRdrName (Orig _ _) = Nothing
demoteRdrName (Exact _) = Nothing
+-- promoteRdrName promotes the NameSpace of RdrName.
+-- See Note [Promotion] in GHC.Rename.Env.
+promoteRdrName :: RdrName -> Maybe RdrName
+promoteRdrName (Unqual occ) = fmap Unqual (promoteOccName occ)
+promoteRdrName (Qual m occ) = fmap (Qual m) (promoteOccName occ)
+promoteRdrName (Orig _ _) = Nothing
+promoteRdrName (Exact _) = Nothing
+
-- These two are the basic constructors
mkRdrUnqual :: OccName -> RdrName
mkRdrUnqual occ = Unqual occ
=====================================
testsuite/tests/module/mod132.stderr
=====================================
@@ -1,4 +1,5 @@
mod132.hs:6:7: error:
- • Data constructor not in scope: Foo
- • Perhaps you meant variable ‘foo’ (line 6)
+ Type constructor ‘Foo’ used where a value identifier was expected
+ In the expression: Foo
+ In an equation for ‘foo’: foo = Foo
=====================================
testsuite/tests/module/mod147.stderr
=====================================
@@ -1,2 +1,5 @@
-mod147.hs:6:5: error: Data constructor not in scope: D :: t0 -> t
+mod147.hs:6:5:
+ Type constructor 'D' used where a value identifier was expected
+ In the expression: D 4
+ In an equation for 'x': x = D 4
=====================================
testsuite/tests/rename/should_fail/RnStaticPointersFail02.stderr
=====================================
@@ -1,3 +1,6 @@
-RnStaticPointersFail02.hs:5:12: error:
- Data constructor not in scope: T
+RnStaticPointersFail02.hs:5:12:
+Type constructor ‘T’ used where a value identifier was expected
+In the body of a static form: T
+ In the expression: static T
+ In an equation for ‘f’: f = static T
=====================================
testsuite/tests/rename/should_fail/T18740a.hs
=====================================
@@ -0,0 +1,3 @@
+module T18740a where
+
+x = Int
=====================================
testsuite/tests/rename/should_fail/T18740a.stderr
=====================================
@@ -0,0 +1,5 @@
+
+T18740a.hs:3:5: error:
+ • Type constructor ‘Int’ used where a value identifier was expected
+ • In the expression: Int
+ In an equation for ‘x’: x = Int
=====================================
testsuite/tests/rename/should_fail/T18740b.hs
=====================================
@@ -0,0 +1,6 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+module T18740b where
+
+import Data.Proxy
+
+f (Proxy :: Proxy a) = a
=====================================
testsuite/tests/rename/should_fail/T18740b.stderr
=====================================
@@ -0,0 +1,5 @@
+
+T18740b.hs:6:24: error:
+ • Illegal term-level use of the type variable ‘a’
+ • In the expression: a
+ In an equation for ‘f’: f (Proxy :: Proxy a) = a
=====================================
testsuite/tests/rename/should_fail/all.T
=====================================
@@ -156,3 +156,5 @@ test('T17593', normal, compile_fail, [''])
test('T18145', normal, compile_fail, [''])
test('T18240a', normal, compile_fail, [''])
test('T18240b', normal, compile_fail, [''])
+test('T18740a', normal, compile_fail, [''])
+test('T18740b', normal, compile_fail, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d79d03b6dd90bf12a98edd08a9080ce8f99c5ed6
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d79d03b6dd90bf12a98edd08a9080ce8f99c5ed6
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20200929/3e9f1764/attachment-0001.html>
More information about the ghc-commits
mailing list