+import Id ( idName, isDataConWrapId_maybe )
+import Var ( TyVar, Id, idType )
+import VarSet
+import DataCon ( DataCon )
+import TyCon ( TyCon, DataConDetails )
+import Class ( Class, ClassOpItem )
+import Name ( Name, NamedThing(..),
+ getSrcLoc, mkInternalName, isInternalName, nameIsLocalOrFrom
+ )
+import NameEnv ( NameEnv, lookupNameEnv, nameEnvElts, elemNameEnv,
+ extendNameEnvList, emptyNameEnv, plusNameEnv )
+import OccName ( mkDFunOcc, occNameString )
+import HscTypes ( DFunId,
+ PackageTypeEnv, TypeEnv,
+ extendTypeEnvList, extendTypeEnvWithIds,
+ typeEnvTyCons, typeEnvClasses, typeEnvIds,
+ HomeSymbolTable
+ )
+import Module ( Module )
+import InstEnv ( InstEnv, emptyInstEnv )
+import HscTypes ( lookupType, TyThing(..) )
+import SrcLoc ( SrcLoc )
+import Outputable
+
+import IOExts ( newIORef )
+\end{code}
+
+%************************************************************************
+%* *
+\subsection{TcEnv}
+%* *
+%************************************************************************
+
+\begin{code}
+type TcId = Id -- Type may be a TcType
+type TcIdSet = IdSet
+
+data TcEnv
+ = TcEnv {
+ tcGST :: Name -> Maybe TyThing, -- The type environment at the moment we began this compilation
+
+ tcInsts :: InstEnv, -- All instances (both imported and in this module)
+
+ tcGEnv :: TypeEnv, -- The global type environment we've accumulated while
+ {- NameEnv TyThing-} -- compiling this module:
+ -- types and classes (both imported and local)
+ -- imported Ids
+ -- (Ids defined in this module start in the local envt,
+ -- though they move to the global envt during zonking)
+
+ tcLEnv :: NameEnv TcTyThing, -- The local type environment: Ids and TyVars
+ -- defined in this module
+
+ tcTyVars :: TcRef TcTyVarSet -- The "global tyvars"
+ -- Namely, the in-scope TyVars bound in tcLEnv, plus the tyvars
+ -- mentioned in the types of Ids bound in tcLEnv
+ -- Why mutable? see notes with tcGetGlobalTyVars
+ }
+
+\end{code}
+
+The Global-Env/Local-Env story
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+During type checking, we keep in the GlobalEnv
+ * All types and classes
+ * All Ids derived from types and classes (constructors, selectors)
+ * Imported Ids
+
+At the end of type checking, we zonk the local bindings,
+and as we do so we add to the GlobalEnv
+ * Locally defined top-level Ids
+
+Why? Because they are now Ids not TcIds. This final GlobalEnv is
+used thus:
+ a) fed back (via the knot) to typechecking the
+ unfoldings of interface signatures
+
+ b) used to augment the GlobalSymbolTable
+
+
+\begin{code}
+initTcEnv :: HomeSymbolTable -> PackageTypeEnv -> IO TcEnv
+initTcEnv hst pte
+ = do { gtv_var <- newIORef emptyVarSet ;
+ return (TcEnv { tcGST = lookup,
+ tcGEnv = emptyNameEnv,
+ tcInsts = emptyInstEnv,
+ tcLEnv = emptyNameEnv,
+ tcTyVars = gtv_var
+ })}
+ where
+ lookup name | isInternalName name = Nothing
+ | otherwise = lookupType hst pte name
+
+
+tcEnvClasses env = typeEnvClasses (tcGEnv env)
+tcEnvTyCons env = typeEnvTyCons (tcGEnv env)
+tcEnvIds env = typeEnvIds (tcGEnv env)
+tcLEnvElts env = nameEnvElts (tcLEnv env)
+
+getTcGEnv (TcEnv { tcGEnv = genv }) = genv
+
+tcInLocalScope :: TcEnv -> Name -> Bool
+tcInLocalScope env v = v `elemNameEnv` (tcLEnv env)
+\end{code}
+
+\begin{code}
+data TcTyThing
+ = AGlobal TyThing -- Used only in the return type of a lookup
+ | ATcId TcId -- Ids defined in this module
+ | ATyVar TyVar -- Type variables
+ | AThing TcKind -- Used temporarily, during kind checking
+-- Here's an example of how the AThing guy is used
+-- Suppose we are checking (forall a. T a Int):
+-- 1. We first bind (a -> AThink kv), where kv is a kind variable.
+-- 2. Then we kind-check the (T a Int) part.
+-- 3. Then we zonk the kind variable.
+-- 4. Now we know the kind for 'a', and we add (a -> ATyVar a::K) to the environment
+