do not link with -lrt on Solaris for threaded way
[ghc.git] / compiler / rename / RnEnv.lhs
index 478e45f..f333a23 100644 (file)
@@ -4,13 +4,17 @@
 \section[RnEnv]{Environment manipulation for the renamer monad}
 
 \begin{code}
+{-# LANGUAGE CPP #-}
+
 module RnEnv (
         newTopSrcBinder,
         lookupLocatedTopBndrRn, lookupTopBndrRn,
-        lookupLocatedOccRn, lookupOccRn,
+        lookupLocatedOccRn, lookupOccRn, lookupOccRn_maybe,
         lookupLocalOccRn_maybe,
+        lookupLocalOccThLvl_maybe,
         lookupTypeOccRn, lookupKindOccRn,
         lookupGlobalOccRn, lookupGlobalOccRn_maybe,
+        reportUnboundName,
 
         HsSigCtxt(..), lookupLocalTcNames, lookupSigOccRn,
 
@@ -18,13 +22,14 @@ module RnEnv (
         lookupInstDeclBndr, lookupSubBndrOcc, lookupFamInstName,
         greRdrName,
         lookupSubBndrGREs, lookupConstructorFields,
-        lookupSyntaxName, lookupSyntaxTable, lookupIfThenElse,
-        lookupGreRn, lookupGreLocalRn, lookupGreRn_maybe,
+        lookupSyntaxName, lookupSyntaxNames, lookupIfThenElse,
+        lookupGreRn, lookupGreRn_maybe,
+        lookupGreLocalRn_maybe, 
         getLookupOccRn, addUsedRdrNames,
 
         newLocalBndrRn, newLocalBndrsRn,
-        bindLocalName, bindLocalNames, bindLocalNamesFV,
-        MiniFixityEnv, emptyFsEnv, extendFsEnv, lookupFsEnv,
+        bindLocalNames, bindLocalNamesFV,
+        MiniFixityEnv, 
         addLocalFixities,
         bindLocatedLocalsFV, bindLocatedLocalsRn,
         extendTyVarEnvFVRn,
@@ -34,13 +39,13 @@ module RnEnv (
         addFvRn, mapFvRn, mapMaybeFvRn, mapFvRnCPS,
         warnUnusedMatches,
         warnUnusedTopBinds, warnUnusedLocalBinds,
-        dataTcOccs, unknownNameErr, kindSigErr, perhapsForallMsg,
+        dataTcOccs, kindSigErr, perhapsForallMsg,
         HsDocContext(..), docOfHsDocContext
     ) where
 
 #include "HsVersions.h"
 
-import LoadIface        ( loadInterfaceForName, loadSrcInterface )
+import LoadIface        ( loadInterfaceForName, loadSrcInterface_maybe )
 import IfaceEnv
 import HsSyn
 import RdrName
@@ -52,16 +57,18 @@ import Name
 import NameSet
 import NameEnv
 import Avail
-import Module           ( ModuleName, moduleName )
-import UniqFM
+import Module
+import ConLike
 import DataCon          ( dataConFieldLabels, dataConTyCon )
 import TyCon            ( isTupleTyCon, tyConArity )
-import PrelNames        ( mkUnboundName, rOOT_MAIN, forall_tv_RDR )
+import PrelNames        ( mkUnboundName, isUnboundName, rOOT_MAIN, forall_tv_RDR )
 import ErrUtils         ( MsgDoc )
+import BasicTypes       ( Fixity(..), FixityDirection(..), minPrecedence, defaultFixity )
 import SrcLoc
 import Outputable
 import Util
 import Maybes
+import BasicTypes       ( TopLevelFlag(..) )
 import ListSetOps       ( removeDups )
 import DynFlags
 import FastString
@@ -71,12 +78,6 @@ import qualified Data.Set as Set
 import Constants        ( mAX_TUPLE_SIZE )
 \end{code}
 
-\begin{code}
--- XXX
-thenM :: Monad a => a b -> (b -> a c) -> a c
-thenM = (>>=)
-\end{code}
-
 %*********************************************************
 %*                                                      *
                 Source-code binders
@@ -132,7 +133,6 @@ newTopSrcBinder (L loc rdr_name)
         -- have an arbitrary mixture of external core definitions in a single module,
         -- (apart from module-initialisation issues, perhaps).
         ; newGlobalBinder rdr_mod rdr_occ loc }
-                --TODO, should pass the whole span
 
   | otherwise
   = do  { unless (not (isQual rdr_name))
@@ -220,7 +220,7 @@ lookupTopBndrRn_maybe rdr_name
                (do { op_ok <- xoptM Opt_TypeOperators
                    ; unless op_ok (addErr (opDeclErr rdr_name)) })
 
-        ; mb_gre <- lookupGreLocalRn rdr_name
+        ; mb_gre <- lookupGreLocalRn_maybe rdr_name
         ; case mb_gre of
                 Nothing  -> return Nothing
                 Just gre -> return (Just $ gre_name gre) }
@@ -232,9 +232,9 @@ lookupExactOcc :: Name -> RnM Name
 lookupExactOcc name
   | Just thing <- wiredInNameTyThing_maybe name
   , Just tycon <- case thing of
-                    ATyCon tc   -> Just tc
-                    ADataCon dc -> Just (dataConTyCon dc)
-                    _           -> Nothing
+                    ATyCon tc                 -> Just tc
+                    AConLike (RealDataCon dc) -> Just (dataConTyCon dc)
+                    _                         -> Nothing
   , isTupleTyCon tycon
   = do { checkTupSize (tyConArity tycon)
        ; return name }
@@ -255,18 +255,42 @@ lookupExactOcc name
        ; case gres of
            []    -> -- 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) }
