Skip to content
Snippets Groups Projects
Commit 3fbb1348 authored by Simon Peyton Jones's avatar Simon Peyton Jones Committed by Ian Lynagh
Browse files

Fix Trac #5404: looking up signature binders in RnEnv

See Note [Looking up Exact RdrNames] in RnEnv
parent d23fcba5
No related branches found
No related tags found
No related merge requests found
...@@ -942,14 +942,5 @@ temporary variables "a". Since there are lots of things called "a" we ...@@ -942,14 +942,5 @@ temporary variables "a". Since there are lots of things called "a" we
usually want to print the name with the unique, and that is indeed usually want to print the name with the unique, and that is indeed
the way System Names are printed. the way System Names are printed.
There's a small complication of course. For data types and There's a small complication of course; see Note [Looking up Exact
classes we'll now have system Names in the binding positions RdrNames] in RnEnv.
for constructors, TyCons etc. For example
[d| data T = MkT Int |]
when we splice in and Convert to HsSyn RdrName, we'll get
data (Exact (system Name "T")) = (Exact (system Name "MkT")) ...
So RnEnv.newGlobalBinder we spot Exact RdrNames that wrap a
non-External Name, and make an External name for. (Remember,
constructors and the like need External Names.) Oddly, the
*occurrences* will continue to be that (non-External) System Name,
but the first sweep of the optimiser will fix that.
...@@ -223,14 +223,17 @@ lookupTopBndrRn_maybe rdr_name ...@@ -223,14 +223,17 @@ lookupTopBndrRn_maybe rdr_name
----------------------------------------------- -----------------------------------------------
lookupExactOcc :: Name -> RnM Name lookupExactOcc :: Name -> RnM Name
-- See Note [Looking up Exact RdrNames]
lookupExactOcc name lookupExactOcc name
| isExternalName name = return name | isExternalName name
| otherwise = do { env <- getGlobalRdrEnv = return name
; let gres = lookupGRE_Name env name | otherwise
; case gres of = do { env <- getGlobalRdrEnv
[] -> return name ; let gres = lookupGRE_Name env name
[gre] -> return (gre_name gre) ; case gres of
_ -> pprPanic "lookupExactOcc" (ppr name $$ ppr gres) } [] -> return name
[gre] -> return (gre_name gre)
_ -> pprPanic "lookupExactOcc" (ppr name $$ ppr gres) }
----------------------------------------------- -----------------------------------------------
lookupInstDeclBndr :: Name -> RdrName -> RnM Name lookupInstDeclBndr :: Name -> RdrName -> RnM Name
...@@ -352,6 +355,39 @@ newIPNameRn :: IPName RdrName -> TcRnIf m n (IPName Name) ...@@ -352,6 +355,39 @@ newIPNameRn :: IPName RdrName -> TcRnIf m n (IPName Name)
newIPNameRn ip_rdr = newIPName (mapIPName rdrNameOcc ip_rdr) newIPNameRn ip_rdr = newIPName (mapIPName rdrNameOcc ip_rdr)
\end{code} \end{code}
Note [Looking up Exact RdrNames]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Exact RdrNames are generated by Template Haskell. See Note [Binders
in Template Haskell] in Convert.
For data types and classes have Exact system Names in the binding
positions for constructors, TyCons etc. For example
[d| data T = MkT Int |]
when we splice in and Convert to HsSyn RdrName, we'll get
data (Exact (system Name "T")) = (Exact (system Name "MkT")) ...
But, constructors and the like need External Names, not System Names!
So we do the following
* In RnEnv.newGlobalBinder we spot Exact RdrNames that wrap a
non-External Name, and make an External name for it. This is
the name that goes in the GlobalRdrEnv
* When looking up an occurrence of an Exact name, done in
RnEnv.lookupExactOcc, we find the Name with the right unique in the
GlobalRdrEnv, and use the on from the envt -- it will be an
External Name in the case of the data type/constructor above.
* Exact names are also use for purely local binders generated
by TH, such as \x_33. x_33
Both binder and occurrence are Exact RdrNames. The occurrence
gets looked up in the LocalRdrEnv by RnEnv.lookupOccRn, and
misses, because lookupLocalRdrEnv always returns Nothing for
an Exact Name. Now we fall through to lookupExactOcc, which
will find the Name is not in the GlobalRdrEnv, so we just use
the Exact supplied Name.
Note [Usage for sub-bndrs] Note [Usage for sub-bndrs]
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
If you have this If you have this
...@@ -567,6 +603,10 @@ lookupBindGroupOcc :: Maybe NameSet -- See notes on the (Maybe NameSet) ...@@ -567,6 +603,10 @@ lookupBindGroupOcc :: Maybe NameSet -- See notes on the (Maybe NameSet)
-- --
-- See Note [Looking up signature names] -- See Note [Looking up signature names]
lookupBindGroupOcc mb_bound_names what rdr_name lookupBindGroupOcc mb_bound_names what rdr_name
| Just n <- isExact_maybe rdr_name
= do { n' <- lookupExactOcc n
; check_local_name n' }
| otherwise
= do { local_env <- getLocalRdrEnv = do { local_env <- getLocalRdrEnv
; case lookupLocalRdrEnv local_env rdr_name of { ; case lookupLocalRdrEnv local_env rdr_name of {
Just n -> check_local_name n; Just n -> check_local_name n;
...@@ -582,7 +622,7 @@ lookupBindGroupOcc mb_bound_names what rdr_name ...@@ -582,7 +622,7 @@ lookupBindGroupOcc mb_bound_names what rdr_name
[] | null gres -> bale_out_with empty [] | null gres -> bale_out_with empty
| otherwise -> bale_out_with import_msg | otherwise -> bale_out_with import_msg
}}} }}}
where where
check_local_name name -- The name is in scope, and not imported check_local_name name -- The name is in scope, and not imported
= case mb_bound_names of = case mb_bound_names of
Just bound_names | not (name `elemNameSet` bound_names) Just bound_names | not (name `elemNameSet` bound_names)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment