diff options
-rw-r--r-- | compiler/GHC/Rename/Names.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Runtime/Context.hs | 16 | ||||
-rw-r--r-- | compiler/GHC/Types/Name/Occurrence.hs | 11 | ||||
-rw-r--r-- | compiler/GHC/Types/Name/Reader.hs | 8 |
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 |