+                       ; unless (name `inLocalRdrEnvScope` lcl_env) $
+#ifdef GHCI
+                         do { th_topnames_var <- fmap tcg_th_topnames getGblEnv
+                            ; th_topnames <- readTcRef th_topnames_var
+                            ; unless (name `elemNameSet` th_topnames)
+                                     (addErr exact_nm_err)
+                            }
+#else /* !GHCI */
+                         addErr exact_nm_err
+#endif /* !GHCI */
+                       ; return name
+                       }
+
+           [gre]   -> return (gre_name gre)
+           (gre:_) -> do {addErr dup_nm_err
+                         ; return (gre_name gre)
+                         }
+           -- We can get more than one GRE here, if there are multiple 
+           -- bindings for the same name. Sometimes they are caught later
+           -- by findLocalDupsRdrEnv, like in this example (Trac #8932):
+           --    $( [d| foo :: a->a; foo x = x |])
+           --    foo = True
+           -- But when the names are totally identical, we panic (Trac #7241):
+           --    $(newName "Foo" >>= \o -> return [DataD [] o [] [RecC o []] [''Show]])
+           -- So, let's emit an error here, even if it will lead to duplication in some cases.
+       }
 
   where
     exact_nm_err = hang (ptext (sLit "The exact Name") <+> quotes (ppr name) <+> ptext (sLit "is not in scope"))
                       2 (vcat [ ptext (sLit "Probable cause: you used a unique Template Haskell name (NameU), ")
                               , ptext (sLit "perhaps via newName, but did not bind it")
                               , ptext (sLit "If that's it, then -ddump-splices might be useful") ])
+    dup_nm_err   = hang (ptext (sLit "Duplicate exact Name") <+> quotes (ppr $ nameOccName name))
+                      2 (vcat [ ptext (sLit "Probable cause: you used a unique Template Haskell name (NameU), ")
+                              , ptext (sLit "perhaps via newName, but bound it multiple times")
+                              , ptext (sLit "If that's it, then -ddump-splices might be useful") ])
 
 -----------------------------------------------
 lookupInstDeclBndr :: Name -> SDoc -> RdrName -> RnM Name
@@ -290,7 +314,11 @@ lookupInstDeclBndr cls what rdr
                 -- In an instance decl you aren't allowed
                 -- to use a qualified name for the method
                 -- (Although it'd make perfect sense.)
-       ; lookupSubBndrOcc (ParentIs cls) doc rdr }
+       ; lookupSubBndrOcc False -- False => we don't give deprecated
+                                -- warnings when a deprecated class
+                                -- method is defined. We only warn
+                                -- when it's used
+                          (ParentIs cls) doc rdr }
   where
     doc = what <+> ptext (sLit "of class") <+> quotes (ppr cls)
 
@@ -337,11 +365,12 @@ lookupConstructorFields con_name
 -- unambiguous because there is only one field id 'fld' in scope.
 -- But currently it's rejected.
 
-lookupSubBndrOcc :: Parent  -- NoParent   => just look it up as usual
+lookupSubBndrOcc :: Bool
+                 -> Parent  -- NoParent   => just look it up as usual
                             -- ParentIs p => use p to disambiguate
                  -> SDoc -> RdrName
                  -> RnM Name
-lookupSubBndrOcc parent doc rdr_name
+lookupSubBndrOcc warnIfDeprec parent doc rdr_name
   | Just n <- isExact_maybe rdr_name   -- This happens in derived code
   = lookupExactOcc n
 
@@ -355,7 +384,7 @@ lookupSubBndrOcc parent doc rdr_name
                 -- NB: lookupGlobalRdrEnv, not lookupGRE_RdrName!
                 --     The latter does pickGREs, but we want to allow 'x'
                 --     even if only 'M.x' is in scope
