Major refactoring of CoAxioms
[ghc.git] / compiler / rename / RnEnv.lhs
index f112915..ccce0c9 100644 (file)
@@ -4,57 +4,65 @@
 \section[RnEnv]{Environment manipulation for the renamer monad}
 
 \begin{code}
+{-# OPTIONS -fno-warn-tabs #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and
+-- detab the module (please do the detabbing in a separate patch). See
+--     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
+-- for details
+
 module RnEnv ( 
-       newTopSrcBinder, lookupFamInstDeclBndr,
+       newTopSrcBinder, 
        lookupLocatedTopBndrRn, lookupTopBndrRn,
-       lookupLocatedOccRn, lookupOccRn, 
-       lookupLocatedGlobalOccRn, 
-       lookupGlobalOccRn, lookupGlobalOccRn_maybe,
-       lookupLocalDataTcNames, lookupSigOccRn,
+       lookupLocatedOccRn, lookupOccRn, lookupLocalOccRn_maybe, lookupPromotedOccRn,
+        lookupGlobalOccRn, lookupGlobalOccRn_maybe,
+
+       HsSigCtxt(..), lookupLocalDataTcNames, lookupSigOccRn,
+
        lookupFixityRn, lookupTyFixityRn, 
-       lookupInstDeclBndr, lookupSubBndr, lookupConstructorFields,
-       lookupSyntaxName, lookupSyntaxTable, 
+       lookupInstDeclBndr, lookupSubBndrOcc, greRdrName,
+        lookupSubBndrGREs, lookupConstructorFields,
+       lookupSyntaxName, lookupSyntaxTable, lookupIfThenElse,
        lookupGreRn, lookupGreLocalRn, lookupGreRn_maybe,
        getLookupOccRn, addUsedRdrNames,
 
-       newLocalBndrRn, newLocalBndrsRn, newIPNameRn,
+       newLocalBndrRn, newLocalBndrsRn,
        bindLocalName, bindLocalNames, bindLocalNamesFV, 
        MiniFixityEnv, emptyFsEnv, extendFsEnv, lookupFsEnv,
        addLocalFixities,
        bindLocatedLocalsFV, bindLocatedLocalsRn,
        bindSigTyVarsFV, bindPatSigTyVars, bindPatSigTyVarsFV,
-       bindTyVarsRn, bindTyVarsFV, extendTyVarEnvFVRn,
+       extendTyVarEnvFVRn,
 
        checkDupRdrNames, checkDupAndShadowedRdrNames,
         checkDupNames, checkDupAndShadowedNames, 
        addFvRn, mapFvRn, mapMaybeFvRn, mapFvRnCPS,
        warnUnusedMatches,
        warnUnusedTopBinds, warnUnusedLocalBinds,
-       dataTcOccs, unknownNameErr, kindSigErr, perhapsForallMsg
+       dataTcOccs, unknownNameErr, kindSigErr, polyKindsErr, perhapsForallMsg,
+
+        HsDocContext(..), docOfHsDocContext
     ) where
 
 #include "HsVersions.h"
 
 import LoadIface       ( loadInterfaceForName, loadSrcInterface )
-import IfaceEnv                ( lookupOrig, newGlobalBinder, newIPName )
+import IfaceEnv
 import HsSyn
 import RdrHsSyn                ( extractHsTyRdrTyVars )
 import RdrName
-import HscTypes                ( availNames, ModIface(..), FixItem(..), lookupFixity)
+import HscTypes
 import TcEnv           ( tcLookupDataCon, tcLookupField, isBrackStage )
 import TcRnMonad
 import Id              ( isRecordSelector )
-import Name            ( Name, nameIsLocalOrFrom, mkInternalName, isWiredInName,
-                         nameSrcLoc, nameSrcSpan, nameOccName, nameModule, isExternalName )
+import Name
 import NameSet
 import NameEnv
+import Avail
+import Module           ( ModuleName, moduleName )
 import UniqFM
 import DataCon         ( dataConFieldLabels )
-import OccName
-import PrelNames       ( mkUnboundName, rOOT_MAIN, iNTERACTIVE, 
-                         consDataConKey, forall_tv_RDR )
-import Unique
-import BasicTypes
+import PrelNames        ( mkUnboundName, rOOT_MAIN, forall_tv_RDR )
 import ErrUtils                ( Message )
 import SrcLoc
 import Outputable
@@ -93,12 +101,19 @@ newTopSrcBinder (L loc rdr_name)
        -- very confused indeed. This test rejects code like
        --      data T = (,) Int Int
        -- unless we are in GHC.Tup
-    ASSERT2( isExternalName name,  ppr name )
-    do { this_mod <- getModule
-        ; unless (this_mod == nameModule name)
-                (addErrAt loc (badOrigBinding rdr_name))
-       ; return name }
-
+    if isExternalName name then
+      do { this_mod <- getModule
+         ; unless (this_mod == nameModule name)
+                 (addErrAt loc (badOrigBinding rdr_name))
+         ; return name }
+    else   -- See Note [Binders in Template Haskell] in Convert.hs
+      do { let occ = nameOccName name
+         ; occ `seq` return () -- c.f. seq in newGlobalBinder
+         ; this_mod <- getModule
+         ; updNameCache $ \ ns ->
+           let name' = mkExternalName (nameUnique name) this_mod occ loc
+               ns'   = ns { nsNames = extendNameCache (nsNames ns) this_mod occ name' }
+           in (ns', name') }
 
   | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name
   = do { this_mod <- getModule
@@ -168,7 +183,7 @@ lookupTopBndrRn n = do nopt <- lookupTopBndrRn_maybe n
                        case nopt of 
                          Just n' -> return n'
                          Nothing -> do traceRn $ text "lookupTopBndrRn"
-                                       unboundName n
+                                       unboundName WL_LocalTop n
 
 lookupLocatedTopBndrRn :: Located RdrName -> RnM (Located Name)
 lookupLocatedTopBndrRn = wrapLocM lookupTopBndrRn
@@ -192,7 +207,7 @@ lookupTopBndrRn_maybe :: RdrName -> RnM (Maybe Name)
 
 lookupTopBndrRn_maybe rdr_name
   | Just name <- isExact_maybe rdr_name
-  = return (Just name)
+  = do { name' <- lookupExactOcc name; return (Just name') }
 
   | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name   
        -- This deals with the case of derived bindings, where
