-- Getting stuff from the environment
TcEnv, initTcEnv,
tcEnvTyCons, tcEnvClasses, tcEnvIds, tcEnvTcIds, tcEnvTyVars,
- getTcGST, getTcGEnv,
+ getTcGEnv,
-- Instance environment, and InstInfo type
tcGetInstEnv, tcSetInstEnv,
InstInfo(..), pprInstInfo,
- simpleInstInfoTy, simpleInstInfoTyCon, isLocalInst,
+ simpleInstInfoTy, simpleInstInfoTyCon,
-- Global environment
tcExtendGlobalEnv, tcExtendGlobalValEnv,
tcLookupTyCon, tcLookupClass, tcLookupGlobalId, tcLookupDataCon,
- tcLookupGlobal_maybe, tcLookupGlobal,
+ tcLookupGlobal_maybe, tcLookupGlobal,
-- Local environment
tcExtendKindEnv,
tcGetGlobalTyVars, tcExtendGlobalTyVars,
-- Random useful things
- tcAddImportedIdInfo, tcInstId,
+ RecTcEnv, tcAddImportedIdInfo, tcLookupRecId, tcLookupRecId_maybe, tcInstId,
-- New Ids
newLocalId, newSpecPragmaId,
- newDefaultMethodName, newDFunName,
+ newDFunName,
- -- ???
- tcSetEnv, explicitLookupId
+ -- Misc
+ isLocalThing, tcSetEnv
) where
#include "HsVersions.h"
tcInstTyVars, zonkTcTyVars,
)
import Id ( idName, mkUserLocal, isDataConWrapId_maybe )
-import IdInfo ( vanillaIdInfo )
+import IdInfo ( constantIdInfo )
import MkId ( mkSpecPragmaId )
import Var ( TyVar, Id, idType, lazySetIdInfo, idInfo )
import VarSet
-import Type ( Type, ThetaType,
- tyVarsOfTypes,
+import Type ( Type,
+ tyVarsOfTypes, splitDFunTy,
splitForAllTys, splitRhoTy,
- getDFunTyKey, splitTyConApp_maybe
+ getDFunTyKey, tyConAppTyCon
)
import DataCon ( DataCon )
import TyCon ( TyCon )
import Class ( Class, ClassOpItem, ClassContext )
import Subst ( substTy )
import Name ( Name, OccName, NamedThing(..),
- nameOccName, nameModule, getSrcLoc, mkGlobalName,
- isLocallyDefined, nameModule,
- NameEnv, lookupNameEnv, nameEnvElts,
- extendNameEnvList, emptyNameEnv
+ nameOccName, getSrcLoc, mkLocalName,
+ isLocalName, nameModule_maybe
)
-import OccName ( mkDFunOcc, mkDefaultMethodOcc, occNameString )
-import HscTypes ( DFunId )
+import Name ( NameEnv, lookupNameEnv, nameEnvElts, extendNameEnvList, emptyNameEnv )
+import OccName ( mkDFunOcc, occNameString )
+import HscTypes ( DFunId, TypeEnv, HomeSymbolTable, PackageTypeEnv )
import Module ( Module )
import InstEnv ( InstEnv, emptyInstEnv )
-import HscTypes ( lookupTypeEnv, TyThing(..), GlobalSymbolTable )
+import HscTypes ( lookupType, TyThing(..) )
import Util ( zipEqual )
import SrcLoc ( SrcLoc )
import Outputable
data TcEnv
= TcEnv {
- tcGST :: GlobalSymbolTable, -- The symbol table at the moment we began this compilation
+ 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 :: NameEnv TyThing, -- The global type environment we've accumulated while
- {- TypeEnv -} -- compiling 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)
-- 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 :: GlobalSymbolTable -> IO TcEnv
-initTcEnv gst
+initTcEnv :: HomeSymbolTable -> PackageTypeEnv -> IO TcEnv
+initTcEnv hst pte
= do { gtv_var <- newIORef emptyVarSet ;
- return (TcEnv { tcGST = gst,
+ 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)]
tcEnvTyVars env = [tv | ATyVar tv <- nameEnvElts (tcLEnv env)]
tcEnvTcIds env = [id | ATcId id <- nameEnvElts (tcLEnv env)]
-getTcGST (TcEnv { tcGST = gst }) = gst
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] [Class]
+ | DataTyDetails ClassContext [DataCon] [Id]
| ClassDetails ClassContext [Id] [ClassOpItem] DataCon
\end{code}
lookup_global env name
= case lookupNameEnv (tcGEnv env) name of
Just thing -> Just thing
- Nothing -> lookupTypeEnv (tcGST env) name
+ Nothing -> tcGST env name
lookup_local :: TcEnv -> Name -> Maybe TcTyThing
-- Try the local envt and then try the global
Nothing -> case lookup_global env name of
Just thing -> Just (AGlobal thing)
Nothing -> Nothing
-
-explicitLookupId :: TcEnv -> Name -> Maybe Id
-explicitLookupId env name = case lookup_global env name of
- Just (AnId id) -> Just id
- other -> 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 -> pprTrace "tcAddIdInfo" (ppr id) 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}
%************************************************************************
%* *
(theta', tau') = splitRhoTy rho'
in
returnNF_Tc (tyvars', theta', tau')
-
-tcAddImportedIdInfo :: TcEnv -> Id -> Id
-tcAddImportedIdInfo unf_env id
- | isLocallyDefined id -- Don't look up locally defined Ids, because they
- -- have explicit local definitions, so we get a black hole!
- = id
- | otherwise
- = id `lazySetIdInfo` new_info
- -- The Id must be returned without a data dependency on maybe_id
- where
- new_info = case explicitLookupId unf_env (getName id) of
- Nothing -> vanillaIdInfo
- Just imported_id -> idInfo imported_id
- -- ToDo: could check that types are the same
\end{code}
returnNF_Tc (mkSpecPragmaId (nameOccName name) uniq ty (getSrcLoc name))
\end{code}
-Make a name for the dict fun for an instance decl
+Make a name for the dict fun for an instance decl.
+It's a *local* name for the moment. The CoreTidy pass
+will globalise it.
\begin{code}
-newDFunName :: Module -> Class -> [Type] -> SrcLoc -> NF_TcM Name
-newDFunName mod clas (ty:_) loc
- = tcGetDFunUniq dfun_string `thenNF_Tc` \ inst_uniq ->
- tcGetUnique `thenNF_Tc` \ uniq ->
- returnNF_Tc (mkGlobalName uniq mod
- (mkDFunOcc dfun_string inst_uniq)
- loc)
+newDFunName :: Class -> [Type] -> SrcLoc -> NF_TcM Name
+newDFunName clas (ty:_) loc
+ = tcGetUnique `thenNF_Tc` \ uniq ->
+ returnNF_Tc (mkLocalName uniq (mkDFunOcc dfun_string) loc)
where
-- Any string that is somewhat unique will do
dfun_string = occNameString (getOccName clas) ++ occNameString (getDFunTyKey ty)
-newDefaultMethodName :: Name -> SrcLoc -> NF_TcM Name
-newDefaultMethodName op_name loc
- = tcGetUnique `thenNF_Tc` \ uniq ->
- returnNF_Tc (mkGlobalName uniq (nameModule op_name)
- (mkDefaultMethodOcc (getOccName op_name))
- loc)
+newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc)
\end{code}
+\begin{code}
+isLocalThing :: NamedThing a => Module -> a -> Bool
+ -- True if the thing has a Local name,
+ -- or a Global name from the specified module
+isLocalThing mod thing = case nameModule_maybe (getName thing) of
+ Nothing -> True -- A local name
+ Just m -> m == mod -- A global thing
+\end{code}
%************************************************************************
%* *
%************************************************************************
\begin{code}
-tcExtendGlobalEnv :: [(Name, TyThing)] -> TcM r -> TcM r
-tcExtendGlobalEnv bindings thing_inside
+tcExtendGlobalEnv :: [TyThing] -> TcM r -> TcM r
+tcExtendGlobalEnv things thing_inside
= tcGetEnv `thenNF_Tc` \ env ->
let
- ge' = extendNameEnvList (tcGEnv env) bindings
+ ge' = extendNameEnvList (tcGEnv env) [(getName thing, thing) | thing <- things]
in
tcSetEnv (env {tcGEnv = ge'}) thing_inside
tcExtendGlobalValEnv :: [Id] -> TcM a -> TcM a
tcExtendGlobalValEnv ids thing_inside
- = tcExtendGlobalEnv [(getName id, AnId id) | id <- ids] thing_inside
+ = tcGetEnv `thenNF_Tc` \ env ->
+ let
+ ge' = extendNameEnvList (tcGEnv env) [(getName id, AnId id) | id <- ids]
+ in
+ tcSetEnv (env {tcGEnv = ge'}) thing_inside
\end{code}
= tcLookupGlobal_maybe name `thenNF_Tc` \ maybe_thing ->
case maybe_thing of
Just thing -> returnNF_Tc thing
- other -> notFound "tcLookupGlobal:" name
+ other -> notFound "tcLookupGlobal" name
tcLookupGlobalId :: Name -> NF_TcM Id
tcLookupGlobalId name
= tcLookupGlobal_maybe name `thenNF_Tc` \ maybe_id ->
case maybe_id of
Just (AnId clas) -> returnNF_Tc clas
- other -> notFound "tcLookupGlobalId:" name
+ other -> notFound "tcLookupGlobalId" name
tcLookupDataCon :: Name -> TcM DataCon
tcLookupDataCon con_name
= tcLookupGlobal_maybe name `thenNF_Tc` \ maybe_clas ->
case maybe_clas of
Just (AClass clas) -> returnNF_Tc clas
- other -> notFound "tcLookupClass:" name
+ other -> notFound "tcLookupClass" name
tcLookupTyCon :: Name -> NF_TcM TyCon
tcLookupTyCon name
= tcLookupGlobal_maybe name `thenNF_Tc` \ maybe_tc ->
case maybe_tc of
Just (ATyCon tc) -> returnNF_Tc tc
- other -> notFound "tcLookupTyCon:" name
+ other -> notFound "tcLookupTyCon" name
\end{code}
= tcLookup_maybe name `thenNF_Tc` \ maybe_thing ->
case maybe_thing of
Just thing -> returnNF_Tc thing
- other -> notFound "tcLookup:" name
+ other -> notFound "tcLookup" name
-- Extract the IdInfo from an IfaceSig imported from an interface file
\end{code}
\begin{code}
data InstInfo
= InstInfo {
- iClass :: Class, -- Class, k
- iTyVars :: [TyVar], -- Type variables, tvs
- iTys :: [Type], -- The types at which the class is being instantiated
- iTheta :: ThetaType, -- inst_decl_theta: the original context, c, from the
- -- instance declaration. It constrains (some of)
- -- the TyVars above
- iLocal :: Bool, -- True <=> it's defined in this module
+ iLocal :: Bool, -- True <=> it's defined in this module
iDFunId :: DFunId, -- The dfun id
iBinds :: RenamedMonoBinds, -- Bindings, b
- iLoc :: SrcLoc, -- Source location assoc'd with this instance's defn
iPrags :: [RenamedSig] -- User pragmas recorded for generating specialised instances
}
nest 4 (ppr (iBinds info))]
simpleInstInfoTy :: InstInfo -> Type
-simpleInstInfoTy (InstInfo {iTys = [ty]}) = ty
+simpleInstInfoTy info = case splitDFunTy (idType (iDFunId info)) of
+ (_, _, _, [ty]) -> ty
simpleInstInfoTyCon :: InstInfo -> TyCon
-- Gets the type constructor for a simple instance declaration,
-- i.e. one of the form instance (...) => C (T a b c) where ...
-simpleInstInfoTyCon inst
- = case splitTyConApp_maybe (simpleInstInfoTy inst) of
- Just (tycon, _) -> tycon
-
-isLocalInst :: Module -> InstInfo -> Bool
-isLocalInst mod info = mod == nameModule (idName (iDFunId info))
+simpleInstInfoTyCon inst = tyConAppTyCon (simpleInstInfoTy inst)
\end{code}