summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/GHC/Rename/Names.hs2
-rw-r--r--compiler/GHC/Runtime/Context.hs16
-rw-r--r--compiler/GHC/Types/Name/Occurrence.hs11
-rw-r--r--compiler/GHC/Types/Name/Reader.hs8
4 files changed, 27 insertions, 10 deletions
diff --git a/compiler/GHC/Rename/Names.hs b/compiler/GHC/Rename/Names.hs
index f5309eb174..570fb1485d 100644
--- a/compiler/GHC/Rename/Names.hs
+++ b/compiler/GHC/Rename/Names.hs
@@ -717,7 +717,7 @@ extendGlobalRdrEnvRn new_gres new_fixities
-- Deal with shadowing: see Note [GlobalRdrEnv shadowing]
want_shadowing = isGHCi || inBracket
- rdr_env1 | want_shadowing = shadowNames rdr_env new_gres_env
+ rdr_env1 | want_shadowing = shadowNames False rdr_env new_gres_env
| otherwise = rdr_env
lcl_env3 = lcl_env2 { tcl_th_bndrs = extendNameEnvList th_bndrs
diff --git a/compiler/GHC/Runtime/Context.hs b/compiler/GHC/Runtime/Context.hs
index 929b2ca6e9..5f60abf896 100644
--- a/compiler/GHC/Runtime/Context.hs
+++ b/compiler/GHC/Runtime/Context.hs
@@ -401,8 +401,11 @@ setInteractivePrintName ic n = ic{ic_int_print = n}
icExtendIcGblRdrEnv :: IcGlobalRdrEnv -> [TyThing] -> IcGlobalRdrEnv
icExtendIcGblRdrEnv igre tythings = IcGlobalRdrEnv
- { igre_env = igre_env igre `icExtendGblRdrEnv` tythings
- , igre_prompt_env = igre_prompt_env igre `icExtendGblRdrEnv` tythings
+ { igre_env = icExtendGblRdrEnv False (igre_env igre) tythings
+ , igre_prompt_env = icExtendGblRdrEnv True (igre_prompt_env igre) tythings
+ -- Pass 'True' <=> drop names that are only available qualified.
+ -- This is done to maintain the invariant of Note [icReaderEnv recalculation]
+ -- that igre_prompt_env should only contain Names that are available unqualified.
}
-- This is used by setContext in GHC.Runtime.Eval when the set of imports
@@ -410,13 +413,14 @@ icExtendIcGblRdrEnv igre tythings = IcGlobalRdrEnv
replaceImportEnv :: IcGlobalRdrEnv -> GlobalRdrEnv -> IcGlobalRdrEnv
replaceImportEnv igre import_env = igre { igre_env = new_env }
where
- import_env_shadowed = import_env `shadowNames` igre_prompt_env igre
+ import_env_shadowed = shadowNames False import_env (igre_prompt_env igre)
new_env = import_env_shadowed `plusGlobalRdrEnv` igre_prompt_env igre
-- | Add 'TyThings' to the 'GlobalRdrEnv', earlier ones in the list shadowing
-- later ones, and shadowing existing entries in the 'GlobalRdrEnv'.
-icExtendGblRdrEnv :: GlobalRdrEnv -> [TyThing] -> GlobalRdrEnv
-icExtendGblRdrEnv env tythings
+icExtendGblRdrEnv :: Bool -- ^ discard names that are only available qualified?
+ -> GlobalRdrEnv -> [TyThing] -> GlobalRdrEnv
+icExtendGblRdrEnv drop_only_qualified env tythings
= foldr add env tythings -- Foldr makes things in the front of
-- the list shadow things at the back
where
@@ -428,7 +432,7 @@ icExtendGblRdrEnv env tythings
= foldl' extendGlobalRdrEnv env1 new_gres
where
new_gres = tyThingLocalGREs thing
- env1 = shadowNames env $ mkGlobalRdrEnv new_gres
+ env1 = shadowNames drop_only_qualified env $ mkGlobalRdrEnv new_gres
-- Ugh! The new_tythings may include record selectors, since they
-- are not implicit-ids, and must appear in the TypeEnv. But they
diff --git a/compiler/GHC/Types/Name/Occurrence.hs b/compiler/GHC/Types/Name/Occurrence.hs
index b7d95543b0..8aecadf71e 100644
--- a/compiler/GHC/Types/Name/Occurrence.hs
+++ b/compiler/GHC/Types/Name/Occurrence.hs
@@ -88,6 +88,7 @@ module GHC.Types.Name.Occurrence (
-- * The 'OccEnv' type
OccEnv, emptyOccEnv, unitOccEnv, extendOccEnv,
mapOccEnv, strictMapOccEnv,
+ mapMaybeOccEnv,
lookupOccEnv, lookupOccEnv_WithFields, lookupFieldsOccEnv,
mkOccEnv, mkOccEnv_C, extendOccEnvList, elemOccEnv,
nonDetOccEnvElts, nonDetFoldOccEnv,
@@ -685,6 +686,16 @@ plusOccEnv_C f (MkOccEnv env1) (MkOccEnv env2)
mapOccEnv :: (a->b) -> OccEnv a -> OccEnv b
mapOccEnv = fmap
+-- | 'mapMaybe' for b 'OccEnv'.
+mapMaybeOccEnv :: (a -> Maybe b) -> OccEnv a -> OccEnv b
+mapMaybeOccEnv f (MkOccEnv env)
+ = MkOccEnv $ mapMaybeUFM g env
+ where
+ g as =
+ case mapMaybeUFM f as of
+ m' | isNullUFM m' -> Nothing
+ | otherwise -> Just m'
+
-- | Add a single element to an 'OccEnv', using a different function whether
-- the 'OccName' already exists or not.
extendOccEnv_Acc :: forall a b
diff --git a/compiler/GHC/Types/Name/Reader.hs b/compiler/GHC/Types/Name/Reader.hs
index dd7a612d22..928bac9c0c 100644
--- a/compiler/GHC/Types/Name/Reader.hs
+++ b/compiler/GHC/Types/Name/Reader.hs
@@ -1412,10 +1412,11 @@ Wrinkle [Shadowing namespaces]
-}
-shadowNames :: GlobalRdrEnv -> GlobalRdrEnv -> GlobalRdrEnv
+shadowNames :: Bool -- ^ discard names that are only available qualified?
+ -> GlobalRdrEnv -> GlobalRdrEnv -> GlobalRdrEnv
-- Remove certain old GREs that share the same OccName as this new Name.
-- See Note [GlobalRdrEnv shadowing] for details
-shadowNames env new_gres = minusOccEnv_C_Ns do_shadowing env new_gres
+shadowNames drop_only_qualified env new_gres = minusOccEnv_C_Ns do_shadowing env new_gres
where
do_shadowing :: UniqFM NameSpace [GlobalRdrElt]
@@ -1455,7 +1456,8 @@ shadowNames env new_gres = minusOccEnv_C_Ns do_shadowing env new_gres
case greDefinitionModule old_gre of
Nothing -> Just old_gre -- Old name is Internal; do not shadow
Just old_mod
- | null iss' -- Nothing remains
+ | null iss' -- Nothing remains
+ || drop_only_qualified
-> Nothing
| otherwise