diff options
Diffstat (limited to 'compiler/rename/RnEnv.lhs')
-rw-r--r-- | compiler/rename/RnEnv.lhs | 56 |
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) |