-
-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 are in the local envt)
-
- 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}
-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
-
-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 | isLocalName name = Nothing
- | otherwise = lookupType hst pte name
-
-
-tcEnvClasses env = [cl | AClass cl <- nameEnvElts (tcGEnv env)]
-tcEnvTyCons env = [tc | ATyCon tc <- nameEnvElts (tcGEnv env)]
-tcEnvIds env = [id | AnId id <- nameEnvElts (tcGEnv env)]
-tcEnvTyVars env = [tv | ATyVar tv <- nameEnvElts (tcLEnv env)]
-tcEnvTcIds env = [id | ATcId id <- nameEnvElts (tcLEnv env)]
-
-getTcGEnv (TcEnv { tcGEnv = genv }) = genv
-
--- This data type is used to help tie the knot
--- when type checking type and class declarations
-data TyThingDetails = SynTyDetails Type
- | DataTyDetails ClassContext [DataCon] [Id]
- | ClassDetails ClassContext [Id] [ClassOpItem] DataCon
-\end{code}
-
-
-%************************************************************************
-%* *
-\subsection{Basic lookups}
-%* *
-%************************************************************************
-
-\begin{code}
-lookup_global :: TcEnv -> Name -> Maybe TyThing
- -- Try the global envt and then the global symbol table
-lookup_global env name
- = case lookupNameEnv (tcGEnv env) name of
- Just thing -> Just thing
- Nothing -> tcGST env name
-
-lookup_local :: TcEnv -> Name -> Maybe TcTyThing
- -- Try the local envt and then try the global
-lookup_local env name
- = case lookupNameEnv (tcLEnv env) name of
- Just thing -> Just thing
- Nothing -> case lookup_global env name of
- Just thing -> Just (AGlobal thing)
- Nothing -> Nothing
-\end{code}
-
-\begin{code}
-type RecTcEnv = TcEnv
--- 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
-
-tcAddImportedIdInfo :: RecTcEnv -> Id -> Id
-tcAddImportedIdInfo env id
- = id `lazySetIdInfo` new_info
- -- The Id must be returned without a data dependency on maybe_id
- where
- new_info = case tcLookupRecId_maybe env (idName id) of
- Nothing -> constantIdInfo
- Just imported_id -> idInfo imported_id
- -- ToDo: could check that types are the same
-
-tcLookupRecId_maybe :: RecTcEnv -> Name -> Maybe Id
-tcLookupRecId_maybe env name = case lookup_global env name of
- Just (AnId id) -> Just id
- other -> Nothing
-
-tcLookupRecId :: RecTcEnv -> Name -> Id
-tcLookupRecId env name = case lookup_global env name of
- Just (AnId id) -> id
- Nothing -> pprPanic "tcLookupRecId" (ppr name)
-\end{code}
-
-%************************************************************************
-%* *
-\subsection{Random useful functions}
-%* *
-%************************************************************************
-
-
-\begin{code}
--- A useful function that takes an occurrence of a global thing
--- and instantiates its type with fresh type variables
-tcInstId :: Id
- -> NF_TcM ([TcTyVar], -- It's instantiated type
- TcThetaType, --
- TcType) --
-tcInstId id
- = let
- (tyvars, rho) = splitForAllTys (idType id)
- in
- tcInstTyVars tyvars `thenNF_Tc` \ (tyvars', arg_tys, tenv) ->
- let
- rho' = substTy tenv rho
- (theta', tau') = splitRhoTy rho'
- in
- returnNF_Tc (tyvars', theta', tau')