diff --git a/compiler/basicTypes/Name.lhs b/compiler/basicTypes/Name.lhs
index a26729f4b5ce8c264ea134e9cd8e12572f0c0630..3fefd7b59b51f9565808e0aaa20c882c8306f7a1 100644
--- a/compiler/basicTypes/Name.lhs
+++ b/compiler/basicTypes/Name.lhs
@@ -55,7 +55,7 @@ module Name (
 	nameOccName, nameModule, nameModule_maybe,
 	tidyNameOcc, 
 	hashName, localiseName,
-  mkLocalisedOccName,
+        mkLocalisedOccName,
 
 	nameSrcLoc, nameSrcSpan, pprNameDefnLoc, pprDefinedAt,
 
diff --git a/compiler/basicTypes/RdrName.lhs b/compiler/basicTypes/RdrName.lhs
index 22bd41f7d6fd00eb26403fd53dc28c6d348f2da9..c8f7c169fdec15cf80b53949ac0bbf921b0aa3db 100644
--- a/compiler/basicTypes/RdrName.lhs
+++ b/compiler/basicTypes/RdrName.lhs
@@ -49,7 +49,8 @@ module RdrName (
 
 	-- * Local mapping of 'RdrName' to 'Name.Name'
 	LocalRdrEnv, emptyLocalRdrEnv, extendLocalRdrEnv, extendLocalRdrEnvList,
-	lookupLocalRdrEnv, lookupLocalRdrOcc, elemLocalRdrEnv,
+	lookupLocalRdrEnv, lookupLocalRdrOcc, elemLocalRdrEnv, inLocalRdrEnvScope, 
+        localRdrEnvElts, delLocalRdrEnvList,
 
 	-- * Global mapping of 'RdrName' to 'GlobalRdrElt's
 	GlobalRdrEnv, emptyGlobalRdrEnv, mkGlobalRdrEnv, plusGlobalRdrEnv, 
@@ -70,6 +71,7 @@ module RdrName (
 
 import Module
 import Name
+import NameSet
 import Maybes
 import SrcLoc
 import FastString
@@ -333,30 +335,42 @@ instance Ord RdrName where
 \begin{code}
 -- | This environment is used to store local bindings (@let@, @where@, lambda, @case@).
 -- It is keyed by OccName, because we never use it for qualified names
-type LocalRdrEnv = OccEnv Name
+-- We keep the current mapping, *and* the set of all Names in scope
+-- Reason: see Note [Splicing Exact Names] in RnEnv
+type LocalRdrEnv = (OccEnv Name, NameSet) 
 
 emptyLocalRdrEnv :: LocalRdrEnv
-emptyLocalRdrEnv = emptyOccEnv
+emptyLocalRdrEnv = (emptyOccEnv, emptyNameSet)
 
 extendLocalRdrEnv :: LocalRdrEnv -> Name -> LocalRdrEnv
-extendLocalRdrEnv env name
-  = extendOccEnv env (nameOccName name) name
+extendLocalRdrEnv (env, ns) name
+  = (extendOccEnv env (nameOccName name) name, addOneToNameSet ns name)
 
 extendLocalRdrEnvList :: LocalRdrEnv -> [Name] -> LocalRdrEnv
-extendLocalRdrEnvList env names
-  = extendOccEnvList env [(nameOccName n, n) | n <- names]
+extendLocalRdrEnvList (env, ns) names
+  = (extendOccEnvList env [(nameOccName n, n) | n <- names], addListToNameSet  ns names)
 
 lookupLocalRdrEnv :: LocalRdrEnv -> RdrName -> Maybe Name
-lookupLocalRdrEnv env (Unqual occ) = lookupOccEnv env occ
-lookupLocalRdrEnv _   _            = Nothing
+lookupLocalRdrEnv (env, _) (Unqual occ) = lookupOccEnv env occ
+lookupLocalRdrEnv _        _            = Nothing
 
 lookupLocalRdrOcc :: LocalRdrEnv -> OccName -> Maybe Name
-lookupLocalRdrOcc env occ = lookupOccEnv env occ
+lookupLocalRdrOcc (env, _) occ = lookupOccEnv env occ
 
 elemLocalRdrEnv :: RdrName -> LocalRdrEnv -> Bool
-elemLocalRdrEnv rdr_name env 
+elemLocalRdrEnv rdr_name (env, _)
   | isUnqual rdr_name = rdrNameOcc rdr_name `elemOccEnv` env
   | otherwise	      = False
+
+localRdrEnvElts :: LocalRdrEnv -> [Name]
+localRdrEnvElts (env, _) = occEnvElts env
+
+inLocalRdrEnvScope :: Name -> LocalRdrEnv -> Bool
+-- This is the point of the NameSet
+inLocalRdrEnvScope name (_, ns) = name `elemNameSet` ns
+
+delLocalRdrEnvList :: LocalRdrEnv -> [OccName] -> LocalRdrEnv
+delLocalRdrEnvList (env, ns) occs = (delListFromOccEnv env occs, ns)
 \end{code}
 
 %************************************************************************
diff --git a/compiler/rename/RnEnv.lhs b/compiler/rename/RnEnv.lhs
index 66c40928a2b5de68351006d4e824d29e60636afa..f45354dcc2a1e9df557fe47159e51f6f5115dd3d 100644
--- a/compiler/rename/RnEnv.lhs
+++ b/compiler/rename/RnEnv.lhs
@@ -240,10 +240,19 @@ lookupExactOcc name
   = do { env <- getGlobalRdrEnv
        ; let gres = lookupGRE_Name env name
        ; case gres of
-           []    -> return name
+           []    -> -- See Note [Splicing Exact names]
+                    do { lcl_env <- getLocalRdrEnv
+                       ; unless (name `inLocalRdrEnvScope` lcl_env)
+                                (addErr exact_nm_err)
+                       ; return name }
+   
            [gre] -> return (gre_name gre)
            _     -> pprPanic "lookupExactOcc" (ppr name $$ ppr gres) }
 
+  where
+    exact_nm_err = hang (ptext (sLit "The exact Name") <+> quotes (ppr name) <+> ptext (sLit "is not in scope"))
+                      2 (ptext (sLit "Probable cause: you used a unique name (NameU) in Template Haskell but did not bind it"))
+
 -----------------------------------------------
 lookupInstDeclBndr :: Name -> SDoc -> RdrName -> RnM Name
 -- This is called on the method name on the left-hand side of an 
@@ -427,6 +436,7 @@ 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")) ...
+These System names are generated by Convert.thRdrName
 
 But, constructors and the like need External Names, not System Names!
 So we do the following
@@ -437,7 +447,7 @@ So we do the following
 
  * 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
+   GlobalRdrEnv, and use the one 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
@@ -449,6 +459,15 @@ So we do the following
    will find the Name is not in the GlobalRdrEnv, so we just use
    the Exact supplied Name.
 
+Note [Splicing Exact names]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider the splice $(do { x <- newName "x"; return (VarE x) })
+This will generate a (HsExpr RdrName) term that mentions the 
+Exact RdrName "x_56" (or whatever), but does not bind it.  So
+when looking such Exact names we want to check that it's in scope,
+otherwise the type checker will get confused.  To do this we need to
+keep track of all the Names in scope, and the LocalRdrEnv does just that;
+we consult it with RdrName.inLocalRdrEnvScope.
 
 Note [Usage for sub-bndrs]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1230,7 +1249,7 @@ unknownNameSuggestErr where_look tried_rdr_name
       | tried_is_qual = []
       | not local_ok  = []
       | otherwise     = [ (mkRdrUnqual occ, nameSrcSpan name)
-                      	| name <- occEnvElts env
+                      	| name <- localRdrEnvElts env
                       	, let occ = nameOccName name
                       	, correct_name_space occ]
 
diff --git a/compiler/rename/RnNames.lhs b/compiler/rename/RnNames.lhs
index 7007eb559c74522546b445e10e50b71df46d3c54..8741b9ab84e0fd827dadddc920ba60b61050db07 100644
--- a/compiler/rename/RnNames.lhs
+++ b/compiler/rename/RnNames.lhs
@@ -406,7 +406,8 @@ extendGlobalRdrEnvRn avails new_fixities
               new_occs = map (nameOccName . gre_name) gres
               rdr_env_TH = transformGREs qual_gre new_occs rdr_env
               rdr_env_GHCi = delListFromOccEnv rdr_env new_occs
-              lcl_env1 = lcl_env { tcl_rdr = delListFromOccEnv (tcl_rdr lcl_env) new_occs }
+
+              lcl_env1 = lcl_env { tcl_rdr = delLocalRdrEnvList (tcl_rdr lcl_env) new_occs }
               (rdr_env2, lcl_env2) | shadowP   = (rdr_env_TH,   lcl_env1)
                                    | isGHCi    = (rdr_env_GHCi, lcl_env1)
                                    | otherwise = (rdr_env,      lcl_env)
@@ -921,8 +922,7 @@ rnExports explicit_mod exports
         ; (rn_exports, avails) <- exports_from_avail real_exports rdr_env imports this_mod
         ; let final_avails = nubAvails avails    -- Combine families
 
-        ; traceRn (vcat [ text "rnExports: RdrEnv:" <+> ppr rdr_env
-                        , text "     Exports:" <+> ppr final_avails] )
+        ; traceRn (text "rnExports: Exports:" <+> ppr final_avails)
 
         ; return (tcg_env { tcg_exports    = final_avails,
                             tcg_rn_exports = case tcg_rn_exports tcg_env of
diff --git a/compiler/rename/RnTypes.lhs b/compiler/rename/RnTypes.lhs
index ddd788f0bf12196036ea60f71b3a9b46e33a0e5d..2c5a5a57182e87cc982bedd0a904d085deb3aadd 100644
--- a/compiler/rename/RnTypes.lhs
+++ b/compiler/rename/RnTypes.lhs
@@ -838,7 +838,7 @@ rnSplice (HsSplice n expr)
 	; gbl_rdr <- getGlobalRdrEnv
 	; let gbl_names = mkNameSet [gre_name gre | gre <- globalRdrEnvElts gbl_rdr, 
 						    isLocalGRE gre]
-	      lcl_names = mkNameSet (occEnvElts lcl_rdr)
+	      lcl_names = mkNameSet (localRdrEnvElts lcl_rdr)
 
 	; return (HsSplice n' expr', fvs `plusFV` lcl_names `plusFV` gbl_names) }