[commit: ghc] master: Comments about GlobalRdrEnv shadowing (6257fb5)
git at git.haskell.org
git at git.haskell.org
Fri Aug 18 13:51:46 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/6257fb528c1c92fbe3bd66441bfba00f632d1b50/ghc
>---------------------------------------------------------------
commit 6257fb528c1c92fbe3bd66441bfba00f632d1b50
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Tue Aug 1 12:07:34 2017 +0100
Comments about GlobalRdrEnv shadowing
Provoked by Trac #14052
>---------------------------------------------------------------
6257fb528c1c92fbe3bd66441bfba00f632d1b50
compiler/basicTypes/RdrName.hs | 43 +++++++++++++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 7 deletions(-)
diff --git a/compiler/basicTypes/RdrName.hs b/compiler/basicTypes/RdrName.hs
index 9e59c97..f28ae01 100644
--- a/compiler/basicTypes/RdrName.hs
+++ b/compiler/basicTypes/RdrName.hs
@@ -999,15 +999,44 @@ shadowNames = foldl shadowName
{- Note [GlobalRdrEnv shadowing]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before adding new names to the GlobalRdrEnv we nuke some existing entries;
-this is "shadowing". The actual work is done by RdrEnv.shadowNames.
+this is "shadowing". The actual work is done by RdrEnv.shadowName.
+Suppose
+ env' = shadowName env M.f
+
+Then:
+ * Looking up (Unqual f) in env' should succeed, returning M.f,
+ even if env contains existing unqualified bindings for f.
+ They are shadowed
+
+ * Looking up (Qual M.f) in env' should succeed, returning M.f
+
+ * Looking up (Qual X.f) in env', where X /= M, should be the same as
+ looking up (Qual X.f) in env.
+ That is, shadowName does /not/ delete earlier qualified bindings
+
There are two reasons for shadowing:
* The GHCi REPL
- Ids bought into scope on the command line (eg let x = True) have
External Names, like Ghci4.x. We want a new binding for 'x' (say)
- to override the existing binding for 'x'.
- See Note [Interactively-bound Ids in GHCi] in HscTypes
+ to override the existing binding for 'x'. Example:
+
+ ghci> :load M -- Brings `x` and `M.x` into scope
+ ghci> x
+ ghci> "Hello"
+ ghci> M.x
+ ghci> "hello"
+ ghci> let x = True -- Shadows `x`
+ ghci> x -- The locally bound `x`
+ -- NOT an ambiguous reference
+ ghci> True
+ ghci> M.x -- M.x is still in scope!
+ ghci> "Hello"
+ So when we add `x = True` we must not delete the `M.x` from the
+ `GlobalRdrEnv`; rather we just want to make it "qualified only";
+ hence the `mk_fake-imp_spec` in `shadowName`. See also Note
+ [Interactively-bound Ids in GHCi] in HscTypes
- Data types also have Extenal Names, like Ghci4.T; but we still want
'T' to mean the newly-declared 'T', not an old one.
@@ -1017,10 +1046,10 @@ There are two reasons for shadowing:
Consider a TH decl quote:
module M where
- f x = h [d| f = 3 |]
- We must shadow the outer declaration of 'f', else we'll get a
- complaint when extending the GlobalRdrEnv, saying that there are two
- bindings for 'f'. There are several tricky points:
+ f x = h [d| f = ...f...M.f... |]
+ We must shadow the outer unqualified binding of 'f', else we'll get
+ a complaint when extending the GlobalRdrEnv, saying that there are
+ two bindings for 'f'. There are several tricky points:
- This shadowing applies even if the binding for 'f' is in a
where-clause, and hence is in the *local* RdrEnv not the *global*
More information about the ghc-commits
mailing list