[project @ 2005-11-02 17:41:00 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcEnv.lhs
index 455fddf..1c7e722 100644 (file)
@@ -1,32 +1,30 @@
 \begin{code}
 module TcEnv(
-       TyThing(..), TyThingDetails(..), TcTyThing(..), TcId,
+       TyThing(..), TcTyThing(..), TcId,
 
        -- Instance environment, and InstInfo type
-       tcGetInstEnv, tcSetInstEnv, 
-       InstInfo(..), pprInstInfo, pprInstInfoDetails,
-       simpleInstInfoTy, simpleInstInfoTyCon, 
+       InstInfo(..), iDFunId, pprInstInfo, pprInstInfoDetails,
+       simpleInstInfoClsTy, simpleInstInfoTy, simpleInstInfoTyCon, 
        InstBindings(..),
 
        -- Global environment
        tcExtendGlobalEnv, 
        tcExtendGlobalValEnv,
-       tcExtendGlobalTypeEnv,
-       tcLookupTyCon, tcLookupClass, tcLookupDataCon,
-       tcLookupGlobal_maybe, tcLookupGlobal, tcLookupGlobalId,
-       getInGlobalScope,
-
+       tcLookupLocatedGlobal,  tcLookupGlobal, 
+       tcLookupGlobalId, tcLookupTyCon, tcLookupClass, tcLookupDataCon,
+       tcLookupLocatedGlobalId, tcLookupLocatedTyCon,
+       tcLookupLocatedClass, 
+       
        -- Local environment
-       tcExtendKindEnv,     
-       tcExtendTyVarEnv,    tcExtendTyVarEnv2, 
-       tcExtendLocalValEnv, tcExtendLocalValEnv2, 
-       tcLookup, tcLookupLocalIds, tcLookup_maybe, 
-       tcLookupId, tcLookupIdLvl, 
-       getLclEnvElts, getInLocalScope,
-       findGlobals,
+       tcExtendKindEnv, tcExtendKindEnvTvs,
+       tcExtendTyVarEnv, tcExtendTyVarEnv2, 
+       tcExtendIdEnv, tcExtendIdEnv1, tcExtendIdEnv2, 
+       tcLookup, tcLookupLocated, tcLookupLocalIds,
+       tcLookupId, tcLookupTyVar,
+       lclEnvElts, getInLocalScope, findGlobals, 
+       wrongThingErr, pprBinders,
 
-       -- Instance environment
-       tcExtendLocalInstEnv, tcExtendInstEnv, 
+       tcExtendRecEnv,         -- For knot-tying
 
        -- Rules
        tcExtendRules,
@@ -34,270 +32,157 @@ module TcEnv(
        -- Global type variables
        tcGetGlobalTyVars,
 
-       -- Random useful things
-       RecTcGblEnv, tcLookupRecId_maybe, 
-
        -- Template Haskell stuff
-       wellStaged, spliceOK, bracketOK, tcMetaTy, metaLevel,
+       checkWellStaged, spliceOK, bracketOK, tcMetaTy, thLevel, 
+       topIdLvl, 
 
        -- New Ids
-       newLocalName, newDFunName,
-
-       -- Misc
-       isLocalThing
+       newLocalName, newDFunName
   ) where
 
 #include "HsVersions.h"
 
-import RnHsSyn         ( RenamedMonoBinds, RenamedSig )
-import HsSyn           ( RuleDecl(..), ifaceRuleDeclName )
+import HsSyn           ( LRuleDecl, LHsBinds, LSig, 
+                         LHsTyVarBndr, HsTyVarBndr(..), pprLHsBinds )
+import TcIface         ( tcImportDecl )
+import IfaceEnv                ( newGlobalBinder )
 import TcRnMonad
-import TcMType         ( zonkTcType, zonkTcTyVar, zonkTcTyVarsAndFV )
-import TcType          ( Type, ThetaType, TcKind, TcTyVar, TcTyVarSet, 
-                         tyVarsOfType, tyVarsOfTypes, tcSplitDFunTy, mkGenTyConApp,
-                         getDFunTyKey, tcTyConAppTyCon, tyVarBindingInfo, 
-                         tidyOpenType, tidyOpenTyVar
+import TcMType         ( zonkTcType, zonkTcTyVarsAndFV )
+import TcType          ( Type, TcKind, TcTyVar, TcTyVarSet, TcType,
+                         tyVarsOfType, tyVarsOfTypes, mkGenTyConApp,
+                         getDFunTyKey, tcTyConAppTyCon, tcGetTyVar, mkTyVarTy,
+                         tidyOpenType 
                        )
 import qualified Type  ( getTyVar_maybe )
-import Rules           ( extendRuleBase )
-import Id              ( idName, isDataConWrapId_maybe )
-import Var             ( TyVar, Id, idType )
+import Id              ( idName, isLocalId )
+import Var             ( TyVar, Id, idType, tyVarName )
 import VarSet
 import VarEnv
-import CoreSyn         ( IdCoreRule )
+import RdrName         ( extendLocalRdrEnv )
+import InstEnv         ( Instance, DFunId, instanceDFunId, instanceHead )
 import DataCon         ( DataCon )
-import TyCon           ( TyCon, DataConDetails )
-import Class           ( Class, ClassOpItem )
-import Name            ( Name, NamedThing(..), 
-                         getSrcLoc, mkInternalName, nameIsLocalOrFrom
-                       )
+import TyCon           ( TyCon )
+import Class           ( Class )
+import Name            ( Name, NamedThing(..), getSrcLoc, nameModule )
+import PrelNames       ( thFAKE )
 import NameEnv
 import OccName         ( mkDFunOcc, occNameString )
-import HscTypes                ( DFunId, TypeEnv, extendTypeEnvList, 
-                         TyThing(..), ExternalPackageState(..) )
-import Rules           ( RuleBase )
-import BasicTypes      ( EP )
-import Module          ( Module )
-import InstEnv         ( InstEnv, extendInstEnv )
-import Maybes          ( seqMaybe )
-import SrcLoc          ( SrcLoc )
-import Outputable
-import Maybe           ( isJust )
-import List            ( partition )
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-               Meta level
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-instance Outputable Stage where
-   ppr Comp         = text "Comp"
-   ppr (Brack l _ _) = text "Brack" <+> int l
-   ppr (Splice l)    = text "Splice" <+> int l
-
-
-metaLevel :: Stage -> Level
-metaLevel Comp         = topLevel
-metaLevel (Splice l)    = l
-metaLevel (Brack l _ _) = l
-
-wellStaged :: Level    -- Binding level
-          -> Level     -- Use level
-          -> Bool
-wellStaged bind_stage use_stage 
-  = bind_stage <= use_stage
+import HscTypes                ( extendTypeEnvList, lookupType,
+                         TyThing(..), tyThingId, tyThingDataCon,
+                         ExternalPackageState(..) )
 
--- Indicates the legal transitions on bracket( [| |] ).
-bracketOK :: Stage -> Maybe Level
-bracketOK (Brack _ _ _) = Nothing      -- Bracket illegal inside a bracket
-bracketOK stage         = (Just (metaLevel stage + 1))
-
--- Indicates the legal transitions on splice($).
-spliceOK :: Stage -> Maybe Level
-spliceOK (Splice _) = Nothing  -- Splice illegal inside splice
-spliceOK stage      = Just (metaLevel stage - 1)
-
-tcMetaTy :: Name -> TcM Type
--- Given the name of a Template Haskell data type, 
--- return the type
--- E.g. given the name "Expr" return the type "Expr"
-tcMetaTy tc_name
-  = tcLookupTyCon tc_name      `thenM` \ t ->
-    returnM (mkGenTyConApp t [])
-       -- Use mkGenTyConApp because it might be a synonym
+import SrcLoc          ( SrcLoc, Located(..) )
+import Outputable
 \end{code}
 
 
 %************************************************************************
 %*                                                                     *
-\subsection{TyThingDetails}
+%*                     tcLookupGlobal                                  *
 %*                                                                     *
 %************************************************************************
 
-This data type is used to help tie the knot
- when type checking type and class declarations
-
-\begin{code}
-data TyThingDetails = SynTyDetails  Type
-                   | DataTyDetails ThetaType (DataConDetails DataCon) [Id] (Maybe (EP Id))
-                   | ClassDetails  ThetaType [Id] [ClassOpItem] DataCon Name
-                               -- The Name is the Name of the implicit TyCon for the class
-                   | ForeignTyDetails  -- Nothing yet
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\subsection{Basic lookups}
-%*                                                                     *
-%************************************************************************
+Using the Located versions (eg. tcLookupLocatedGlobal) is preferred,
+unless you know that the SrcSpan in the monad is already set to the
+span of the Name.
 
 \begin{code}
-type RecTcGblEnv = TcGblEnv
--- This environment is used for getting the 'right' IdInfo 
--- on imported things and for looking up Ids in unfoldings
--- The environment doesn't have any local Ids in it
-
-tcLookupRecId_maybe :: RecTcGblEnv -> Name -> Maybe Id
-tcLookupRecId_maybe env name = case lookup_global env name of
-                                  Just (AnId id) -> Just id
-                                  other          -> Nothing
-\end{code}
+tcLookupLocatedGlobal :: Located Name -> TcM TyThing
+-- c.f. IfaceEnvEnv.tcIfaceGlobal
+tcLookupLocatedGlobal name
+  = addLocM tcLookupGlobal name
 
-%************************************************************************
-%*                                                                     *
-\subsection{Making new Ids}
-%*                                                                     *
-%************************************************************************
+tcLookupGlobal :: Name -> TcM TyThing
+tcLookupGlobal name
+  = ASSERT( isGlobalName name )
+    do { env <- getGblEnv
+       
+               -- Try local envt
+       ; case lookupNameEnv (tcg_type_env env) name of {
+               Just thing -> return thing ;
+               Nothing    -> do 
+        
+               -- Try global envt
+       { (eps,hpt) <- getEpsAndHpt
+       ; case lookupType hpt (eps_PTE eps) name of  {
+           Just thing -> return thing ;
+           Nothing    -> do
+
+               -- Should it have been in the local envt?
+       { let mod = nameModule name
+       ; if mod == tcg_mod env || mod == thFAKE then
+               notFound name   -- It should be local, so panic
+                               -- The thFAKE possibility is because it
+                               -- might be in a declaration bracket
+         else
+               tcImportDecl name       -- Go find it in an interface
+       }}}}}
 
-Constructing new Ids
+tcLookupGlobalId :: Name -> TcM Id
+-- Never used for Haskell-source DataCons, hence no ADataCon case
+tcLookupGlobalId name
+  = tcLookupGlobal name                `thenM` \ thing ->
+    return (tyThingId thing)
 
-\begin{code}
-newLocalName :: Name -> TcM Name
-newLocalName name      -- Make a clone
-  = newUnique          `thenM` \ uniq ->
-    returnM (mkInternalName uniq (getOccName name) (getSrcLoc name))
-\end{code}
+tcLookupDataCon :: Name -> TcM DataCon
+tcLookupDataCon con_name
+  = tcLookupGlobal con_name    `thenM` \ thing ->
+    return (tyThingDataCon thing)
 
-Make a name for the dict fun for an instance decl.
-It's a *local* name for the moment.  The CoreTidy pass
-will externalise it.
+tcLookupClass :: Name -> TcM Class
+tcLookupClass name
+  = tcLookupGlobal name                `thenM` \ thing ->
+    case thing of
+       AClass cls -> return cls
+       other      -> wrongThingErr "class" (AGlobal thing) name
+       
+tcLookupTyCon :: Name -> TcM TyCon
+tcLookupTyCon name
+  = tcLookupGlobal name                `thenM` \ thing ->
+    case thing of
+       ATyCon tc -> return tc
+       other     -> wrongThingErr "type constructor" (AGlobal thing) name
 
-\begin{code}
-newDFunName :: Class -> [Type] -> SrcLoc -> TcM Name
-newDFunName clas (ty:_) loc
-  = newUnique                  `thenM` \ uniq ->
-    returnM (mkInternalName uniq (mkDFunOcc dfun_string) loc)
-  where
-       -- Any string that is somewhat unique will do
-    dfun_string = occNameString (getOccName clas) ++ occNameString (getDFunTyKey ty)
+tcLookupLocatedGlobalId :: Located Name -> TcM Id
+tcLookupLocatedGlobalId = addLocM tcLookupId
 
-newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc)
-\end{code}
+tcLookupLocatedClass :: Located Name -> TcM Class
+tcLookupLocatedClass = addLocM tcLookupClass
 
-\begin{code}
-isLocalThing :: NamedThing a => Module -> a -> Bool
-isLocalThing mod thing = nameIsLocalOrFrom mod (getName thing)
+tcLookupLocatedTyCon :: Located Name -> TcM TyCon
+tcLookupLocatedTyCon = addLocM tcLookupTyCon
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsection{The global environment}
+               Extending the global environment
 %*                                                                     *
 %************************************************************************
 
+
 \begin{code}
 tcExtendGlobalEnv :: [TyThing] -> TcM r -> TcM r
-  -- Given a mixture of Ids, TyCons, Classes, perhaps from the
-  -- module being compiled, perhaps from a package module,
-  -- extend the global environment, and update the EPS
+  -- Given a mixture of Ids, TyCons, Classes, all from the
+  -- module being compiled, extend the global environment
 tcExtendGlobalEnv things thing_inside
-   = do        { eps <- getEps
-       ; hpt <- getHpt
-       ; env <- getGblEnv
-       ; let mod = tcg_mod env
-             (lcl_things, pkg_things) = partition (isLocalThing mod) things
-             ge'  = extendTypeEnvList (tcg_type_env env) lcl_things
-             eps' = eps { eps_PTE = extendTypeEnvList (eps_PTE eps) pkg_things }
-             ist' = mkImpTypeEnv eps' hpt
-       ; setEps eps'
-       ; setGblEnv (env {tcg_type_env = ge', tcg_ist = ist'}) thing_inside }
+   = do        { env <- getGblEnv
+       ; let ge'  = extendTypeEnvList (tcg_type_env env) things
+       ; setGblEnv (env {tcg_type_env = ge'}) thing_inside }
 
 tcExtendGlobalValEnv :: [Id] -> TcM a -> TcM a
   -- Same deal as tcExtendGlobalEnv, but for Ids
 tcExtendGlobalValEnv ids thing_inside 
   = tcExtendGlobalEnv [AnId id | id <- ids] thing_inside
-
-tcExtendGlobalTypeEnv :: TypeEnv -> TcM r -> TcM r
-  -- Top-level things of the interactive context
-  -- No need to extend the package env
-tcExtendGlobalTypeEnv extra_env thing_inside
- = do { env <- getGblEnv 
-      ; let ge' = tcg_type_env env `plusNameEnv` extra_env 
-      ; setGblEnv (env {tcg_type_env = ge'}) thing_inside }
 \end{code}
 
-
 \begin{code}
-lookup_global :: TcGblEnv -> Name -> Maybe TyThing
-       -- Try the global envt and then the global symbol table
-lookup_global env name 
-  = lookupNameEnv (tcg_type_env env) name 
-       `seqMaybe`
-    tcg_ist env name
-
-tcLookupGlobal_maybe :: Name -> TcRn m (Maybe TyThing)
-tcLookupGlobal_maybe name
-  = getGblEnv          `thenM` \ env ->
-    returnM (lookup_global env name)
-\end{code}
-
-A variety of global lookups, when we know what we are looking for.
-
-\begin{code}
-tcLookupGlobal :: Name -> TcM TyThing
-tcLookupGlobal name
-  = tcLookupGlobal_maybe name  `thenM` \ maybe_thing ->
-    case maybe_thing of
-       Just thing -> returnM thing
-       other      -> notFound "tcLookupGlobal" name
-
-tcLookupGlobalId :: Name -> TcM Id
-tcLookupGlobalId name
-  = tcLookupGlobal_maybe name  `thenM` \ maybe_thing ->
-    case maybe_thing of
-       Just (AnId id) -> returnM id
-       other          -> notFound "tcLookupGlobal" name
-
-tcLookupDataCon :: Name -> TcM DataCon
-tcLookupDataCon con_name
-  = tcLookupGlobalId con_name  `thenM` \ con_id ->
-    case isDataConWrapId_maybe con_id of
-       Just data_con -> returnM data_con
-       Nothing       -> failWithTc (badCon con_id)
-
-tcLookupClass :: Name -> TcM Class
-tcLookupClass name
-  = tcLookupGlobal_maybe name  `thenM` \ maybe_clas ->
-    case maybe_clas of
-       Just (AClass clas) -> returnM clas
-       other              -> notFound "tcLookupClass" name
-       
-tcLookupTyCon :: Name -> TcM TyCon
-tcLookupTyCon name
-  = tcLookupGlobal_maybe name  `thenM` \ maybe_tc ->
-    case maybe_tc of
-       Just (ATyCon tc) -> returnM tc
-       other            -> notFound "tcLookupTyCon" name
-
-
-getInGlobalScope :: TcRn m (Name -> Bool)
-getInGlobalScope = do { gbl_env <- getGblEnv ;
-                       return (\n -> isJust (lookup_global gbl_env n)) }
+tcExtendRecEnv :: [(Name,TyThing)] -> TcM r -> TcM r
+-- Extend the global environments for the type/class knot tying game
+tcExtendRecEnv gbl_stuff thing_inside
+ = updGblEnv upd thing_inside
+ where
+   upd env = env { tcg_type_env = extend (tcg_type_env env) }
+   extend env = extendNameEnvList env gbl_stuff
 \end{code}
 
 
@@ -308,56 +193,48 @@ getInGlobalScope = do { gbl_env <- getGblEnv ;
 %************************************************************************
 
 \begin{code}
-tcLookup_maybe :: Name -> TcM (Maybe TcTyThing)
-tcLookup_maybe name
-  = getLclEnv          `thenM` \ local_env ->
-    case lookupNameEnv (tcl_env local_env) name of
-       Just thing -> returnM (Just thing)
-       Nothing    -> tcLookupGlobal_maybe name `thenM` \ mb_res ->
-                     returnM (case mb_res of
-                                Just thing -> Just (AGlobal thing)
-                                Nothing    -> Nothing)
+tcLookupLocated :: Located Name -> TcM TcTyThing
+tcLookupLocated = addLocM tcLookup
 
 tcLookup :: Name -> TcM TcTyThing
 tcLookup name
-  = tcLookup_maybe name                `thenM` \ maybe_thing ->
-    case maybe_thing of
+  = getLclEnv          `thenM` \ local_env ->
+    case lookupNameEnv (tcl_env local_env) name of
        Just thing -> returnM thing
-       other      -> notFound "tcLookup" name
-       -- Extract the IdInfo from an IfaceSig imported from an interface file
+       Nothing    -> tcLookupGlobal name `thenM` \ thing ->
+                     returnM (AGlobal thing)
+
+tcLookupTyVar :: Name -> TcM TcTyVar
+tcLookupTyVar name
+  = tcLookup name      `thenM` \ thing -> 
+    case thing of
+       ATyVar _ ty -> returnM (tcGetTyVar "tcLookupTyVar" ty)
+       other       -> pprPanic "tcLookupTyVar" (ppr name)
 
 tcLookupId :: Name -> TcM Id
 -- Used when we aren't interested in the binding level
+-- Never a DataCon. (Why does that matter? see TcExpr.tcId)
 tcLookupId name
   = tcLookup name      `thenM` \ thing -> 
     case thing of
-       ATcId tc_id lvl   -> returnM tc_id
+       ATcId tc_id _     -> returnM tc_id
        AGlobal (AnId id) -> returnM id
        other             -> pprPanic "tcLookupId" (ppr name)
 
-tcLookupIdLvl :: Name -> TcM (Id, Level)
-tcLookupIdLvl name
-  = tcLookup name      `thenM` \ thing -> 
-    case thing of
-       ATcId tc_id lvl   -> returnM (tc_id, lvl)
-       AGlobal (AnId id) -> returnM (id, impLevel)
-       other             -> pprPanic "tcLookupIdLvl" (ppr name)
-
 tcLookupLocalIds :: [Name] -> TcM [TcId]
 -- We expect the variables to all be bound, and all at
 -- the same level as the lookup.  Only used in one place...
 tcLookupLocalIds ns
   = getLclEnv          `thenM` \ env ->
-    returnM (map (lookup (tcl_env env) (metaLevel (tcl_level env))) ns)
+    returnM (map (lookup (tcl_env env) (thLevel (tcl_th_ctxt env))) ns)
   where
     lookup lenv lvl name 
        = case lookupNameEnv lenv name of
                Just (ATcId id lvl1) -> ASSERT( lvl == lvl1 ) id
                other                -> pprPanic "tcLookupLocalIds" (ppr name)
 
-getLclEnvElts :: TcM [TcTyThing]
-getLclEnvElts = getLclEnv      `thenM` \ env ->
-               return (nameEnvElts (tcl_env env))
+lclEnvElts :: TcLclEnv -> [TcTyThing]
+lclEnvElts env = nameEnvElts (tcl_env env)
 
 getInLocalScope :: TcM (Name -> Bool)
   -- Ids only
@@ -369,65 +246,72 @@ getInLocalScope = getLclEnv       `thenM` \ env ->
 \end{code}
 
 \begin{code}
-tcExtendKindEnv :: [(Name,TcKind)] -> TcM r -> TcM r
-tcExtendKindEnv pairs thing_inside
+tcExtendKindEnv :: [(Name, TcKind)] -> TcM r -> TcM r
+tcExtendKindEnv things thing_inside
+  = updLclEnv upd thing_inside
+  where
+    upd lcl_env = lcl_env { tcl_env = extend (tcl_env lcl_env) }
+    extend env  = extendNameEnvList env [(n, AThing k) | (n,k) <- things]
+
+tcExtendKindEnvTvs :: [LHsTyVarBndr Name] -> TcM r -> TcM r
+tcExtendKindEnvTvs bndrs thing_inside
   = updLclEnv upd thing_inside
   where
     upd lcl_env = lcl_env { tcl_env = extend (tcl_env lcl_env) }
-    extend env = extendNameEnvList env [(n, AThing k) | (n,k) <- pairs]
-       -- No need to extend global tyvars for kind checking
-    
+    extend env  = extendNameEnvList env pairs
+    pairs       = [(n, AThing k) | L _ (KindedTyVar n k) <- bndrs]
+
 tcExtendTyVarEnv :: [TyVar] -> TcM r -> TcM r
 tcExtendTyVarEnv tvs thing_inside
-  = tc_extend_tv_env [(getName tv, ATyVar tv) | tv <- tvs] tvs thing_inside
+  = tcExtendTyVarEnv2 [(tyVarName tv, mkTyVarTy tv) | tv <- tvs] thing_inside
 
-tcExtendTyVarEnv2 :: [(TyVar,TcTyVar)] -> TcM r -> TcM r
-tcExtendTyVarEnv2 tv_pairs thing_inside
-  = tc_extend_tv_env [(getName tv1, ATyVar tv2) | (tv1,tv2) <- tv_pairs]
-                    [tv | (_,tv) <- tv_pairs]
-                    thing_inside
-
-tc_extend_tv_env binds tyvars thing_inside
-  = getLclEnv     `thenM` \ env@(TcLclEnv {tcl_env = le, tcl_tyvars = gtvs}) ->
+tcExtendTyVarEnv2 :: [(Name,TcType)] -> TcM r -> TcM r
+tcExtendTyVarEnv2 binds thing_inside
+  = getLclEnv     `thenM` \ env@(TcLclEnv {tcl_env = le, 
+                                           tcl_tyvars = gtvs, 
+                                           tcl_rdr = rdr_env}) ->
     let
-       le'        = extendNameEnvList le binds
-       new_tv_set = mkVarSet tyvars
+       rdr_env'   = extendLocalRdrEnv rdr_env (map fst binds)
+       new_tv_set = tyVarsOfTypes (map snd binds)
+       le'        = extendNameEnvList le [(name, ATyVar name ty) | (name, ty) <- binds]
     in
        -- It's important to add the in-scope tyvars to the global tyvar set
        -- as well.  Consider
-       --      f (x::r) = let g y = y::r in ...
+       --      f (_::r) = let g y = y::r in ...
        -- Here, g mustn't be generalised.  This is also important during
        -- class and instance decls, when we mustn't generalise the class tyvars
        -- when typechecking the methods.
     tc_extend_gtvs gtvs new_tv_set             `thenM` \ gtvs' ->
-    setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs'}) thing_inside
+    setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs', tcl_rdr = rdr_env'}) thing_inside
 \end{code}
 
 
 \begin{code}
-tcExtendLocalValEnv :: [TcId] -> TcM a -> TcM a
-tcExtendLocalValEnv ids thing_inside
-  = getLclEnv          `thenM` \ env ->
-    let
-       extra_global_tyvars = tyVarsOfTypes [idType id | id <- ids]
-       lvl                 = metaLevel (tcl_level env)
-       extra_env           = [(idName id, ATcId id lvl) | id <- ids]
-       le'                 = extendNameEnvList (tcl_env env) extra_env
-    in
-    tc_extend_gtvs (tcl_tyvars env) extra_global_tyvars        `thenM` \ gtvs' ->
-    setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs'}) thing_inside
-
-tcExtendLocalValEnv2 :: [(Name,TcId)] -> TcM a -> TcM a
-tcExtendLocalValEnv2 names_w_ids thing_inside
+tcExtendIdEnv :: [TcId] -> TcM a -> TcM a
+-- Invariant: the TcIds are fully zonked. Reasons:
+--     (a) The kinds of the forall'd type variables are defaulted
+--         (see Kind.defaultKind, done in zonkQuantifiedTyVar)
+--     (b) There are no via-Indirect occurrences of the bound variables
+--         in the types, because instantiation does not look through such things
+--     (c) The call to tyVarsOfTypes is ok without looking through refs
+tcExtendIdEnv ids thing_inside = tcExtendIdEnv2 [(idName id, id) | id <- ids] thing_inside
+
+tcExtendIdEnv1 :: Name -> TcId -> TcM a -> TcM a
+tcExtendIdEnv1 name id thing_inside = tcExtendIdEnv2 [(name,id)] thing_inside
+
+tcExtendIdEnv2 :: [(Name,TcId)] -> TcM a -> TcM a
+-- Invariant: the TcIds are fully zonked (see tcExtendIdEnv above)
+tcExtendIdEnv2 names_w_ids thing_inside
   = getLclEnv          `thenM` \ env ->
     let
        extra_global_tyvars = tyVarsOfTypes [idType id | (name,id) <- names_w_ids]
-       lvl                 = metaLevel (tcl_level env)
-       extra_env           = [(name, ATcId id lvl) | (name,id) <- names_w_ids]
+       th_lvl              = thLevel    (tcl_th_ctxt   env)
+       extra_env           = [(name, ATcId id th_lvl) | (name,id) <- names_w_ids]
        le'                 = extendNameEnvList (tcl_env env) extra_env
+       rdr_env'            = extendLocalRdrEnv (tcl_rdr env) (map fst names_w_ids)
     in
     tc_extend_gtvs (tcl_tyvars env) extra_global_tyvars        `thenM` \ gtvs' ->
-    setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs'}) thing_inside
+    setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs', tcl_rdr = rdr_env'}) thing_inside
 \end{code}
 
 
@@ -439,12 +323,12 @@ tcExtendLocalValEnv2 names_w_ids thing_inside
 -- We must be careful to pass it a zonked type variable, too.
 
 findGlobals :: TcTyVarSet
-             -> TidyEnv 
-             -> TcM (TidyEnv, [SDoc])
+            -> TidyEnv 
+            -> TcM (TidyEnv, [SDoc])
 
 findGlobals tvs tidy_env
-  = getLclEnvElts      `thenM` \ lcl_env ->
-    go tidy_env [] lcl_env
+  = getLclEnv          `thenM` \ lcl_env ->
+    go tidy_env [] (lclEnvElts lcl_env)
   where
     go tidy_env acc [] = returnM (tidy_env, acc)
     go tidy_env acc (thing : things)
@@ -468,22 +352,22 @@ find_thing ignore_it tidy_env (ATcId id _)
     in
     returnM (tidy_env', Just msg)
 
-find_thing ignore_it tidy_env (ATyVar tv)
-  = zonkTcTyVar tv             `thenM` \ tv_ty ->
+find_thing ignore_it tidy_env (ATyVar tv ty)
+  = zonkTcType ty              `thenM` \ tv_ty ->
     if ignore_it tv_ty then
        returnM (tidy_env, Nothing)
     else let
-       (tidy_env1, tv1)     = tidyOpenTyVar tidy_env  tv
-       (tidy_env2, tidy_ty) = tidyOpenType  tidy_env1 tv_ty
-       msg = sep [ppr tv1 <+> eq_stuff, nest 2 bound_at]
+       -- The name tv is scoped, so we don't need to tidy it
+       (tidy_env1, tidy_ty) = tidyOpenType  tidy_env tv_ty
+       msg = sep [ptext SLIT("Scoped type variable") <+> quotes (ppr tv) <+> eq_stuff, nest 2 bound_at]
 
-       eq_stuff | Just tv' <- Type.getTyVar_maybe tv_ty, tv == tv' = empty
-                | otherwise                                        = equals <+> ppr tv_ty
+       eq_stuff | Just tv' <- Type.getTyVar_maybe tv_ty, 
+                  getOccName tv == getOccName tv' = empty
+                | otherwise = equals <+> ppr tidy_ty
                -- It's ok to use Type.getTyVar_maybe because ty is zonked by now
-       
-       bound_at = tyVarBindingInfo tv
+       bound_at = parens $ ptext SLIT("bound at:") <+> ppr (getSrcLoc tv)
     in
-    returnM (tidy_env2, Just msg)
+    returnM (tidy_env1, Just msg)
 \end{code}
 
 
@@ -516,100 +400,96 @@ tcGetGlobalTyVars
 
 %************************************************************************
 %*                                                                     *
-\subsection{The instance environment}
+\subsection{Rules}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-tcGetInstEnv :: TcM InstEnv
-tcGetInstEnv = getGblEnv       `thenM` \ env -> 
-              returnM (tcg_inst_env env)
-
-tcSetInstEnv :: InstEnv -> TcM a -> TcM a
-tcSetInstEnv ie thing_inside
-  = getGblEnv  `thenM` \ env ->
-    setGblEnv (env {tcg_inst_env = ie}) thing_inside
-
-tcExtendInstEnv :: [DFunId] -> TcM a -> TcM a
-       -- Add instances from local or imported
-       -- instances, and refresh the instance-env cache
-tcExtendInstEnv dfuns thing_inside
- = do { dflags <- getDOpts
-      ; eps <- getEps
-      ; env <- getGblEnv
-      ; let
-         -- Extend the total inst-env with the new dfuns
-         (inst_env', errs) = extendInstEnv dflags (tcg_inst_env env) dfuns
-  
-         -- Sort the ones from this module from the others
-         (lcl_dfuns, pkg_dfuns) = partition (isLocalThing mod) dfuns
-         mod = tcg_mod env
-  
-         -- And add the pieces to the right places
-                 (eps_inst_env', _) = extendInstEnv dflags (eps_inst_env eps) pkg_dfuns
-         eps'               = eps { eps_inst_env = eps_inst_env' }
-  
-         env'  = env { tcg_inst_env = inst_env', 
-                       tcg_insts = lcl_dfuns ++ tcg_insts env }
-
-      ; traceDFuns dfuns
-      ; addErrs errs
-      ; setEps eps'
-      ; setGblEnv env' thing_inside }
-
-tcExtendLocalInstEnv :: [InstInfo] -> TcM a -> TcM a
-  -- Special case for local instance decls
-tcExtendLocalInstEnv infos thing_inside
- = do { dflags <- getDOpts
-      ; env <- getGblEnv
+tcExtendRules :: [LRuleDecl Id] -> TcM a -> TcM a
+       -- Just pop the new rules into the EPS and envt resp
+       -- All the rules come from an interface file, not soruce
+       -- Nevertheless, some may be for this module, if we read
+       -- its interface instead of its source code
+tcExtendRules lcl_rules thing_inside
+ = do { env <- getGblEnv
       ; let
-         dfuns             = map iDFunId infos
-         (inst_env', errs) = extendInstEnv dflags (tcg_inst_env env) dfuns
-         env'              = env { tcg_inst_env = inst_env', 
-                                   tcg_insts = dfuns ++ tcg_insts env }
-      ; traceDFuns dfuns
-      ; addErrs errs
+         env' = env { tcg_rules = lcl_rules ++ tcg_rules env }
       ; setGblEnv env' thing_inside }
-
-traceDFuns dfuns
-  = traceTc (text "Adding instances:" <+> vcat (map pp dfuns))
-  where
-    pp dfun   = ppr dfun <+> dcolon <+> ppr (idType dfun)
 \end{code}
 
 
 %************************************************************************
 %*                                                                     *
-\subsection{Rules}
+               Meta level
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-tcExtendRules :: [RuleDecl Id] -> TcM a -> TcM a
-       -- Just pop the new rules into the EPS and envt resp
-       -- All the rules come from an interface file, not soruce
-       -- Nevertheless, some may be for this module, if we read
-       -- its interface instead of its source code
-tcExtendRules rules thing_inside
- = do { eps <- getEps
-      ; env <- getGblEnv
-      ; let
-         (lcl_rules, pkg_rules) = partition is_local_rule rules
-         is_local_rule = isLocalThing mod . ifaceRuleDeclName
-         mod = tcg_mod env
+instance Outputable ThStage where
+   ppr Comp         = text "Comp"
+   ppr (Brack l _ _) = text "Brack" <+> int l
+   ppr (Splice l)    = text "Splice" <+> int l
 
-         core_rules = [(id,rule) | IfaceRuleOut id rule <- pkg_rules]
-         eps'   = eps { eps_rule_base = addIfaceRules (eps_rule_base eps) core_rules }
-                 -- All the rules from an interface are of the IfaceRuleOut form
 
-         env' = env { tcg_rules = lcl_rules ++ tcg_rules env }
+thLevel :: ThStage -> ThLevel
+thLevel Comp         = topLevel
+thLevel (Splice l)    = l
+thLevel (Brack l _ _) = l
 
-      ; setEps eps' 
-      ; setGblEnv env' thing_inside }
 
-addIfaceRules :: RuleBase -> [IdCoreRule] -> RuleBase
-addIfaceRules rule_base rules
-  = foldl extendRuleBase rule_base rules
+checkWellStaged :: SDoc                -- What the stage check is for
+               -> ThLevel      -- Binding level
+               -> ThStage      -- Use stage
+               -> TcM ()       -- Fail if badly staged, adding an error
+checkWellStaged pp_thing bind_lvl use_stage
+  | bind_lvl <= use_lvl        -- OK!
+  = returnM () 
+
+  | bind_lvl == topLevel       -- GHC restriction on top level splices
+  = failWithTc $ 
+    sep [ptext SLIT("GHC stage restriction:") <+>  pp_thing,
+        nest 2 (ptext SLIT("is used in a top-level splice, and must be imported, not defined locally"))]
+
+  | otherwise                  -- Badly staged
+  = failWithTc $ 
+    ptext SLIT("Stage error:") <+> pp_thing <+> 
+       hsep   [ptext SLIT("is bound at stage") <+> ppr bind_lvl,
+               ptext SLIT("but used at stage") <+> ppr use_lvl]
+  where
+    use_lvl = thLevel use_stage
+
+
+topIdLvl :: Id -> ThLevel
+-- Globals may either be imported, or may be from an earlier "chunk" 
+-- (separated by declaration splices) of this module.  The former
+--  *can* be used inside a top-level splice, but the latter cannot.
+-- Hence we give the former impLevel, but the latter topLevel
+-- E.g. this is bad:
+--     x = [| foo |]
+--     $( f x )
+-- By the time we are prcessing the $(f x), the binding for "x" 
+-- will be in the global env, not the local one.
+topIdLvl id | isLocalId id = topLevel
+           | otherwise    = impLevel
+
+-- Indicates the legal transitions on bracket( [| |] ).
+bracketOK :: ThStage -> Maybe ThLevel
+bracketOK (Brack _ _ _) = Nothing      -- Bracket illegal inside a bracket
+bracketOK stage         = Just (thLevel stage + 1)
+
+-- Indicates the legal transitions on splice($).
+spliceOK :: ThStage -> Maybe ThLevel
+spliceOK (Splice _) = Nothing  -- Splice illegal inside splice
+spliceOK stage      = Just (thLevel stage - 1)
+
+tcMetaTy :: Name -> TcM Type
+-- Given the name of a Template Haskell data type, 
+-- return the type
+-- E.g. given the name "Expr" return the type "Expr"
+tcMetaTy tc_name
+  = tcLookupTyCon tc_name      `thenM` \ t ->
+    returnM (mkGenTyConApp t [])
+       -- Use mkGenTyConApp because it might be a synonym
 \end{code}
 
 
@@ -632,14 +512,17 @@ as well as explicit user written ones.
 \begin{code}
 data InstInfo
   = InstInfo {
-      iDFunId :: DFunId,               -- The dfun id
-      iBinds  :: InstBindings
+      iSpec  :: Instance,              -- Includes the dfun id.  Its forall'd type 
+      iBinds :: InstBindings           -- variables scope over the stuff in InstBindings!
     }
 
+iDFunId :: InstInfo -> DFunId
+iDFunId info = instanceDFunId (iSpec info)
+
 data InstBindings
   = VanillaInst                -- The normal case
-       RenamedMonoBinds        -- Bindings
-       [RenamedSig]            -- User pragmas recorded for generating 
+       (LHsBinds Name)         -- Bindings
+       [LSig Name]             -- User pragmas recorded for generating 
                                -- specialised instances
 
   | NewTypeDerived             -- Used for deriving instances of newtypes, where the
@@ -650,12 +533,17 @@ data InstBindings
 
 pprInstInfo info = vcat [ptext SLIT("InstInfo:") <+> ppr (idType (iDFunId info))]
 
-pprInstInfoDetails (InstInfo { iBinds = VanillaInst b _ }) = ppr b
-pprInstInfoDetails (InstInfo { iBinds = NewTypeDerived _}) = text "Derived from the representation type"
+pprInstInfoDetails info = pprInstInfo info $$ nest 2 (details (iBinds info))
+  where
+    details (VanillaInst b _)  = pprLHsBinds b
+    details (NewTypeDerived _) = text "Derived from the representation type"
+
+simpleInstInfoClsTy :: InstInfo -> (Class, Type)
+simpleInstInfoClsTy info = case instanceHead (iSpec info) of
+                         (_, _, cls, [ty]) -> (cls, ty)
 
 simpleInstInfoTy :: InstInfo -> Type
-simpleInstInfoTy info = case tcSplitDFunTy (idType (iDFunId info)) of
-                         (_, _, _, [ty]) -> ty
+simpleInstInfoTy info = snd (simpleInstInfoClsTy info)
 
 simpleInstInfoTyCon :: InstInfo -> TyCon
   -- Gets the type constructor for a simple instance declaration,
@@ -663,6 +551,24 @@ simpleInstInfoTyCon :: InstInfo -> TyCon
 simpleInstInfoTyCon inst = tcTyConAppTyCon (simpleInstInfoTy inst)
 \end{code}
 
+Make a name for the dict fun for an instance decl.  It's an *external*
+name, like otber top-level names, and hence must be made with newGlobalBinder.
+
+\begin{code}
+newDFunName :: Class -> [Type] -> SrcLoc -> TcM Name
+newDFunName clas (ty:_) loc
+  = do { index   <- nextDFunIndex
+       ; is_boot <- tcIsHsBoot
+       ; mod     <- getModule
+       ; let info_string = occNameString (getOccName clas) ++ 
+                           occNameString (getDFunTyKey ty)
+             dfun_occ = mkDFunOcc info_string is_boot index
+
+       ; newGlobalBinder mod dfun_occ Nothing loc }
+
+newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc)
+\end{code}
+
 
 %************************************************************************
 %*                                                                     *
@@ -671,8 +577,17 @@ simpleInstInfoTyCon inst = tcTyConAppTyCon (simpleInstInfoTy inst)
 %************************************************************************
 
 \begin{code}
-badCon con_id = quotes (ppr con_id) <+> ptext SLIT("is not a data constructor")
-
-notFound wheRe name = failWithTc (text wheRe <> colon <+> quotes (ppr name) <+> 
-                                 ptext SLIT("is not in scope"))
+pprBinders :: [Name] -> SDoc
+-- Used in error messages
+-- Use quotes for a single one; they look a bit "busy" for several
+pprBinders [bndr] = quotes (ppr bndr)
+pprBinders bndrs  = pprWithCommas ppr bndrs
+
+notFound name 
+  = failWithTc (ptext SLIT("GHC internal error:") <+> quotes (ppr name) <+> 
+               ptext SLIT("is not in scope"))
+
+wrongThingErr expected thing name
+  = failWithTc (pprTcTyThingCategory thing <+> quotes (ppr name) <+> 
+               ptext SLIT("used as a") <+> text expected)
 \end{code}