-            [gre] -> do { addUsedRdrName gre (used_rdr_name gre)
+            [gre] -> do { addUsedRdrName warnIfDeprec gre (used_rdr_name gre)
                           -- Add a usage; this is an *occurrence* site
                         ; return (gre_name gre) }
             []    -> do { addErr (unknownSubordinateErr doc rdr_name)
@@ -434,8 +463,8 @@ Thus:
       data G a
     instance C S where
       data G S = Y1 | Y2
-Even though there are two G's in scope (M.G and Blib.G), the occurence
-of 'G' in the 'instance C S' decl is unambiguous, becuase C has only
+Even though there are two G's in scope (M.G and Blib.G), the occurrence
+of 'G' in the 'instance C S' decl is unambiguous, because C has only
 one associated type called G. This is exactly what happens for methods,
 and it is only consistent to do the same thing for types. That's the
 role of the function lookupTcdName; the (Maybe Name) give the class of
@@ -524,8 +553,8 @@ we'll miss the fact that the qualified import is redundant.
 \begin{code}
 getLookupOccRn :: RnM (Name -> Maybe Name)
 getLookupOccRn
-  = getLocalRdrEnv                      `thenM` \ local_env ->
-    return (lookupLocalRdrOcc local_env . nameOccName)
+  = do local_env <- getLocalRdrEnv
+       return (lookupLocalRdrOcc local_env . nameOccName)
 
 lookupLocatedOccRn :: Located RdrName -> RnM (Located Name)
 lookupLocatedOccRn = wrapLocM lookupOccRn
@@ -536,11 +565,19 @@ lookupLocalOccRn_maybe rdr_name
   = do { local_env <- getLocalRdrEnv
        ; return (lookupLocalRdrEnv local_env rdr_name) }
 
+lookupLocalOccThLvl_maybe :: Name -> RnM (Maybe (TopLevelFlag, ThLevel))
+-- Just look in the local environment
+lookupLocalOccThLvl_maybe name
+  = do { lcl_env <- getLclEnv
+       ; return (lookupNameEnv (tcl_th_bndrs lcl_env) name) }
+
 -- lookupOccRn looks up an occurrence of a RdrName
 lookupOccRn :: RdrName -> RnM Name
-lookupOccRn rdr_name = do
-  opt_name <- lookupOccRn_maybe rdr_name
-  maybe (unboundName WL_Any rdr_name) return opt_name
+lookupOccRn rdr_name
+  = do { mb_name <- lookupOccRn_maybe rdr_name
+       ; case mb_name of
+           Just name -> return name
+           Nothing   -> reportUnboundName rdr_name }
 
 lookupKindOccRn :: RdrName -> RnM Name
 -- Looking up a name occurring in a kind
@@ -548,7 +585,7 @@ lookupKindOccRn rdr_name
   = do { mb_name <- lookupOccRn_maybe rdr_name
        ; case mb_name of
            Just name -> return name
-           Nothing -> unboundName WL_Any rdr_name  }
+           Nothing   -> reportUnboundName rdr_name  }
 
 -- lookupPromotedOccRn looks up an optionally promoted RdrName.
 lookupTypeOccRn :: RdrName -> RnM Name
@@ -566,16 +603,16 @@ lookup_demoted rdr_name
   = do { data_kinds <- xoptM Opt_DataKinds
        ; mb_demoted_name <- lookupOccRn_maybe demoted_rdr
        ; case mb_demoted_name of
-           Nothing -> unboundName WL_Any rdr_name
+           Nothing -> reportUnboundName rdr_name
            Just demoted_name
              | data_kinds -> return demoted_name
              | otherwise  -> unboundNameX WL_Any rdr_name suggest_dk }
 
   | otherwise
-  = unboundName WL_Any rdr_name
+  = reportUnboundName rdr_name
 
   where
-    suggest_dk = ptext (sLit "A data constructor of that name is in scope; did you mean -XDataKinds?")
+    suggest_dk = ptext (sLit "A data constructor of that name is in scope; did you mean DataKinds?")
 \end{code}
 
 Note [Demotion]
@@ -587,7 +624,7 @@ When the user writes:
 'Zero' in the type signature of 'foo' is parsed as:
   HsTyVar ("Zero", TcClsName)
 
-When the renamer hits this occurence of 'Zero' it's going to realise
+When the renamer hits this occurrence of 'Zero' it's going to realise
 that it's not in scope. But because it is renaming a type, it knows
 that 'Zero' might be a promoted data constructor, so it will demote
 its namespace to DataName and do a second lookup.
@@ -596,8 +633,23 @@ The final result (after the renamer) will be:
   HsTyVar ("Zero", DataName)
 
 \begin{code}
--- lookupOccRn looks up an occurrence of a RdrName
+--              Use this version to get tracing
+--
+-- lookupOccRn_maybe, lookupOccRn_maybe' :: RdrName -> RnM (Maybe Name)
+-- lookupOccRn_maybe rdr_name
+--  = do { mb_res <- lookupOccRn_maybe' rdr_name
+--       ; gbl_rdr_env   <- getGlobalRdrEnv
+--       ; local_rdr_env <- getLocalRdrEnv
+--       ; traceRn $ text "lookupOccRn_maybe" <+>
+--           vcat [ ppr rdr_name <+> ppr (getUnique (rdrNameOcc rdr_name))
+--                , ppr mb_res
+--                , text "Lcl env" <+> ppr local_rdr_env
+--                , text "Gbl env" <+> ppr [ (getUnique (nameOccName (gre_name (head gres'))),gres') | gres <- occEnvElts gbl_rdr_env
+--                                         , let gres' = filter isLocalGRE gres, not (null gres') ] ]
+--       ; return mb_res }
+
 lookupOccRn_maybe :: RdrName -> RnM (Maybe Name)
+-- lookupOccRn looks up an occurrence of a RdrName
 lookupOccRn_maybe rdr_name
   = do { local_env <- getLocalRdrEnv
        ; case lookupLocalRdrEnv local_env rdr_name of {
@@ -607,23 +659,10 @@ lookupOccRn_maybe rdr_name
        ; case mb_name of {
                 Just name  -> return (Just name) ;
                 Nothing -> do
-       { -- We allow qualified names on the command line to refer to
-         --  *any* name exported by any module in scope, just as if there
-         -- was an "import qualified M" declaration for every module.
-         -- But we DONT allow it under Safe Haskell as we need to check
-         -- imports. We can and should instead check the qualified import
-         -- but at the moment this requires some refactoring so leave as a TODO
-       ; dflags <- getDynFlags
-       ; let allow_qual = dopt Opt_ImplicitImportQualified dflags &&
-                          not (safeDirectImpsReq dflags)
-       ; is_ghci <- getIsGHCi
-               -- This test is not expensive,
-               -- and only happens for failed lookups
-       ; if isQual rdr_name && allow_qual && is_ghci
-         then lookupQualifiedName rdr_name
-         else do { traceRn (text "lookupOccRn" <+> ppr rdr_name)
-                 ; return Nothing } } } } } }
-
+       { dflags  <- getDynFlags
+       ; is_ghci <- getIsGHCi   -- This test is not expensive,
+                                -- and only happens for failed lookups
+       ; lookupQualifiedNameGHCi dflags is_ghci rdr_name } } } } }
 
 lookupGlobalOccRn :: RdrName -> RnM Name
 -- lookupGlobalOccRn is like lookupOccRn, except that it looks in the global