@@ -217,7 +232,21 @@ lookupTopBndrRn_maybe rdr_name
              
 
 -----------------------------------------------
-lookupInstDeclBndr :: Name -> RdrName -> RnM 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) }
+
+-----------------------------------------------
+lookupInstDeclBndr :: Name -> SDoc -> RdrName -> RnM Name
 -- This is called on the method name on the left-hand side of an 
 -- instance declaration binding. eg.  instance Functor T where
 --                                       fmap = ...
@@ -229,15 +258,18 @@ lookupInstDeclBndr :: Name -> RdrName -> RnM Name
 -- name is only in scope qualified.  I.e. even if method op is
 -- in scope as M.op, we still allow plain 'op' on the LHS of
 -- an instance decl
-lookupInstDeclBndr cls rdr
+--
+-- The "what" parameter says "method" or "associated type",
+-- depending on what we are looking up
+lookupInstDeclBndr cls what rdr
   = do { when (isQual rdr)
                      (addErr (badQualBndrErr rdr)) 
                -- In an instance decl you aren't allowed
                -- to use a qualified name for the method
                -- (Although it'd make perfect sense.)
-       ; lookupSubBndr (ParentIs cls) doc rdr }
+       ; lookupSubBndrOcc (ParentIs cls) doc rdr }
   where
-    doc = ptext (sLit "method of class") <+> quotes (ppr cls)
+    doc = what <+> ptext (sLit "of class") <+> quotes (ppr cls)
 
 -----------------------------------------------
 lookupConstructorFields :: Name -> RnM [Name]
@@ -272,78 +304,128 @@ lookupConstructorFields con_name
 -- unambiguous because there is only one field id 'fld' in scope.
 -- But currently it's rejected.
 
-lookupSubBndr :: Parent  -- NoParent   => just look it up as usual
-                        -- ParentIs p => use p to disambiguate
-              -> SDoc -> RdrName 
-              -> RnM Name
-lookupSubBndr parent doc rdr_name
+lookupSubBndrOcc :: Parent  -- NoParent   => just look it up as usual
+                           -- ParentIs p => use p to disambiguate
+                 -> SDoc -> RdrName 
+                 -> RnM Name
+lookupSubBndrOcc parent doc rdr_name
   | Just n <- isExact_maybe rdr_name   -- This happens in derived code
-  = return n
+  = lookupExactOcc n
 
   | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name
   = lookupOrig rdr_mod rdr_occ
 
   | otherwise  -- Find all the things the rdr-name maps to
