import Inst ( InstOrigin(..), LIE, emptyLIE, plusLIE, plusLIEs,
newDicts, newMethod )
-import TcEnv ( TcId, TcEnv, TyThingDetails(..), tcAddImportedIdInfo,
+import TcEnv ( TcId, TcEnv, RecTcEnv, TyThingDetails(..), tcAddImportedIdInfo,
tcLookupClass, tcExtendTyVarEnvForMeths, tcExtendGlobalTyVars,
tcExtendLocalValEnv, tcExtendTyVarEnv, newDefaultMethodName
)
%************************************************************************
\begin{code}
-tcClassDecl1 :: TcEnv -> RenamedTyClDecl -> TcM (Name, TyThingDetails)
+tcClassDecl1 :: RecTcEnv -> RenamedTyClDecl -> TcM (Name, TyThingDetails)
tcClassDecl1 rec_env
(ClassDecl context class_name
tyvar_names fundeps class_sigs def_methods
is_tyvar other = False
-tcClassSig :: TcEnv -- Knot tying only!
+tcClassSig :: RecTcEnv
-> Class -- ...ditto...
-> [TyVar] -- The class type variable, used for error check only
-> [FunDep TyVar]
-- so we distinguish them in checkDefaultBinds, and pass this knowledge in the
-- Class.DefMeth data structure.
-tcClassSig rec_env clas clas_tyvars fds dm_info
+tcClassSig unf_env clas clas_tyvars fds dm_info
(ClassOpSig op_name maybe_dm op_ty src_loc)
= tcAddSrcLoc src_loc $
dm_info_id = case dm_info_name of
NoDefMeth -> NoDefMeth
GenDefMeth -> GenDefMeth
- DefMeth dm_name -> DefMeth (tcAddImportedIdInfo rec_env dm_id)
+ DefMeth dm_name -> DefMeth (tcAddImportedIdInfo unf_env dm_id)
where
dm_id = mkDefaultMethodId dm_name clas global_ty
in
-- 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, tcInstId,
-- New Ids
newLocalId, newSpecPragmaId,
newDefaultMethodName, newDFunName,
-- Misc
- isLocalThing, tcSetEnv, explicitLookupId
+ isLocalThing, tcSetEnv
) where
#include "HsVersions.h"
import TcType ( TcKind, TcType, TcTyVar, TcTyVarSet, TcThetaType,
tcInstTyVars, zonkTcTyVars,
)
-import Id ( mkUserLocal, isDataConWrapId_maybe )
+import Id ( idName, mkUserLocal, isDataConWrapId_maybe )
import IdInfo ( vanillaIdInfo )
import MkId ( mkSpecPragmaId )
import Var ( TyVar, Id, idType, lazySetIdInfo, idInfo )
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 env (idName id) of
+ Nothing -> vanillaIdInfo
+ Just imported_id -> idInfo imported_id
+ -- ToDo: could check that types are the same
+
+tcLookupRecId :: RecTcEnv -> Name -> Maybe Id
+tcLookupRecId env name = case lookup_global env name of
+ Just (AnId id) -> Just id
+ other -> Nothing
+
+\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}
-- Any string that is somewhat unique will do
dfun_string = occNameString (getOccName clas) ++ occNameString (getDFunTyKey ty)
+newDFunName mod clas [] loc = pprPanic "newDFunName" (ppr mod <+> ppr clas <+> ppr loc)
+
newDefaultMethodName :: Name -> SrcLoc -> NF_TcM Name
newDefaultMethodName op_name loc
= tcGetUnique `thenNF_Tc` \ uniq ->
-- so tcHsType will do the Right Thing without
-- having to mess about with zonking
-import TcEnv ( TcEnv, tcExtendTyVarEnv,
+import TcEnv ( TcEnv, RecTcEnv, tcExtendTyVarEnv,
tcExtendGlobalValEnv, tcSetEnv,
- tcLookupGlobal_maybe, explicitLookupId, tcEnvIds
+ tcLookupGlobal_maybe, tcLookupRecId, tcEnvIds
)
import RnHsSyn ( RenamedHsDecl )
signatures.
\begin{code}
-tcInterfaceSigs :: TcEnv -- Envt to use when checking unfoldings
+tcInterfaceSigs :: RecTcEnv -- Envt to use when checking unfoldings
-> [RenamedHsDecl] -- Ignore non-sig-decls in these decls
-> TcM [Id]
= listTc [ do_one name ty id_infos src_loc
| TyClD (IfaceSig name ty id_infos src_loc) <- decls]
where
- in_scope_vars = filter isLocallyDefined (tcEnvIds unf_env)
+ in_scope_vars = [] -- I think this will be OK
+ -- If so, don't pass it around
+ -- Was: filter isLocallyDefined (tcEnvIds unf_env)
do_one name ty id_infos src_loc
= tcAddSrcLoc src_loc $
= uniqSMToTcM (mkWrapper ty arity demands res_bot cpr_info) `thenNF_Tc` \ wrap_fn ->
let
-- Watch out! We can't pull on unf_env too eagerly!
- info' = case explicitLookupId unf_env worker_name of
- Just worker_id -> info `setUnfoldingInfo` mkTopUnfolding (wrap_fn worker_id)
- `setWorkerInfo` HasWorker worker_id arity
+ info' = case tcLookupRecId unf_env worker_name of
+ Just worker_id -> info `setUnfoldingInfo` mkTopUnfolding (wrap_fn worker_id)
+ `setWorkerInfo` HasWorker worker_id arity
- Nothing -> pprTrace "tcWorkerInfo failed:" (ppr worker_name) info
+ Nothing -> pprTrace "tcWorkerInfo failed:" (ppr worker_name) info
in
returnTc info'
where
where
doc = text "unfolding of" <+> ppr name
-tcDelay :: TcEnv -> SDoc -> TcM a -> NF_TcM (Maybe a)
+tcDelay :: RecTcEnv -> SDoc -> TcM a -> NF_TcM (Maybe a)
tcDelay unf_env doc thing_inside
= forkNF_Tc (
recoverNF_Tc bad_value (
import TcDefaults ( tcDefaults )
import TcEnv ( TcEnv, InstInfo(iDFunId), tcExtendGlobalValEnv,
tcEnvTyCons, tcEnvClasses, isLocalThing,
- tcSetEnv, tcSetInstEnv, initTcEnv, getTcGEnv
+ RecTcEnv, tcSetEnv, tcSetInstEnv, initTcEnv, getTcGEnv
)
import TcRules ( tcRules )
import TcForeign ( tcForeignImports, tcForeignExports )
import Type ( funResultTy, splitForAllTys )
import Bag ( isEmptyBag )
import ErrUtils ( printErrorsAndWarnings, dumpIfSet_dyn )
-import Id ( idType, idName, idUnfolding )
+import Id ( idType, idUnfolding )
import Module ( Module )
-import Name ( Name, nameOccName, isLocallyDefined, isGlobalName,
+import Name ( Name, isLocallyDefined,
toRdrName, nameEnvElts, lookupNameEnv,
)
import TyCon ( tyConGenInfo, isClassTyCon )
-import OccName ( isSysOcc )
import Maybes ( thenMaybe )
import Util
import BasicTypes ( EP(..), Fixity )
else
return Nothing
where
- tc_module :: TcM (TcEnv, TcResults)
+ tc_module :: TcM (RecTcEnv, TcResults)
tc_module = fixTc (\ ~(unf_env ,_) -> tcModule pcs hst get_fixity this_mod decls unf_env)
pit = pcs_PIT pcs
-> (Name -> Maybe Fixity)
-> Module
-> [RenamedHsDecl]
- -> TcEnv -- The knot-tied environment
+ -> RecTcEnv -- The knot-tied environment
-> TcM (TcEnv, TcResults)
- -- (unf_env :: TcEnv) is used for type-checking interface pragmas
+ -- (unf_env :: RecTcEnv) is used for type-checking interface pragmas
-- which is done lazily [ie failure just drops the pragma
-- without having any global-failure effect].
--
tcSetInstEnv inst_env $
-- Default declarations
- tcDefaults decls `thenTc` \ defaulting_tys ->
- tcSetDefaultTys defaulting_tys $
+ tcDefaults decls `thenTc` \ defaulting_tys ->
+ tcSetDefaultTys defaulting_tys $
-- Interface type signatures
-- We tie a knot so that the Ids read out of interfaces are in scope
-- imported
tcInterfaceSigs unf_env decls `thenTc` \ sig_ids ->
tcExtendGlobalValEnv sig_ids $
+ tcGetEnv `thenTc` \ unf_env ->
-- Create any necessary record selector Ids and their bindings
-- "Necessary" includes data and newtype declarations
pcs_rules = new_pcs_rules
}
in
- returnTc (final_env,
+ returnTc (unf_env,
TcResults { tc_pcs = final_pcs,
tc_env = local_type_env,
tc_binds = all_binds',
import BasicTypes ( RecFlag(..), NewOrData(..) )
import TcMonad
-import TcEnv ( TcEnv, TcTyThing(..), TyThing(..), TyThingDetails(..),
+import TcEnv ( TcEnv, RecTcEnv, TcTyThing(..), TyThing(..), TyThingDetails(..),
tcExtendKindEnv, tcLookup, tcExtendGlobalEnv )
import TcTyDecls ( tcTyDecl1, kcConDetails, mkNewTyConRep )
import TcClassDcl ( tcClassDecl1 )
The main function
~~~~~~~~~~~~~~~~~
\begin{code}
-tcTyAndClassDecls :: TcEnv -- Knot tying stuff
+tcTyAndClassDecls :: RecTcEnv -- Knot tying stuff
-> [RenamedHsDecl]
-> TcM TcEnv
tcGroups unf_env (group:groups)
= tcGroup unf_env group `thenTc` \ env ->
- tcSetEnv env $
+ tcSetEnv env $
tcGroups unf_env groups
\end{code}
@TyThing@s. @rec_vrcs@ is a finite map from @Name@s to @ArgVrcs@s.
\begin{code}
-tcGroup :: TcEnv -> SCC RenamedTyClDecl -> TcM TcEnv
+tcGroup :: RecTcEnv -> SCC RenamedTyClDecl -> TcM TcEnv
tcGroup unf_env scc
= getDOptsTc `thenTc` \ dflags ->
-- Step 1