@@ -674,9 +713,9 @@ lookupGreRn rdr_name
         ; return (GRE { gre_name = name, gre_par = NoParent,
                         gre_prov = LocalDef }) }}}
 
-lookupGreLocalRn :: RdrName -> RnM (Maybe GlobalRdrElt)
+lookupGreLocalRn_maybe :: RdrName -> RnM (Maybe GlobalRdrElt)
 -- Similar, but restricted to locally-defined things
-lookupGreLocalRn rdr_name
+lookupGreLocalRn_maybe rdr_name
   = lookupGreRn_help rdr_name lookup_fn
   where
     lookup_fn env = filter isLocalGRE (lookupGRE_RdrName rdr_name env)
@@ -690,7 +729,7 @@ lookupGreRn_help rdr_name lookup
   = do  { env <- getGlobalRdrEnv
         ; case lookup env of
             []    -> return Nothing
-            [gre] -> do { addUsedRdrName gre rdr_name
+            [gre] -> do { addUsedRdrName True gre rdr_name
                         ; return (Just gre) }
             gres  -> do { addNameClashErrRn rdr_name gres
                         ; return (Just (head gres)) } }
@@ -719,13 +758,13 @@ Note [Handling of deprecations]
      - the things exported by a module export 'module M'
 
 \begin{code}
-addUsedRdrName :: GlobalRdrElt -> RdrName -> RnM ()
+addUsedRdrName :: Bool -> GlobalRdrElt -> RdrName -> RnM ()
 -- Record usage of imported RdrNames
-addUsedRdrName gre rdr
+addUsedRdrName warnIfDeprec gre rdr
   | isLocalGRE gre = return ()  -- No call to warnIfDeprecated
                                 -- See Note [Handling of deprecations]
   | otherwise      = do { env <- getGblEnv
-                        ; warnIfDeprecated gre
+                        ; when warnIfDeprec $ warnIfDeprecated gre
                         ; updMutVar (tcg_used_rdrnames env)
                                     (\s -> Set.insert rdr s) }
 
@@ -774,7 +813,7 @@ lookupImpDeprec iface gre
 
 Note [Used names with interface not loaded]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-It's (just) possible to to find a used
+It's (just) possible to find a used
 Name whose interface hasn't been loaded:
 
 a) It might be a WiredInName; in that case we may not load
@@ -798,26 +837,46 @@ this is, after all, wired-in stuff.
 %*                                                      *
 %*********************************************************
 
+A qualified name on the command line can refer to any module at
+all: we try to load the interface if we don't already have it, just
+as if there was an "import qualified M" declaration for every
+module.
+
+If we fail we just return Nothing, rather than bleating
+about "attempting to use module ā€˜Dā€™ (./D.hs) which is not loaded"
+which is what loadSrcInterface does.
+
+Note [Safe Haskell and GHCi]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We DONT do this Safe Haskell as we need to check imports. We can
+and should instead check the qualified import but at the moment
+this requires some refactoring so leave as a TODO
+
 \begin{code}
--- A qualified name on the command line can refer to any module at all: we
--- try to load the interface if we don't already have it.
-lookupQualifiedName :: RdrName -> RnM (Maybe Name)
-lookupQualifiedName rdr_name
+lookupQualifiedNameGHCi :: DynFlags -> Bool -> RdrName -> RnM (Maybe Name)
+lookupQualifiedNameGHCi dflags is_ghci rdr_name
   | Just (mod,occ) <- isQual_maybe rdr_name
