summaryrefslogtreecommitdiff
path: root/compiler/rename/RnEnv.lhs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rename/RnEnv.lhs')
-rw-r--r--compiler/rename/RnEnv.lhs56
1 files changed, 48 insertions, 8 deletions
diff --git a/compiler/rename/RnEnv.lhs b/compiler/rename/RnEnv.lhs
index f2a0649f6e..09890181a5 100644
--- a/compiler/rename/RnEnv.lhs
+++ b/compiler/rename/RnEnv.lhs
@@ -223,14 +223,17 @@ lookupTopBndrRn_maybe rdr_name
-----------------------------------------------
lookupExactOcc :: Name -> RnM Name
+-- See Note [Looking up Exact RdrNames]
lookupExactOcc name
- | isExternalName name = return name
- | otherwise = do { env <- getGlobalRdrEnv
- ; let gres = lookupGRE_Name env name
- ; case gres of
- [] -> return name
- [gre] -> return (gre_name gre)
- _ -> pprPanic "lookupExactOcc" (ppr name $$ ppr gres) }
+ | isExternalName name
+ = return name
+ | otherwise
+ = do { env <- getGlobalRdrEnv
+ ; let gres = lookupGRE_Name env name
+ ; case gres of
+ [] -> return name
+ [gre] -> return (gre_name gre)
+ _ -> pprPanic "lookupExactOcc" (ppr name $$ ppr gres) }
-----------------------------------------------
lookupInstDeclBndr :: Name -> RdrName -> RnM Name
@@ -352,6 +355,39 @@ newIPNameRn :: IPName RdrName -> TcRnIf m n (IPName Name)
newIPNameRn ip_rdr = newIPName (mapIPName rdrNameOcc ip_rdr)
\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]
~~~~~~~~~~~~~~~~~~~~~~~~~~
If you have this
@@ -567,6 +603,10 @@ lookupBindGroupOcc :: Maybe NameSet -- See notes on the (Maybe NameSet)
--
-- See Note [Looking up signature names]
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
; case lookupLocalRdrEnv local_env rdr_name of {
Just n -> check_local_name n;
@@ -582,7 +622,7 @@ lookupBindGroupOcc mb_bound_names what rdr_name
[] | null gres -> bale_out_with empty
| otherwise -> bale_out_with import_msg
}}}
- where
+ where
check_local_name name -- The name is in scope, and not imported
= case mb_bound_names of
Just bound_names | not (name `elemNameSet` bound_names)