[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