-  = do {       -- and pick the one with the right parent name
-       ; env <- getGlobalRdrEnv
-        ; let gres = lookupGlobalRdrEnv env (rdrNameOcc rdr_name)
-       ; case pick parent gres  of
+  = do {       -- and pick the one with the right parent namep
+         env <- getGlobalRdrEnv
+       ; case lookupSubBndrGREs env parent rdr_name of
                -- 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 { addUsedRdrNames (used_rdr_names gre)
+           [gre] -> do { addUsedRdrName gre (used_rdr_name gre)
+                          -- Add a usage; this is an *occurrence* site
                         ; return (gre_name gre) }
            []    -> do { addErr (unknownSubordinateErr doc rdr_name)
-                       ; traceRn (text "RnEnv.lookup_sub_bndr" <+> (ppr rdr_name $$ ppr gres))
                        ; return (mkUnboundName rdr_name) }
            gres  -> do { addNameClashErrRn rdr_name gres
                        ; return (gre_name (head gres)) } }
   where
-    pick NoParent gres         -- Normal lookup 
-      = pickGREs rdr_name gres
-    pick (ParentIs p) gres     -- Disambiguating lookup
-      | isUnqual rdr_name = filter (right_parent p) gres
-      | otherwise         = filter (right_parent p) (pickGREs rdr_name gres)
+    -- Note [Usage for sub-bndrs]
+    used_rdr_name gre
+      | isQual rdr_name = rdr_name
+      | otherwise       = greRdrName gre
 
-    right_parent p (GRE { gre_par = ParentIs p' }) = p==p' 
-    right_parent _ _                               = False
+greRdrName :: GlobalRdrElt -> RdrName
+greRdrName gre
+  = case gre_prov gre of
+      LocalDef    -> unqual_rdr
+      Imported is -> used_rdr_name_from_is is
 
-    -- Note [Usage for sub-bndrs]
-    used_rdr_names gre
-      | isQual rdr_name = [rdr_name]
-      | otherwise       = case gre_prov gre of
-                            LocalDef -> [rdr_name]
-                           Imported is -> map mk_qual_rdr is
-    mk_qual_rdr imp_spec = mkRdrQual (is_as (is_decl imp_spec)) rdr_occ
-    rdr_occ = rdrNameOcc rdr_name    
-
-newIPNameRn :: IPName RdrName -> TcRnIf m n (IPName Name)
-newIPNameRn ip_rdr = newIPName (mapIPName rdrNameOcc ip_rdr)
-
--- If the family is declared locally, it will not yet be in the main
--- environment; hence, we pass in an extra one here, which we check first.
--- See "Note [Looking up family names in family instances]" in 'RnNames'.
---
-lookupFamInstDeclBndr :: GlobalRdrEnv -> Located RdrName -> RnM Name
-lookupFamInstDeclBndr tyclGroupEnv (L loc rdr_name)
-  = setSrcSpan loc $
-      case lookupGRE_RdrName rdr_name tyclGroupEnv of
-        (gre:_) -> return $ gre_name gre
-          -- if there is more than one, an error will be raised elsewhere
-        []      -> lookupOccRn rdr_name
+  where 
+    occ = nameOccName (gre_name gre)
+    unqual_rdr = mkRdrUnqual occ
+
+    used_rdr_name_from_is imp_specs    -- rdr_name is unqualified
+      | not (all (is_qual . is_decl) imp_specs) 
+      = unqual_rdr  -- An unqualified import is available
+      | otherwise
+      =            -- Only qualified imports available, so make up 
+                   -- a suitable qualifed name from the first imp_spec
+        ASSERT( not (null imp_specs) )
+        mkRdrQual (is_as (is_decl (head imp_specs))) occ
+
+lookupSubBndrGREs :: GlobalRdrEnv -> Parent -> RdrName -> [GlobalRdrElt]
+-- If Parent = NoParent, just do a normal lookup
+-- If Parent = Parent p then find all GREs that
+--   (a) have parent p
+--   (b) for Unqual, are in scope qualified or unqualified
+--       for Qual, are in scope with that qualification
+lookupSubBndrGREs env parent rdr_name
+  = case parent of
+      NoParent   -> pickGREs rdr_name gres
+      ParentIs p 
+        | isUnqual rdr_name -> filter (parent_is p) gres
+        | otherwise         -> filter (parent_is p) (pickGREs rdr_name gres)
+
+  where
+    gres = lookupGlobalRdrEnv env (rdrNameOcc rdr_name)
+
+    parent_is p (GRE { gre_par = ParentIs p' }) = p == p'
+    parent_is _ _                               = False
 \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
    import qualified M( C( f ) ) 
-   intance M.C T where
+   instance M.C T where
      f x = x
 then is the qualified import M.f used?  Obviously yes.
 But the RdrName used in the instance decl is unqualified.  In effect,
 we fill in the qualification by looking for f's whose class is M.C
 But when adding to the UsedRdrNames we must make that qualification
-explicit, otherwise we get "Redundant import of M.C".
+explicit (saying "used  M.f"), otherwise we get "Redundant import of M.f".
+
+So we make up a suitable (fake) RdrName.  But be careful
+   import qualifed M
+   import M( C(f) )
+   instance C T where
+     f x = x
+Here we want to record a use of 'f', not of 'M.f', otherwise
+we'll miss the fact that the qualified import is redundant.
 
 --------------------------------------------------
 --             Occurrences
@@ -358,49 +440,103 @@ getLookupOccRn
 lookupLocatedOccRn :: Located RdrName -> RnM (Located Name)
 lookupLocatedOccRn = wrapLocM lookupOccRn
 
+lookupLocalOccRn_maybe :: RdrName -> RnM (Maybe Name)
+-- Just look in the local environment
+lookupLocalOccRn_maybe rdr_name 
+  = do { local_env <- getLocalRdrEnv
+       ; return (lookupLocalRdrEnv local_env rdr_name) }
+
 -- lookupOccRn looks up an occurrence of a RdrName
 lookupOccRn :: RdrName -> RnM Name
-lookupOccRn rdr_name
-  = getLocalRdrEnv                     `thenM` \ local_env ->
-    case lookupLocalRdrEnv local_env rdr_name of
-         Just name -> return name
-         Nothing   -> lookupGlobalOccRn rdr_name
+lookupOccRn rdr_name = do
+  opt_name <- lookupOccRn_maybe rdr_name
+  maybe (unboundName WL_Any rdr_name) return opt_name
+
+-- lookupPromotedOccRn looks up an optionally promoted RdrName.
+lookupPromotedOccRn :: RdrName -> RnM Name
+-- see Note [Demotion] 
+lookupPromotedOccRn rdr_name 
+  = do { mb_name <- lookupOccRn_maybe rdr_name 
+       ; case mb_name of {
+             Just name -> return name ;
+             Nothing   -> 
+
+    do { -- Maybe it's the name of a *data* constructor
+         poly_kinds <- xoptM Opt_PolyKinds
+       ; mb_demoted_name <- case demoteRdrName rdr_name of
+                              Just demoted_rdr -> lookupOccRn_maybe demoted_rdr
+                              Nothing          -> return Nothing
+       ; case mb_demoted_name of
+           Nothing -> unboundName WL_Any rdr_name
+           Just demoted_name 
+             | poly_kinds -> return demoted_name
+             | otherwise  -> unboundNameX WL_Any rdr_name suggest_pk }}}
+  where 
+    suggest_pk = ptext (sLit "A data constructor of that name is in scope; did you mean -XPolyKinds?")
+\end{code}
 
-lookupLocatedGlobalOccRn :: Located RdrName -> RnM (Located Name)
-lookupLocatedGlobalOccRn = wrapLocM lookupGlobalOccRn
+Note [Demotion]
+~~~~~~~~~~~~~~~
+When the user writes:
+  data Nat = Zero | Succ Nat
+  foo :: f Zero -> Int
 
-lookupGlobalOccRn :: RdrName -> RnM Name
--- lookupGlobalOccRn is like lookupOccRn, except that it looks in the global 
--- environment.  Adds an error message if the RdrName is not in scope.
--- Also has a special case for GHCi.
+'Zero' in the type signature of 'foo' is parsed as:
+  HsTyVar ("Zero", TcClsName)
 
-lookupGlobalOccRn rdr_name
-  = do { -- First look up the name in the normal environment.
-         mb_name <- lookupGlobalOccRn_maybe rdr_name
+When the renamer hits this occurence 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.
+
+The final result (after the renamer) will be:
+  HsTyVar ("Zero", DataName)
+
+\begin{code}
+-- lookupOccRn looks up an occurrence of a RdrName
+lookupOccRn_maybe :: RdrName -> RnM (Maybe Name)
+lookupOccRn_maybe rdr_name
+  = do { local_env <- getLocalRdrEnv
+       ; case lookupLocalRdrEnv local_env rdr_name of {
+          Just name -> return (Just name) ;
+          Nothing   -> do
+       { mb_name <- lookupGlobalOccRn_maybe rdr_name
        ; case mb_name of {
-               Just n  -> return n ;
-               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.
-        allow_qual <- doptM Opt_ImplicitImportQualified
-       ; mod <- getModule
+                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.
+         allow_qual <- doptM Opt_ImplicitImportQualified
+       ; is_ghci <- getIsGHCi
                -- This test is not expensive,
                -- and only happens for failed lookups
-       ; if isQual rdr_name && allow_qual && mod == iNTERACTIVE
+       ; if isQual rdr_name && allow_qual && is_ghci
          then lookupQualifiedName rdr_name
-         else unboundName rdr_name } } }
+         else do { traceRn (text "lookupOccRn" <+> ppr rdr_name)
+                 ; return Nothing } } } } } }
+
+
+lookupGlobalOccRn :: RdrName -> RnM Name
+-- lookupGlobalOccRn is like lookupOccRn, except that it looks in the global 
+-- environment.  Adds an error message if the RdrName is not in scope.
+lookupGlobalOccRn rdr_name
+  = do { mb_name <- lookupGlobalOccRn_maybe rdr_name
+       ; case mb_name of
+           Just n  -> return n
+           Nothing -> do { traceRn (text "lookupGlobalOccRn" <+> ppr rdr_name)
+                         ; unboundName WL_Global rdr_name } }
 
 lookupGlobalOccRn_maybe :: RdrName -> RnM (Maybe Name)
 -- No filter function; does not report an error on failure
 
 lookupGlobalOccRn_maybe rdr_name
   | Just n <- isExact_maybe rdr_name   -- This happens in derived code
-  = return (Just n)
+  = do { n' <- lookupExactOcc n; return (Just n') }
 
   | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name
-  = do { n <- lookupOrig rdr_mod rdr_occ; return (Just n) }
+  = do { n <- lookupOrig rdr_mod rdr_occ
+       ; return (Just n) }
 
   | otherwise
   = do { mb_gre <- lookupGreRn_maybe rdr_name
@@ -409,15 +545,6 @@ lookupGlobalOccRn_maybe rdr_name
                Just gre -> return (Just (gre_name gre)) }
 
 
-unboundName :: RdrName -> RnM Name
-unboundName rdr_name 
-  = do { addErr (unknownNameErr rdr_name)
-       ; env <- getGlobalRdrEnv;
-       ; traceRn (vcat [unknownNameErr rdr_name, 
-                        ptext (sLit "Global envt is:"),
-                        nest 3 (pprGlobalRdrEnv env)])
-       ; return (mkUnboundName rdr_name) }
-
 --------------------------------------------------
 --     Lookup in the Global RdrEnv of the module
 --------------------------------------------------
@@ -434,8 +561,8 @@ lookupGreRn rdr_name
        ; case mb_gre of {
            Just gre -> return gre ;
            Nothing  -> do
-       { traceRn $ text "lookupGreRn"
-       ; name <- unboundName rdr_name
+       { traceRn (text "lookupGreRn" <+> ppr rdr_name)
+        ; name <- unboundName WL_Global rdr_name
        ; return (GRE { gre_name = name, gre_par = NoParent,
                        gre_prov = LocalDef }) }}}
 
@@ -483,21 +610,20 @@ addUsedRdrNames rdrs
 
 -- 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 Name
+lookupQualifiedName :: RdrName -> RnM (Maybe Name)
 lookupQualifiedName 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  [ (mod,occ) | 
-          (mod,avails) <- mi_exports iface,
-          avail        <- avails,
-          name         <- availNames avail,
-          name == occ ] of
-      ((mod,occ):ns) -> ASSERT (null ns) 
-                       lookupOrig mod occ
-      _ -> unboundName rdr_name
+   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 }
 
   | otherwise
   = pprPanic "RnEnv.lookupQualifiedName" (ppr rdr_name)
@@ -527,75 +653,105 @@ return the imported 'f', so that later on the reanamer will
 correctly report "misplaced type sig".
 
 \begin{code}
-lookupSigOccRn :: Maybe NameSet           -- Just ns => these are the binders
-                                  --            in the same group
-                                  -- Nothing => signatures without 
-                                  --            binders are expected
-                                  --            (a) top-level (SPECIALISE prags)
-                                  --            (b) class decls
-                                  --            (c) hs-boot files
+data HsSigCtxt 
+  = HsBootCtxt              -- Top level of a hs-boot file
+  | TopSigCtxt              -- At top level
+  | LocalBindCtxt NameSet    -- In a local binding, binding these names
+  | ClsDeclCtxt   Name      -- Class decl for this class
+  | InstDeclCtxt  Name      -- Intsance decl for this class
+
+lookupSigOccRn :: HsSigCtxt
               -> Sig RdrName
               -> Located RdrName -> RnM (Located Name)
-lookupSigOccRn mb_bound_names sig
+lookupSigOccRn ctxt sig
   = wrapLocM $ \ rdr_name -> 
-    do { mb_name <- lookupBindGroupOcc mb_bound_names (hsSigDoc sig) rdr_name
+    do { mb_name <- lookupBindGroupOcc ctxt (hsSigDoc sig) rdr_name
        ; case mb_name of
           Left err   -> do { addErr err; return (mkUnboundName rdr_name) }
           Right name -> return name }
 
-lookupBindGroupOcc :: Maybe NameSet  -- See notes on the (Maybe NameSet)
-                  -> SDoc           --  in lookupSigOccRn
+lookupBindGroupOcc :: HsSigCtxt
+                  -> SDoc     
                   -> RdrName -> RnM (Either Message Name)
 -- Looks up the RdrName, expecting it to resolve to one of the 
 -- bound names passed in.  If not, return an appropriate error message
 --
 -- See Note [Looking up signature names]
-lookupBindGroupOcc mb_bound_names what rdr_name
-  = do  { local_env <- getLocalRdrEnv
-        ; case lookupLocalRdrEnv local_env rdr_name of 
-            Just n  -> check_local_name n
-            Nothing -> do       -- Not defined in a nested scope
-
-        { env <- getGlobalRdrEnv 
-        ; let gres = lookupGlobalRdrEnv env (rdrNameOcc rdr_name)
-        ; case (filter isLocalGRE gres) of
-            (gre:_) -> check_local_name (gre_name gre)
+lookupBindGroupOcc ctxt what rdr_name
+  | Just n <- isExact_maybe rdr_name
+  = do { n' <- lookupExactOcc n
+       ; return (Right n') }  -- Maybe we should check the side conditions
+                                     -- but it's a pain, and Exact things only show
+                             -- up when you know what you are doing
+
+  | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name
+  = do { n' <- lookupOrig rdr_mod rdr_occ
+       ; return (Right n') }
+
+  | otherwise
+  = case ctxt of 
+      HsBootCtxt       -> lookup_top               
+      TopSigCtxt       -> lookup_top
+      LocalBindCtxt ns -> lookup_group ns
+      ClsDeclCtxt  cls -> lookup_cls_op cls
+      InstDeclCtxt cls -> lookup_cls_op cls
+  where
+    lookup_cls_op cls
+      = do { env <- getGlobalRdrEnv 
+           ; let gres = lookupSubBndrGREs env (ParentIs cls) rdr_name
+           ; case gres of
+               []      -> return (Left (unknownSubordinateErr doc rdr_name))
+               (gre:_) -> return (Right (gre_name gre)) }
                         -- If there is more than one local GRE for the 
                         -- same OccName 'f', that will be reported separately
                         -- as a duplicate top-level binding for 'f'
-            [] | null gres -> bale_out_with empty
-               | otherwise -> bale_out_with import_msg
-        }}
-    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)
-                                  -> bale_out_with local_msg
-                 _other -> return (Right name)
-
-      bale_out_with msg 
+      where
+        doc = ptext (sLit "method of class") <+> quotes (ppr cls)
+
+    lookup_top
+      = do { env <- getGlobalRdrEnv 
+           ; let gres = lookupGlobalRdrEnv env (rdrNameOcc rdr_name)
+           ; case filter isLocalGRE gres of
+               [] | null gres -> bale_out_with empty
+                  | otherwise -> bale_out_with (bad_msg (ptext (sLit "an imported value")))
+               (gre:_) 
+                  | ParentIs {} <- gre_par gre
+                 -> bale_out_with (bad_msg (ptext (sLit "a record selector or class method")))
+                 | otherwise
+                  -> return (Right (gre_name gre)) }
+
+    lookup_group bound_names
+      = do { mb_name <- lookupOccRn_maybe rdr_name
+           ; case mb_name of
+               Just n  
+                 | n `elemNameSet` bound_names -> return (Right n)
+                 | otherwise                   -> bale_out_with local_msg
+               Nothing                         -> bale_out_with empty }
+
+    bale_out_with msg 
        = return (Left (sep [ ptext (sLit "The") <+> what
                                <+> ptext (sLit "for") <+> quotes (ppr rdr_name)
                           , nest 2 $ ptext (sLit "lacks an accompanying binding")]
                       $$ nest 2 msg))
 
-      local_msg = parens $ ptext (sLit "The")  <+> what <+> ptext (sLit "must be given where")
+    local_msg = parens $ ptext (sLit "The")  <+> what <+> ptext (sLit "must be given where")
                           <+> quotes (ppr rdr_name) <+> ptext (sLit "is declared")
 
-      import_msg = parens $ ptext (sLit "You cannot give a") <+> what
-                         <+> ptext (sLit "for an imported value")
+    bad_msg thing = parens $ ptext (sLit "You cannot give a") <+> what
+                         <+> ptext (sLit "for") <+> thing
+
 
 ---------------
 lookupLocalDataTcNames :: NameSet -> SDoc -> RdrName -> RnM [Name]
 -- GHC extension: look up both the tycon and data con 
--- for con-like things
+-- for con-like things.  Used for top-level fixity signatures
 -- Complain if neither is in scope
-lookupLocalDataTcNames bound_names what rdr_name
+lookupLocalDataTcNames bndr_set what rdr_name
   | Just n <- isExact_maybe rdr_name   
        -- Special case for (:), which doesn't get into the GlobalRdrEnv
-  = return [n] -- For this we don't need to try the tycon too
+  = do { n' <- lookupExactOcc n; return [n'] } -- For this we don't need to try the tycon too
   | otherwise
-  = do { mb_gres <- mapM (lookupBindGroupOcc (Just bound_names) what)
+  = do { mb_gres <- mapM (lookupBindGroupOcc (LocalBindCtxt bndr_set) what)
                          (dataTcOccs rdr_name)
        ; let (errs, names) = splitEithers mb_gres
        ; when (null names) (addErr (head errs))        -- Bleat about one only
@@ -606,21 +762,11 @@ dataTcOccs :: RdrName -> [RdrName]
 -- constructor.  This is useful when we aren't sure which we are
 -- looking at.
 dataTcOccs rdr_name
-  | Just n <- isExact_maybe rdr_name           -- Ghastly special case
-  , n `hasKey` consDataConKey = [rdr_name]     -- see note below
   | isDataOcc occ            = [rdr_name, rdr_name_tc]
   | otherwise                = [rdr_name]
   where    
     occ        = rdrNameOcc rdr_name
     rdr_name_tc = setRdrNameSpace rdr_name tcName
-
--- If the user typed "[]" or "(,,)", we'll generate an Exact RdrName,
--- and setRdrNameSpace generates an Orig, which is fine
--- But it's not fine for (:), because there *is* no corresponding type
--- constructor.  If we generate an Orig tycon for GHC.Base.(:), it'll
--- appear to be in scope (because Orig's simply allocate a new name-cache
--- entry) and then we get an error when we use dataTcOccs in 
--- TcRnDriver.tcRnGetInfo.  Large sigh.
 \end{code}
 
 
@@ -766,6 +912,17 @@ We treat the orignal (standard) names as free-vars too, because the type checker
 checks the type of the user thing against the type of the standard thing.
 
 \begin{code}
+lookupIfThenElse :: RnM (Maybe (SyntaxExpr Name), FreeVars)
+-- Different to lookupSyntaxName because in the non-rebindable
+-- case we desugar directly rather than calling an existing function
+-- Hence the (Maybe (SyntaxExpr Name)) return type
+lookupIfThenElse 
+  = do { rebind <- xoptM Opt_RebindableSyntax
+       ; if not rebind 
+         then return (Nothing, emptyFVs)
+         else do { ite <- lookupOccRn (mkVarUnqual (fsLit "ifThenElse"))
+                 ; return (Just (HsVar ite), unitFV ite) } }
+
 lookupSyntaxName :: Name                               -- The standard name
                 -> RnM (SyntaxExpr Name, FreeVars)     -- Possibly a non-standard name
 lookupSyntaxName std_name
@@ -806,8 +963,7 @@ newLocalBndrRn :: Located RdrName -> RnM Name
 newLocalBndrRn (L loc rdr_name)
   | Just name <- isExact_maybe rdr_name 
   = return name        -- This happens in code generated by Template Haskell
-               -- although I'm not sure why. Perhpas it's the call
-               -- in RnPat.newName LetMk?
+               -- See Note [Binders in Template Haskell] in Convert.lhs
   | otherwise
   = do { unless (isUnqual rdr_name)
                (addErrAt loc (badQualBndrErr rdr_name))
@@ -857,29 +1013,6 @@ bindLocatedLocalsFV rdr_names enclosed_scope
     return (thing, delFVs names fvs)
 
 -------------------------------------
-bindTyVarsFV ::  [LHsTyVarBndr RdrName]
-             -> ([LHsTyVarBndr Name] -> RnM (a, FreeVars))
-             -> RnM (a, FreeVars)
-bindTyVarsFV tyvars thing_inside
-  = bindTyVarsRn tyvars $ \ tyvars' ->
-    do { (res, fvs) <- thing_inside tyvars'
-       ; return (res, delFVs (map hsLTyVarName tyvars') fvs) }
-
-bindTyVarsRn ::  [LHsTyVarBndr RdrName]
-             -> ([LHsTyVarBndr Name] -> RnM a)
-             -> RnM a
--- Haskell-98 binding of type variables; e.g. within a data type decl
-bindTyVarsRn tyvar_names enclosed_scope
-  = bindLocatedLocalsRn located_tyvars $ \ names ->
-    do { kind_sigs_ok <- xoptM Opt_KindSignatures
-       ; unless (null kinded_tyvars || kind_sigs_ok) 
-                       (mapM_ (addErr . kindSigErr) kinded_tyvars)
-       ; enclosed_scope (zipWith replace tyvar_names names) }
-  where 
-    replace (L loc n1) n2 = L loc (replaceTyVarName n1 n2)
-    located_tyvars = hsLTyVarLocNames tyvar_names
-    kinded_tyvars  = [n | L _ (KindedTyVar n _) <- tyvar_names]
-
 bindPatSigTyVars :: [LHsType RdrName] -> ([Name] -> RnM a) -> RnM a
   -- Find the type variables in the pattern type 
   -- signatures that must be brought into scope
@@ -923,18 +1056,20 @@ extendTyVarEnvFVRn tyvars thing_inside = bindLocalNamesFV tyvars thing_inside
 
 -------------------------------------
 checkDupRdrNames :: [Located RdrName] -> RnM ()
+-- Check for duplicated names in a binding group
 checkDupRdrNames rdr_names_w_loc
-  =    -- Check for duplicated names in a binding group
-    mapM_ (dupNamesErr getLoc) dups
+  = mapM_ (dupNamesErr getLoc) dups
   where
     (_, dups) = removeDups (\n1 n2 -> unLoc n1 `compare` unLoc n2) rdr_names_w_loc
 
 checkDupNames :: [Name] -> RnM ()
+-- Check for duplicated names in a binding group
 checkDupNames names
-  =    -- Check for duplicated names in a binding group
-    mapM_ (dupNamesErr nameSrcSpan) dups
+  = mapM_ (dupNamesErr nameSrcSpan) dups
   where
-    (_, dups) = removeDups (\n1 n2 -> nameOccName n1 `compare` nameOccName n2) names
+    (_, dups) = removeDups (\n1 n2 -> nameOccName n1 `compare` nameOccName n2) $
+                filterOut isSystemName names
+               -- See Note [Binders in Template Haskell] in Convert
 
 ---------------------
 checkDupAndShadowedRdrNames :: [Located RdrName] -> RnM ()
@@ -955,7 +1090,7 @@ checkDupAndShadowedNames envs names
 -------------------------------------
 checkShadowedOccs :: (GlobalRdrEnv, LocalRdrEnv) -> [(SrcSpan,OccName)] -> RnM ()
 checkShadowedOccs (global_env,local_env) loc_occs
-  = ifDOptM Opt_WarnNameShadowing $ 
+  = ifWOptM Opt_WarnNameShadowing $ 
     do { traceRn (text "shadow" <+> ppr loc_occs)
        ; mapM_ check_shadow loc_occs }
   where
@@ -993,6 +1128,162 @@ checkShadowedOccs (global_env,local_env) loc_occs
 
 %************************************************************************
 %*                                                                     *
+               What to do when a lookup fails
+%*                                                                      *
+%************************************************************************
+
+\begin{code}
+data WhereLooking = WL_Any        -- Any binding
+                  | WL_Global     -- Any top-level binding (local or imported)
+                  | WL_LocalTop   -- Any top-level binding in this module
+
+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
+        ; let err = unknownNameErr rdr_name $$ extra
+        ; if not show_helpful_errors
+          then addErr err
+          else do { suggestions <- unknownNameSuggestErr where_look rdr_name
+                  ; addErr (err $$ suggestions) }
+
+        ; env <- getGlobalRdrEnv;
+       ; traceRn (vcat [unknownNameErr rdr_name, 
+                        ptext (sLit "Global envt is:"),
+                        nest 3 (pprGlobalRdrEnv env)])
+
+        ; return (mkUnboundName rdr_name) }
+
+unknownNameErr :: RdrName -> SDoc
+unknownNameErr rdr_name
+  = vcat [ hang (ptext (sLit "Not in scope:")) 
+             2 (pprNonVarNameSpace (occNameSpace (rdrNameOcc rdr_name))
+                         <+> quotes (ppr rdr_name))
+        , extra ]
+  where
+    extra | rdr_name == forall_tv_RDR = perhapsForallMsg
+         | otherwise                 = empty
+
+type HowInScope = Either SrcSpan ImpDeclSpec
+     -- Left loc    =>  locally bound at loc
+     -- Right ispec =>  imported as specified by ispec
+
+unknownNameSuggestErr :: WhereLooking -> RdrName -> RnM SDoc
+unknownNameSuggestErr where_look tried_rdr_name
+  = do { local_env <- getLocalRdrEnv
+       ; global_env <- getGlobalRdrEnv
+
+       ; let all_possibilities :: [(String, (RdrName, HowInScope))]
+             all_possibilities
+                =  [ (showSDoc (ppr r), (r, Left loc))
+                   | (r,loc) <- local_possibilities local_env ]
+                ++ [ (showSDoc (ppr r), rp) | (r,rp) <- global_possibilities global_env ]
+
+             suggest = fuzzyLookup (showSDoc (ppr tried_rdr_name)) all_possibilities
+             perhaps = ptext (sLit "Perhaps you meant")
+             extra_err = case suggest of
+                           []  -> empty
+                           [p] -> perhaps <+> pp_item p
+                           ps  -> sep [ perhaps <+> ptext (sLit "one of these:")
+                                      , nest 2 (pprWithCommas pp_item ps) ]
+       ; return extra_err }
+  where
+    pp_item :: (RdrName, HowInScope) -> SDoc
+    pp_item (rdr, Left loc) = 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
+                              parens (ptext (sLit "imported from") <+> ppr (is_mod is))
+
+    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
+                           && isSymOcc occ == tried_is_sym
+        -- Treat operator and non-operators as non-matching
+        -- This heuristic avoids things like
+        --      Not in scope 'f'; perhaps you meant '+' (from Prelude)
+
+    local_ok = case where_look of { WL_Any -> True; _ -> False }
+    local_possibilities :: LocalRdrEnv -> [(RdrName, SrcSpan)]
+    local_possibilities env
+      | tried_is_qual = []
+      | not local_ok  = []
+      | otherwise     = [ (mkRdrUnqual occ, nameSrcSpan name)
+                       | name <- occEnvElts env
+                       , let occ = nameOccName name
+                       , correct_name_space occ]
+
+    gre_ok :: GlobalRdrElt -> Bool
+    gre_ok = case where_look of
+                   WL_LocalTop -> isLocalGRE
+                   _           -> \_ -> True
+
+    global_possibilities :: GlobalRdrEnv -> [(RdrName, (RdrName, HowInScope))]
+    global_possibilities global_env
+      | tried_is_qual = [ (rdr_qual, (rdr_qual, how))
+                        | gre <- globalRdrEnvElts global_env
+                        , gre_ok gre
+                        , let name = gre_name gre
+                             occ  = nameOccName name
+                        , correct_name_space occ
+                        , (mod, how) <- quals_in_scope name (gre_prov gre)
+                        , let rdr_qual = mkRdrQual mod occ ]
+
+      | otherwise = [ (rdr_unqual, pair)
+                    | gre <- globalRdrEnvElts global_env
+                    , gre_ok gre
+                    , let name = gre_name gre
+                          prov = gre_prov gre
+                          occ  = nameOccName name
+                          rdr_unqual = mkRdrUnqual occ
+                    , correct_name_space occ
+                    , pair <- case (unquals_in_scope name prov, quals_only occ prov) of
+                                (how:_, _)    -> [ (rdr_unqual, how) ]
+                                ([],    pr:_) -> [ pr ]  -- See Note [Only-quals]
+                                ([],    [])   -> [] ]
+
+              -- Note [Only-quals]
+              -- The second alternative returns those names with the same
+              -- OccName as the one we tried, but live in *qualified* imports
+                     -- e.g. if you have:
+                     --
+                     -- > import qualified Data.Map as Map
+                     -- > foo :: Map
+                     --
+                     -- then we suggest @Map.Map@.
+
+    --------------------
+    unquals_in_scope :: Name -> Provenance -> [HowInScope]
+    unquals_in_scope n LocalDef      = [ Left (nameSrcSpan n) ]
+    unquals_in_scope _ (Imported is) = [ Right ispec
+                                       | i <- is, let ispec = is_decl i
+                                       , not (is_qual ispec) ]
+
+    --------------------
+    quals_in_scope :: Name -> Provenance -> [(ModuleName, HowInScope)]
+    -- Ones for which the qualified version is in scope
+    quals_in_scope n LocalDef      = case nameModule_maybe n of
+                                       Nothing -> []
+                                       Just m  -> [(moduleName m, Left (nameSrcSpan n))]
+    quals_in_scope _ (Imported is) = [ (is_as ispec, Right ispec)
+                                     | i <- is, let ispec = is_decl i ]
+
+    --------------------
+    quals_only :: OccName -> Provenance -> [(RdrName, HowInScope)]
+    -- Ones for which *only* the qualified version is in scope
+    quals_only _   LocalDef      = []
+    quals_only occ (Imported is) = [ (mkRdrQual (is_as ispec) occ, Right ispec)
+                                   | i <- is, let ispec = is_decl i, is_qual ispec ]
+\end{code}
+
+%************************************************************************
+%*                                                                     *
 \subsection{Free variable manipulation}
 %*                                                                     *
 %************************************************************************
@@ -1034,7 +1325,7 @@ mapFvRnCPS f (x:xs) cont = f x               $ \ x' ->
 \begin{code}
 warnUnusedTopBinds :: [GlobalRdrElt] -> RnM ()
 warnUnusedTopBinds gres
-    = ifDOptM Opt_WarnUnusedBinds
+    = ifWOptM Opt_WarnUnusedBinds
     $ do isBoot <- tcIsHsBoot
          let noParent gre = case gre_par gre of
                             NoParent -> True
@@ -1050,9 +1341,9 @@ warnUnusedLocalBinds, warnUnusedMatches :: [Name] -> FreeVars -> RnM ()
 warnUnusedLocalBinds = check_unused Opt_WarnUnusedBinds
 warnUnusedMatches    = check_unused Opt_WarnUnusedMatches
 
-check_unused :: DynFlag -> [Name] -> FreeVars -> RnM ()
+check_unused :: WarningFlag -> [Name] -> FreeVars -> RnM ()
 check_unused flag bound_names used_names
- = ifDOptM flag (warnUnusedLocals (filterOut (`elemNameSet` used_names) bound_names))
+ = ifWOptM flag (warnUnusedLocals (filterOut (`elemNameSet` used_names) bound_names))
 
 -------------------------
 --     Helpers
@@ -1113,16 +1404,6 @@ shadowedNameWarn occ shadowed_locs
            <+> ptext (sLit "shadows the existing binding") <> plural shadowed_locs,
         nest 2 (vcat shadowed_locs)]
 
-unknownNameErr :: RdrName -> SDoc
-unknownNameErr rdr_name
-  = vcat [ hang (ptext (sLit "Not in scope:")) 
-             2 (pprNonVarNameSpace (occNameSpace (rdrNameOcc rdr_name))
-                         <+> quotes (ppr rdr_name))
-        , extra ]
-  where
-    extra | rdr_name == forall_tv_RDR = perhapsForallMsg
-         | otherwise                 = empty
-
 perhapsForallMsg :: SDoc
 perhapsForallMsg 
   = vcat [ ptext (sLit "Perhaps you intended to use -XExplicitForAll or similar flag")
@@ -1153,6 +1434,11 @@ kindSigErr thing
   = hang (ptext (sLit "Illegal kind signature for") <+> quotes (ppr thing))
        2 (ptext (sLit "Perhaps you intended to use -XKindSignatures"))
 
+polyKindsErr :: Outputable a => a -> SDoc
+polyKindsErr thing
+  = hang (ptext (sLit "Illegal kind:") <+> quotes (ppr thing))
+       2 (ptext (sLit "Perhaps you intended to use -XPolyKinds"))
+
 
 badQualBndrErr :: RdrName -> SDoc
 badQualBndrErr rdr_name
@@ -1163,3 +1449,56 @@ 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"))
 \end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{Contexts for renaming errors}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+
+data HsDocContext
+  = TypeSigCtx SDoc
+  | PatCtx
+  | SpecInstSigCtx
+  | DefaultDeclCtx
+  | ForeignDeclCtx (Located RdrName)
+  | DerivDeclCtx
+  | RuleCtx FastString
+  | TyDataCtx (Located RdrName)
+  | TySynCtx (Located RdrName)
+  | TyFamilyCtx (Located RdrName)
+  | ConDeclCtx (Located RdrName)
+  | ClassDeclCtx (Located RdrName)
+  | ExprWithTySigCtx
+  | TypBrCtx
+  | HsTypeCtx
+  | GHCiCtx
+  | SpliceTypeCtx (LHsType RdrName)
+  | ClassInstanceCtx
+  | VectDeclCtx (Located RdrName)
+
+docOfHsDocContext :: HsDocContext -> SDoc
+docOfHsDocContext (TypeSigCtx doc) = text "In the type signature for" <+> doc
+docOfHsDocContext PatCtx = text "In a pattern type-signature"
+docOfHsDocContext SpecInstSigCtx = text "In a SPECIALISE instance pragma"
+docOfHsDocContext DefaultDeclCtx = text "In a `default' declaration"
+docOfHsDocContext (ForeignDeclCtx name) = ptext (sLit "In the foreign declaration for") <+> ppr name
+docOfHsDocContext DerivDeclCtx = text "In a deriving declaration"
+docOfHsDocContext (RuleCtx name) = text "In the transformation rule" <+> ftext name
+docOfHsDocContext (TyDataCtx tycon) = text "In the data type declaration for" <+> quotes (ppr tycon)
+docOfHsDocContext (TySynCtx name) = text "In the declaration for type synonym" <+> quotes (ppr name)
+docOfHsDocContext (TyFamilyCtx name) = text "In the declaration for type family" <+> quotes (ppr name)
+docOfHsDocContext (ConDeclCtx name) = text "In the definition of data constructor" <+> quotes (ppr name)
+docOfHsDocContext (ClassDeclCtx name) = text "In the declaration for class"    <+> ppr name
+docOfHsDocContext ExprWithTySigCtx = text "In an expression type signature"
+docOfHsDocContext TypBrCtx = ptext (sLit "In a Template-Haskell quoted type")
+docOfHsDocContext HsTypeCtx = text "In a type argument"
+docOfHsDocContext GHCiCtx = ptext (sLit "In GHCi input")
+docOfHsDocContext (SpliceTypeCtx hs_ty) = ptext (sLit "In the spliced type") <+> ppr hs_ty
+docOfHsDocContext ClassInstanceCtx = ptext (sLit "TcSplice.reifyInstances")
+docOfHsDocContext (VectDeclCtx tycon) = ptext (sLit "In the VECTORISE pragma for type constructor") <+> quotes (ppr tycon)
+
+\end{code}