-   -- Note: we want to behave as we would for a source file import here,
-   -- and respect hiddenness of modules/packages, hence loadSrcInterface.
-   = loadSrcInterface doc mod False Nothing     `thenM` \ iface ->
-
-   case  [ name
-         | avail <- mi_exports iface,
-           name  <- availNames avail,
-           nameOccName name == occ ] of
-      (n:ns) -> ASSERT (null ns) return (Just n)
-      _ -> do { traceRn (text "lookupQualified" <+> ppr rdr_name)
-              ; return Nothing }
+  , is_ghci
+  , gopt Opt_ImplicitImportQualified dflags   -- Enables this GHCi behaviour
+  , not (safeDirectImpsReq dflags)            -- See Note [Safe Haskell and GHCi]
+  = -- We want to behave as we would for a source file import here,
+    -- and respect hiddenness of modules/packages, hence loadSrcInterface.
+    do { res <- loadSrcInterface_maybe doc mod False Nothing
+       ; case res of
+           Succeeded iface
+             | (n:ns) <- [ name
+                         | avail <- mi_exports iface
+                         , name  <- availNames avail
+                         , nameOccName name == occ ]
+             -> ASSERT(null ns) return (Just n)
+
+           _ -> -- Either we couldn't load the interface, or
+                -- we could but we didn't find the name in it
+                do { traceRn (text "lookupQualifiedNameGHCi" <+> ppr rdr_name)
+                   ; return Nothing } }
 
   | otherwise
-  = pprPanic "RnEnv.lookupQualifiedName" (ppr rdr_name)
+  = return Nothing
   where
     doc = ptext (sLit "Need to find") <+> ppr rdr_name
 \end{code}
@@ -1026,18 +1085,6 @@ deprecation declarations, and lookup of names in GHCi.
 
 \begin{code}
 --------------------------------
-type FastStringEnv a = UniqFM a         -- Keyed by FastString
-
-
-emptyFsEnv  :: FastStringEnv a
-lookupFsEnv :: FastStringEnv a -> FastString -> Maybe a
-extendFsEnv :: FastStringEnv a -> FastString -> a -> FastStringEnv a
-
-emptyFsEnv  = emptyUFM
-lookupFsEnv = lookupUFM
-extendFsEnv = addToUFM
-
---------------------------------
 type MiniFixityEnv = FastStringEnv (Located Fixity)
         -- Mini fixity env for the names we're about
         -- to bind, in a single binding group
@@ -1055,7 +1102,7 @@ type MiniFixityEnv = FastStringEnv (Located Fixity)
 
 addLocalFixities :: MiniFixityEnv -> [Name] -> RnM a -> RnM a
 addLocalFixities mini_fix_env names thing_inside
-  = extendFixityEnv (mapCatMaybes find_fixity names) thing_inside
+  = extendFixityEnv (mapMaybe find_fixity names) thing_inside
   where
     find_fixity name
       = case lookupFsEnv mini_fix_env (occNameFS occ) of
@@ -1082,14 +1129,26 @@ lookupFixity is a bit strange.
 \begin{code}
 lookupFixityRn :: Name -> RnM Fixity
 lookupFixityRn name
