From 3fbb1348bb2719db22f81c8d90e96de25fc4972e Mon Sep 17 00:00:00 2001 From: Simon Peyton Jones <simonpj@microsoft.com> Date: Mon, 15 Aug 2011 08:41:55 +0100 Subject: [PATCH] Fix Trac #5404: looking up signature binders in RnEnv See Note [Looking up Exact RdrNames] in RnEnv --- compiler/hsSyn/Convert.lhs | 13 ++------- compiler/rename/RnEnv.lhs | 56 ++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/compiler/hsSyn/Convert.lhs b/compiler/hsSyn/Convert.lhs index 0cb8da5acb78..c081b30c9d88 100644 --- a/compiler/hsSyn/Convert.lhs +++ b/compiler/hsSyn/Convert.lhs @@ -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 the way System Names are printed. -There's a small complication of course. For data types and -classes we'll now have 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")) ... -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. +There's a small complication of course; see Note [Looking up Exact +RdrNames] in RnEnv. diff --git a/compiler/rename/RnEnv.lhs b/compiler/rename/RnEnv.lhs index f2a0649f6e6e..09890181a598 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) -- GitLab