-  = getModule                           `thenM` \ this_mod ->
-    if nameIsLocalOrFrom this_mod name
-    then do     -- It's defined in this module
-      local_fix_env <- getFixityEnv
-      traceRn (text "lookupFixityRn: looking up name in local environment:" <+>
-               vcat [ppr name, ppr local_fix_env])
-      return $ lookupFixity local_fix_env name
-    else        -- It's imported
+  | isUnboundName name
+  = return (Fixity minPrecedence InfixL) 
+    -- Minimise errors from ubound names; eg
+    --    a>0 `foo` b>0
+    -- where 'foo' is not in scope, should not give an error (Trac #7937)
+
+  | otherwise
+  = do { local_fix_env <- getFixityEnv
+       ; case lookupNameEnv local_fix_env name of {
+           Just (FixItem _ fix) -> return fix ;
+           Nothing ->
+
+    do { this_mod <- getModule
+       ; if nameIsLocalOrFrom this_mod name || isInteractiveModule (nameModule name)
+               -- Interactive modules are all in the fixity env,
+               -- and don't have entries in the HPT
+         then return defaultFixity
+         else lookup_imported } } }
+  where
+    lookup_imported
       -- For imported names, we have to get their fixities by doing a
       -- loadInterfaceForName, and consulting the Ifaces that comes back
       -- from that, because the interface file for the Name might not
@@ -1106,12 +1165,11 @@ lookupFixityRn name
       --
       -- loadInterfaceForName will find B.hi even if B is a hidden module,
       -- and that's what we want.
-        loadInterfaceForName doc name   `thenM` \ iface -> do {
-          traceRn (text "lookupFixityRn: looking up name in iface cache and found:" <+>
-                   vcat [ppr name, ppr $ mi_fix_fn iface (nameOccName name)]);
-           return (mi_fix_fn iface (nameOccName name))
-                                                           }
-  where
+      = do { iface <- loadInterfaceForName doc name
+           ; traceRn (text "lookupFixityRn: looking up name in iface cache and found:" <+>
+                      vcat [ppr name, ppr $ mi_fix_fn iface (nameOccName name)])
+           ; return (mi_fix_fn iface (nameOccName name)) }
+
     doc = ptext (sLit "Checking fixity for") <+> ppr name
 
 ---------------
@@ -1174,27 +1232,23 @@ lookupIfThenElse
 lookupSyntaxName :: Name                                -- The standard name
                  -> RnM (SyntaxExpr Name, FreeVars)     -- Possibly a non-standard name
 lookupSyntaxName std_name
-  = xoptM Opt_RebindableSyntax          `thenM` \ rebindable_on ->
-    if not rebindable_on then normal_case
-    else
-        -- Get the similarly named thing from the local environment
-    lookupOccRn (mkRdrUnqual (nameOccName std_name)) `thenM` \ usr_name ->
-    return (HsVar usr_name, unitFV usr_name)
-  where
-    normal_case = return (HsVar std_name, emptyFVs)
-
-lookupSyntaxTable :: [Name]                             -- Standard names
-                  -> RnM (SyntaxTable Name, FreeVars)   -- See comments with HsExpr.ReboundNames
-lookupSyntaxTable std_names
-  = xoptM Opt_RebindableSyntax          `thenM` \ rebindable_on ->
-    if not rebindable_on then normal_case
-    else
-        -- Get the similarly named thing from the local environment
-    mapM (lookupOccRn . mkRdrUnqual . nameOccName) std_names    `thenM` \ usr_names ->
-
-    return (std_names `zip` map HsVar usr_names, mkFVs usr_names)
-  where
-    normal_case = return (std_names `zip` map HsVar std_names, emptyFVs)
+  = do { rebindable_on <- xoptM Opt_RebindableSyntax
+       ; if not rebindable_on then 
+           return (HsVar std_name, emptyFVs)
+         else
+            -- Get the similarly named thing from the local environment
+           do { usr_name <- lookupOccRn (mkRdrUnqual (nameOccName std_name))
+              ; return (HsVar usr_name, unitFV usr_name) } }
+
+lookupSyntaxNames :: [Name]                          -- Standard names
+                  -> RnM ([HsExpr Name], FreeVars)   -- See comments with HsExpr.ReboundNames
+lookupSyntaxNames std_names
+  = do { rebindable_on <- xoptM Opt_RebindableSyntax
+       ; if not rebindable_on then 
+             return (map HsVar std_names, emptyFVs)
+        else
+          do { usr_names <- mapM (lookupOccRn . mkRdrUnqual . nameOccName) std_names
+             ; return (map HsVar usr_names, mkFVs usr_names) } }
 \end{code}
 
 
@@ -1235,15 +1289,14 @@ bindLocatedLocalsRn rdr_names_w_loc enclosed_scope
 
 bindLocalNames :: [Name] -> RnM a -> RnM a
 bindLocalNames names enclosed_scope
-  = do { name_env <- getLocalRdrEnv
-       ; setLocalRdrEnv (extendLocalRdrEnvList name_env names)
-                        enclosed_scope }
-
-bindLocalName :: Name -> RnM a -> RnM a
-bindLocalName name enclosed_scope
-  = do { name_env <- getLocalRdrEnv
-       ; setLocalRdrEnv (extendLocalRdrEnv name_env name)
-                        enclosed_scope }
+  = do { lcl_env <- getLclEnv
+       ; let th_level  = thLevel (tcl_th_ctxt lcl_env)
+             th_bndrs' = extendNameEnvList (tcl_th_bndrs lcl_env)
+                           [ (n, (NotTopLevel, th_level)) | n <- names ]
+             rdr_env'  = extendLocalRdrEnvList (tcl_rdr lcl_env) names
+       ; setLclEnv (lcl_env { tcl_th_bndrs = th_bndrs'
+                            , tcl_rdr      = rdr_env' })
+                    enclosed_scope }
 
 bindLocalNamesFV :: [Name] -> RnM (a, FreeVars) -> RnM (a, FreeVars)
 bindLocalNamesFV names enclosed_scope
@@ -1258,8 +1311,8 @@ bindLocatedLocalsFV :: [Located RdrName]
                     -> ([Name] -> RnM (a,FreeVars)) -> RnM (a, FreeVars)
 bindLocatedLocalsFV rdr_names enclosed_scope
   = bindLocatedLocalsRn rdr_names       $ \ names ->
-    enclosed_scope names                `thenM` \ (thing, fvs) ->
-    return (thing, delFVs names fvs)
+    do (thing, fvs) <- enclosed_scope names
+       return (thing, delFVs names fvs)
 
 -------------------------------------
 
@@ -1277,49 +1330,59 @@ checkDupRdrNames rdr_names_w_loc
 
 checkDupNames :: [Name] -> RnM ()
 -- Check for duplicated names in a binding group
-checkDupNames names
+checkDupNames names = check_dup_names (filterOut isSystemName names)
+                -- See Note [Binders in Template Haskell] in Convert
+
+check_dup_names :: [Name] -> RnM ()
+check_dup_names names
   = mapM_ (dupNamesErr nameSrcSpan) dups
   where
-    (_, dups) = removeDups (\n1 n2 -> nameOccName n1 `compare` nameOccName n2) $
-                filterOut isSystemName names
-                -- See Note [Binders in Template Haskell] in Convert
+    (_, dups) = removeDups (\n1 n2 -> nameOccName n1 `compare` nameOccName n2) names
 
 ---------------------
 checkShadowedRdrNames :: [Located RdrName] -> RnM ()
 checkShadowedRdrNames loc_rdr_names
   = do { envs <- getRdrEnvs
-       ; checkShadowedOccs envs loc_occs }
+       ; checkShadowedOccs envs get_loc_occ filtered_rdrs }
   where
-    loc_occs = [(loc,rdrNameOcc rdr) | L loc rdr <- loc_rdr_names]
+    filtered_rdrs = filterOut (isExact . unLoc) loc_rdr_names
+                -- See Note [Binders in Template Haskell] in Convert
+    get_loc_occ (L loc rdr) = (loc,rdrNameOcc rdr)
 
 checkDupAndShadowedNames :: (GlobalRdrEnv, LocalRdrEnv) -> [Name] -> RnM ()
 checkDupAndShadowedNames envs names
-  = do { checkDupNames names
-       ; checkShadowedOccs envs loc_occs }
+  = do { check_dup_names filtered_names
+       ; checkShadowedOccs envs get_loc_occ filtered_names }
   where
-    loc_occs = [(nameSrcSpan name, nameOccName name) | name <- names]
+    filtered_names = filterOut isSystemName names
+                -- See Note [Binders in Template Haskell] in Convert
+    get_loc_occ name = (nameSrcSpan name, nameOccName name)
 
 -------------------------------------
-checkShadowedOccs :: (GlobalRdrEnv, LocalRdrEnv) -> [(SrcSpan,OccName)] -> RnM ()
-checkShadowedOccs (global_env,local_env) loc_occs
-  = ifWOptM Opt_WarnNameShadowing $
-    do  { traceRn (text "shadow" <+> ppr loc_occs)
-        ; mapM_ check_shadow loc_occs }
+checkShadowedOccs :: (GlobalRdrEnv, LocalRdrEnv)
+                  -> (a -> (SrcSpan, OccName))
+                  -> [a] -> RnM ()
+checkShadowedOccs (global_env,local_env) get_loc_occ ns
+  = whenWOptM Opt_WarnNameShadowing $
+    do  { traceRn (text "shadow" <+> ppr (map get_loc_occ ns))
+        ; mapM_ check_shadow ns }
   where
-    check_shadow (loc, occ)
+    check_shadow n
         | startsWithUnderscore occ = return ()  -- Do not report shadowing for "_x"
                                                 -- See Trac #3262
         | Just n <- mb_local = complain [ptext (sLit "bound at") <+> ppr (nameSrcLoc n)]
         | otherwise = do { gres' <- filterM is_shadowed_gre gres
                          ; complain (map pprNameProvenance gres') }
         where
-          complain []      = return ()
-          complain pp_locs = addWarnAt loc (shadowedNameWarn occ pp_locs)
-          mb_local = lookupLocalRdrOcc local_env occ
-          gres     = lookupGRE_RdrName (mkRdrUnqual occ) global_env
+          (loc,occ) = get_loc_occ n
+          mb_local  = lookupLocalRdrOcc local_env occ
+          gres      = lookupGRE_RdrName (mkRdrUnqual occ) global_env
                 -- Make an Unqualified RdrName and look that up, so that
                 -- we don't find any GREs that are in scope qualified-only
 
+          complain []      = return ()
+          complain pp_locs = addWarnAt loc (shadowedNameWarn occ pp_locs)
+
     is_shadowed_gre :: GlobalRdrElt -> RnM Bool
         -- Returns False for record selectors that are shadowed, when
         -- punning or wild-cards are on (cf Trac #2723)
@@ -1349,19 +1412,21 @@ data WhereLooking = WL_Any        -- Any binding
                   | WL_Global     -- Any top-level binding (local or imported)
                   | WL_LocalTop   -- Any top-level binding in this module
 
+reportUnboundName :: RdrName -> RnM Name
+reportUnboundName rdr = unboundName WL_Any rdr
+
 unboundName :: WhereLooking -> RdrName -> RnM Name
 unboundName wl rdr = unboundNameX wl rdr empty
 
 unboundNameX :: WhereLooking -> RdrName -> SDoc -> RnM Name
 unboundNameX where_look rdr_name extra
-  = do  { show_helpful_errors <- doptM Opt_HelpfulErrors
+  = do  { show_helpful_errors <- goptM Opt_HelpfulErrors
         ; let what = pprNonVarNameSpace (occNameSpace (rdrNameOcc rdr_name))
               err = unknownNameErr what rdr_name $$ extra
         ; if not show_helpful_errors
           then addErr err
           else do { suggestions <- unknownNameSuggestErr where_look rdr_name
                   ; addErr (err $$ suggestions) }
-
         ; return (mkUnboundName rdr_name) }
 
 unknownNameErr :: SDoc -> RdrName -> SDoc
@@ -1387,7 +1452,7 @@ unknownNameSuggestErr where_look tried_rdr_name
              all_possibilities
                 =  [ (showPpr dflags r, (r, Left loc))
                    | (r,loc) <- local_possibilities local_env ]
-                ++ [ (showPpr dflags r, rp) | (r,rp) <- global_possibilities global_env ]
+                ++ [ (showPpr dflags r, rp) | (r, rp) <- global_possibilities global_env ]
 
              suggest = fuzzyLookup (showPpr dflags tried_rdr_name) all_possibilities
              perhaps = ptext (sLit "Perhaps you meant")
@@ -1399,19 +1464,24 @@ unknownNameSuggestErr where_look tried_rdr_name
        ; return extra_err }
   where
     pp_item :: (RdrName, HowInScope) -> SDoc
-    pp_item (rdr, Left loc) = quotes (ppr rdr) <+> loc' -- Locally defined
+    pp_item (rdr, Left loc) = pp_ns rdr <+> quotes (ppr rdr) <+> loc' -- Locally defined
         where loc' = case loc of
                      UnhelpfulSpan l -> parens (ppr l)
                      RealSrcSpan l -> parens (ptext (sLit "line") <+> int (srcSpanStartLine l))
-    pp_item (rdr, Right is) = quotes (ppr rdr) <+>   -- Imported
+    pp_item (rdr, Right is) = pp_ns rdr <+> quotes (ppr rdr) <+>   -- Imported
                               parens (ptext (sLit "imported from") <+> ppr (is_mod is))
 
+    pp_ns :: RdrName -> SDoc
+    pp_ns rdr | ns /= tried_ns = pprNameSpace ns
+              | otherwise      = empty
+      where ns = rdrNameSpace rdr
+
     tried_occ     = rdrNameOcc tried_rdr_name
     tried_is_sym  = isSymOcc tried_occ
     tried_ns      = occNameSpace tried_occ
     tried_is_qual = isQual tried_rdr_name
 
-    correct_name_space occ =  occNameSpace occ == tried_ns
+    correct_name_space occ =  nameSpacesRelated (occNameSpace occ) tried_ns
                            && isSymOcc occ == tried_is_sym
         -- Treat operator and non-operators as non-matching
         -- This heuristic avoids things like
@@ -1533,7 +1603,7 @@ mapFvRnCPS f (x:xs) cont = f x             $ \ x' ->
 \begin{code}
 warnUnusedTopBinds :: [GlobalRdrElt] -> RnM ()
 warnUnusedTopBinds gres
-    = ifWOptM Opt_WarnUnusedBinds
+    = whenWOptM Opt_WarnUnusedBinds
     $ do isBoot <- tcIsHsBoot
          let noParent gre = case gre_par gre of
                             NoParent -> True
@@ -1551,7 +1621,7 @@ warnUnusedMatches    = check_unused Opt_WarnUnusedMatches
 
 check_unused :: WarningFlag -> [Name] -> FreeVars -> RnM ()
 check_unused flag bound_names used_names
- = ifWOptM flag (warnUnusedLocals (filterOut (`elemNameSet` used_names) bound_names))
+ = whenWOptM flag (warnUnusedLocals (filterOut (`elemNameSet` used_names) bound_names))
 
 -------------------------
 --      Helpers
@@ -1597,11 +1667,14 @@ addUnusedWarning name span msg
 
 \begin{code}
 addNameClashErrRn :: RdrName -> [GlobalRdrElt] -> RnM ()
-addNameClashErrRn rdr_name names
+addNameClashErrRn rdr_name gres
+  | all isLocalGRE gres  -- If there are two or more *local* defns, we'll have reported
+  = return ()            -- that already, and we don't want an error cascade
+  | otherwise
   = addErr (vcat [ptext (sLit "Ambiguous occurrence") <+> quotes (ppr rdr_name),
                   ptext (sLit "It could refer to") <+> vcat (msg1 : msgs)])
   where
-    (np1:nps) = names
+    (np1:nps) = gres
     msg1 = ptext  (sLit "either") <+> mk_ref np1
     msgs = [ptext (sLit "    or") <+> mk_ref np | np <- nps]
     mk_ref gre = sep [quotes (ppr (gre_name gre)) <> comma, pprNameProvenance gre]
@@ -1614,7 +1687,7 @@ shadowedNameWarn occ shadowed_locs
 
 perhapsForallMsg :: SDoc
 perhapsForallMsg
-  = vcat [ ptext (sLit "Perhaps you intended to use -XExplicitForAll or similar flag")
+  = vcat [ ptext (sLit "Perhaps you intended to use ExplicitForAll or similar flag")
          , ptext (sLit "to enable explicit-forall syntax: forall <tvs>. <type>")]
 
 unknownSubordinateErr :: SDoc -> RdrName -> SDoc
@@ -1640,7 +1713,7 @@ dupNamesErr get_loc names
 kindSigErr :: Outputable a => a -> SDoc
 kindSigErr thing
   = hang (ptext (sLit "Illegal kind signature for") <+> quotes (ppr thing))
-       2 (ptext (sLit "Perhaps you intended to use -XKindSignatures"))
+       2 (ptext (sLit "Perhaps you intended to use KindSignatures"))
 
 badQualBndrErr :: RdrName -> SDoc
 badQualBndrErr rdr_name
@@ -1649,7 +1722,7 @@ badQualBndrErr rdr_name
 opDeclErr :: RdrName -> SDoc
 opDeclErr n
   = hang (ptext (sLit "Illegal declaration of a type or class operator") <+> quotes (ppr n))
-       2 (ptext (sLit "Use -XTypeOperators to declare operators in type and declarations"))
+       2 (ptext (sLit "Use TypeOperators to declare operators in type and declarations"))
 
 checkTupSize :: Int -> RnM ()
 checkTupSize tup_size