InteractiveContext(..), emptyInteractiveContext,
icPrintUnqual, mkPrintUnqualified, extendInteractiveContext,
+ substInteractiveContext,
ModIface(..), mkIfaceDepCache, mkIfaceVerCache, mkIfaceFixCache,
emptyIfaceDepCache,
Linkable(..), isObjectLinkable,
Unlinked(..), CompiledByteCode,
isObject, nameOfObject, isInterpretable, byteCodeOfObject,
- HpcInfo(..), noHpcInfo,
+ HpcInfo(..), emptyHpcInfo, isHpcUsed, AnyHpcUsage,
-- Breakpoints
ModBreaks (..), BreakIndex, emptyModBreaks,
import {-# SOURCE #-} InteractiveEval ( Resume )
#endif
-import RdrName ( GlobalRdrEnv, emptyGlobalRdrEnv, GlobalRdrElt(..),
- unQualOK, ImpDeclSpec(..), Provenance(..),
- ImportSpec(..), lookupGlobalRdrEnv )
+import RdrName
import Name ( Name, NamedThing, getName, nameOccName, nameModule )
import NameEnv
import NameSet
import CoreSyn ( CoreBind )
import VarEnv
import VarSet
-import Var
+import Var hiding ( setIdType )
import Id
-import Type ( TyThing(..) )
+import Type
import Class ( Class, classSelIds, classATs, classTyCon )
import TyCon
import DataCon ( DataCon, dataConImplicitIds )
import PrelNames ( gHC_PRIM )
-import Packages ( PackageId )
+import Packages hiding ( Version(..) )
import DynFlags ( DynFlags(..), isOneShot, HscTarget (..) )
import DriverPhases ( HscSource(..), isHsBoot, hscSourceString, Phase )
import BasicTypes ( Version, initialVersion, IPName,
import UniqFM ( lookupUFM, eltsUFM, emptyUFM )
import UniqSupply ( UniqSupply )
import FastString ( FastString )
-
import StringBuffer ( StringBuffer )
import System.Time ( ClockTime )
import Data.IORef
import Data.Array ( Array, array )
+import Data.List
\end{code}
instance Outputable Target where
ppr = pprTarget
+pprTargetId :: TargetId -> SDoc
pprTargetId (TargetModule m) = ppr m
pprTargetId (TargetFile f _) = text f
type PackageIfaceTable = ModuleEnv ModIface
-- Domain = modules in the imported packages
+emptyHomePackageTable :: HomePackageTable
emptyHomePackageTable = emptyUFM
+
+emptyPackageIfaceTable :: PackageIfaceTable
emptyPackageIfaceTable = emptyModuleEnv
data HomeModInfo
-- and are not put into the interface file
mi_dep_fn :: Name -> Maybe DeprecTxt, -- Cached lookup for mi_deprecs
mi_fix_fn :: OccName -> Fixity, -- Cached lookup for mi_fixities
- mi_ver_fn :: OccName -> Maybe (OccName, Version)
+ mi_ver_fn :: OccName -> Maybe (OccName, Version),
-- Cached lookup for mi_decls
-- The Nothing in mi_ver_fn means that the thing
-- isn't in decls. It's useful to know that when
-- seeing if we are up to date wrt the old interface
-- The 'OccName' is the parent of the name, if it has one.
+ mi_hpc :: !AnyHpcUsage
+ -- True if this program uses Hpc at any point in the program.
}
-- Should be able to construct ModDetails from mi_decls in ModIface
md_insts :: ![Instance], -- Dfun-ids for the instances in this module
md_fam_insts :: ![FamInst],
md_rules :: ![CoreRule], -- Domain may include Ids from other modules
- md_modBreaks :: !ModBreaks, -- Breakpoint information for this module
md_vect_info :: !VectInfo -- Vectorisation information
}
+emptyModDetails :: ModDetails
emptyModDetails = ModDetails { md_types = emptyTypeEnv,
md_exports = [],
md_insts = [],
md_rules = [],
md_fam_insts = [],
- md_modBreaks = emptyModBreaks,
md_vect_info = noVectInfo
}
mg_usages :: ![Usage], -- Version info for what it needed
mg_rdr_env :: !GlobalRdrEnv, -- Top-level lexical environment
- mg_fix_env :: !FixityEnv, -- Fixity env, for things declared in
- -- this module
-
- mg_fam_inst_env :: FamInstEnv, -- Type-family instance enviroment
- -- for *home-package* modules (including
- -- this one). c.f. tcg_fam_inst_env
+ -- These fields all describe the things **declared in this module**
+ mg_fix_env :: !FixityEnv, -- Fixities
mg_types :: !TypeEnv,
mg_insts :: ![Instance], -- Instances
mg_fam_insts :: ![FamInst], -- Instances
mg_deprecs :: !Deprecations, -- Deprecations declared in the module
mg_hpc_info :: !HpcInfo, -- info about coverage tick boxes
mg_modBreaks :: !ModBreaks,
- mg_vect_info :: !VectInfo -- Pool of vectorised declarations
+ mg_vect_info :: !VectInfo, -- Pool of vectorised declarations
+
+ -- The next two fields are unusual, because they give instance
+ -- environments for *all* modules in the home package, including
+ -- this module, rather than for *just* this module.
+ -- Reason: when looking up an instance we don't want to have to
+ -- look at each module in the home package in turn
+ mg_inst_env :: InstEnv, -- Class instance enviroment fro
+ -- *home-package* modules (including
+ -- this one); c.f. tcg_inst_env
+ mg_fam_inst_env :: FamInstEnv -- Type-family instance enviroment
+ -- for *home-package* modules (including
+ -- this one); c.f. tcg_fam_inst_env
}
-- The ModGuts takes on several slightly different forms:
cg_foreign :: !ForeignStubs,
cg_dep_pkgs :: ![PackageId], -- Used to generate #includes for C code gen
- cg_hpc_info :: !HpcInfo -- info about coverage tick boxes
+ cg_hpc_info :: !HpcInfo, -- info about coverage tick boxes
+ cg_modBreaks :: !ModBreaks
}
-----------------------------------
-- "foreign exported" functions
[FastString] -- Headers that need to be included
-- into C code generated for this module
- [Id] -- Foreign-exported binders
- -- we have to generate code to register these
\end{code}
mi_vect_info = noIfaceVectInfo,
mi_dep_fn = emptyIfaceDepCache,
mi_fix_fn = emptyIfaceFixCache,
- mi_ver_fn = emptyIfaceVerCache
+ mi_ver_fn = emptyIfaceVerCache,
+ mi_hpc = False
}
\end{code}
}
+emptyInteractiveContext :: InteractiveContext
emptyInteractiveContext
= InteractiveContext { ic_toplev_scope = [],
ic_exports = [],
#endif
}
-icPrintUnqual :: InteractiveContext -> PrintUnqualified
-icPrintUnqual ictxt = mkPrintUnqualified (ic_rn_gbl_env ictxt)
+icPrintUnqual :: DynFlags -> InteractiveContext -> PrintUnqualified
+icPrintUnqual dflags ictxt = mkPrintUnqualified dflags (ic_rn_gbl_env ictxt)
extendInteractiveContext
-- NB. must be this way around, because we want
-- new ids to shadow existing bindings.
ic_tyvars = ic_tyvars ictxt `unionVarSet` tyvars }
+
+
+substInteractiveContext :: InteractiveContext -> TvSubst -> InteractiveContext
+substInteractiveContext ictxt subst | isEmptyTvSubst subst = ictxt
+substInteractiveContext ictxt@InteractiveContext{ic_tmp_ids=ids} subst =
+ let ids' = map (\id -> id `setIdType` substTy subst (idType id)) ids
+ subst_dom= varEnvKeys$ getTvSubstEnv subst
+ subst_ran= varEnvElts$ getTvSubstEnv subst
+ new_tvs = [ tv | Just tv <- map getTyVar_maybe subst_ran]
+ ic_tyvars'= (`delVarSetListByKey` subst_dom)
+ . (`extendVarSetList` new_tvs)
+ $ ic_tyvars ictxt
+ in ictxt { ic_tmp_ids = ids'
+ , ic_tyvars = ic_tyvars' }
+
+ where delVarSetListByKey = foldl' delVarSetByKey
\end{code}
%************************************************************************
%* *
%************************************************************************
+Deciding how to print names is pretty tricky. We are given a name
+P:M.T, where P is the package name, M is the defining module, and T is
+the occurrence name, and we have to decide in which form to display
+the name given a GlobalRdrEnv describing the current scope.
+
+Ideally we want to display the name in the form in which it is in
+scope. However, the name might not be in scope at all, and that's
+where it gets tricky. Here are the cases:
+
+ 1. T uniquely maps to P:M.T ---> "T"
+ 2. there is an X for which X.T uniquely maps to P:M.T ---> "X.T"
+ 3. there is no binding for "M.T" ---> "M.T"
+ 4. otherwise ---> "P:M.T"
+
+3 and 4 apply when P:M.T is not in scope. In these cases we want to
+refer to the name as "M.T", but "M.T" might mean something else in the
+current scope (e.g. if there's an "import X as M"), so to avoid
+confusion we avoid using "M.T" if there's already a binding for it.
+
+There's one further subtlety: if the module M cannot be imported
+because it is not exposed by any package, then we must refer to it as
+"P:M". This is handled by the qual_mod component of PrintUnqualified.
+
\begin{code}
-mkPrintUnqualified :: GlobalRdrEnv -> PrintUnqualified
-mkPrintUnqualified env = (qual_name, qual_mod)
+mkPrintUnqualified :: DynFlags -> GlobalRdrEnv -> PrintUnqualified
+mkPrintUnqualified dflags env = (qual_name, qual_mod)
where
- qual_name mod occ
- | null gres = Just (moduleName mod)
- -- it isn't in scope at all, this probably shouldn't happen,
- -- but we'll qualify it by the original module anyway.
- | any unQualOK gres = Nothing
- | (Imported is : _) <- map gre_prov gres, (idecl : _) <- is
- = Just (is_as (is_decl idecl))
- | otherwise = panic "mkPrintUnqualified"
+ qual_name mod occ -- The (mod,occ) pair is the original name of the thing
+ | [gre] <- unqual_gres, right_name gre = NameUnqual
+ -- If there's a unique entity that's in scope unqualified with 'occ'
+ -- AND that entity is the right one, then we can use the unqualified name
+
+ | [gre] <- qual_gres = NameQual (get_qual_mod (gre_prov gre))
+
+ | null qual_gres =
+ if null (lookupGRE_RdrName (mkRdrQual (moduleName mod) occ) env)
+ then NameNotInScope1
+ else NameNotInScope2
+
+ | otherwise = panic "mkPrintUnqualified"
where
- gres = [ gre | gre <- lookupGlobalRdrEnv env occ,
- nameModule (gre_name gre) == mod ]
+ right_name gre = nameModule (gre_name gre) == mod
+
+ unqual_gres = lookupGRE_RdrName (mkRdrUnqual occ) env
+ qual_gres = filter right_name (lookupGlobalRdrEnv env occ)
+
+ get_qual_mod LocalDef = moduleName mod
+ get_qual_mod (Imported is) = ASSERT( not (null is) ) is_as (is_decl (head is))
+
+ -- we can mention a module P:M without the P: qualifier iff
+ -- "import M" would resolve unambiguously to P:M. (if P is the
+ -- current package we can just assume it is unqualified).
- qual_mod mod = Nothing -- For now...
+ qual_mod mod
+ | modulePackageId mod == thisPackage dflags = False
+
+ | [pkgconfig] <- [pkg | (pkg,exposed_module) <- lookup,
+ exposed pkg && exposed_module],
+ packageConfigId pkgconfig == modulePackageId mod
+ -- this says: we are given a module P:M, is there just one exposed package
+ -- that exposes a module M, and is it package P?
+ = False
+
+ | otherwise = True
+ where lookup = lookupModuleInAllPackages dflags (moduleName mod)
\end{code}
implicitTyThings :: TyThing -> [TyThing]
-- If you change this, make sure you change LoadIface.ifaceDeclSubBndrs in sync
-implicitTyThings (AnId id) = []
+implicitTyThings (AnId _) = []
-- For type constructors, add the data cons (and their extras),
-- and the selectors and generic-programming Ids too
isImplicitTyThing (ATyCon tc) = isImplicitTyCon tc
-- For newtypes and indexed data types, add the implicit coercion tycon
+implicitCoTyCon :: TyCon -> [TyThing]
implicitCoTyCon tc
= map ATyCon . catMaybes $ [newTyConCo_maybe tc,
tyConFamilyCoercion_maybe tc]
+extras_plus :: TyThing -> [TyThing]
extras_plus thing = thing : implicitTyThings thing
extendTypeEnvWithIds :: TypeEnv -> [Id] -> TypeEnv
\end{code}
\begin{code}
+tyThingTyCon :: TyThing -> TyCon
tyThingTyCon (ATyCon tc) = tc
-tyThingTyCon other = pprPanic "tyThingTyCon" (ppr other)
+tyThingTyCon other = pprPanic "tyThingTyCon" (pprTyThing other)
+tyThingClass :: TyThing -> Class
tyThingClass (AClass cls) = cls
-tyThingClass other = pprPanic "tyThingClass" (ppr other)
+tyThingClass other = pprPanic "tyThingClass" (pprTyThing other)
+tyThingDataCon :: TyThing -> DataCon
tyThingDataCon (ADataCon dc) = dc
-tyThingDataCon other = pprPanic "tyThingDataCon" (ppr other)
+tyThingDataCon other = pprPanic "tyThingDataCon" (pprTyThing other)
+tyThingId :: TyThing -> Id
tyThingId (AnId id) = id
-tyThingId other = pprPanic "tyThingId" (ppr other)
+tyThingId other = pprPanic "tyThingId" (pprTyThing other)
\end{code}
%************************************************************************
add_imp bndr env = extendOccEnv env bndr (decl_name, v)
emptyIfaceVerCache :: OccName -> Maybe (OccName, Version)
-emptyIfaceVerCache occ = Nothing
+emptyIfaceVerCache _occ = Nothing
------------------ Deprecations -------------------------
data Deprecs a
-- deprecation appears.
mkIfaceDepCache:: IfaceDeprecs -> Name -> Maybe DeprecTxt
-mkIfaceDepCache NoDeprecs = \n -> Nothing
-mkIfaceDepCache (DeprecAll t) = \n -> Just t
+mkIfaceDepCache NoDeprecs = \_ -> Nothing
+mkIfaceDepCache (DeprecAll t) = \_ -> Just t
mkIfaceDepCache (DeprecSome pairs) = lookupOccEnv (mkOccEnv pairs) . nameOccName
emptyIfaceDepCache :: Name -> Maybe DeprecTxt
-emptyIfaceDepCache n = Nothing
+emptyIfaceDepCache _ = Nothing
plusDeprecs :: Deprecations -> Deprecations -> Deprecations
plusDeprecs d NoDeprecs = d
plusDeprecs NoDeprecs d = d
-plusDeprecs d (DeprecAll t) = DeprecAll t
-plusDeprecs (DeprecAll t) d = DeprecAll t
+plusDeprecs _ (DeprecAll t) = DeprecAll t
+plusDeprecs (DeprecAll t) _ = DeprecAll t
plusDeprecs (DeprecSome v1) (DeprecSome v2) = DeprecSome (v1 `plusNameEnv` v2)
\end{code}
availNames :: GenAvailInfo name -> [name]
availNames (Avail n) = [n]
-availNames (AvailTC n ns) = ns
+availNames (AvailTC _ ns) = ns
instance Outputable n => Outputable (GenAvailInfo n) where
ppr = pprAvail
env = mkOccEnv pairs
emptyIfaceFixCache :: OccName -> Fixity
-emptyIfaceFixCache n = defaultFixity
+emptyIfaceFixCache _ = defaultFixity
-- This fixity environment is for source code only
type FixityEnv = NameEnv FixItem
%************************************************************************
\begin{code}
-data HpcInfo = HpcInfo
+data HpcInfo
+ = HpcInfo
{ hpcInfoTickCount :: Int
, hpcInfoHash :: Int
}
- | NoHpcInfo
+ | NoHpcInfo
+ { hpcUsed :: AnyHpcUsage -- is hpc used anywhere on the module tree?
+ }
+
+-- This is used to mean there is no module-local hpc usage,
+-- but one of my imports used hpc instrumentation.
+
+type AnyHpcUsage = Bool
+
+emptyHpcInfo :: AnyHpcUsage -> HpcInfo
+emptyHpcInfo = NoHpcInfo
-noHpcInfo :: HpcInfo
-noHpcInfo = NoHpcInfo
+isHpcUsed :: HpcInfo -> AnyHpcUsage
+isHpcUsed (HpcInfo {}) = True
+isHpcUsed (NoHpcInfo { hpcUsed = used }) = used
\end{code}
%************************************************************************
subsystem. It communicates the vectorisation status of declarations from one
module to another.
-Why do we need both f and f_CC in the ModGuts/ModDetails/EPS version VectInfo
+Why do we need both f and f_v in the ModGuts/ModDetails/EPS version VectInfo
below? We need to know `f' when converting to IfaceVectInfo. However, during
-closure conversion, we need to know `f_CC', whose `Var' we cannot lookup based
+vectorisation, we need to know `f_v', whose `Var' we cannot lookup based
on just the OccName easily in a Core pass.
\begin{code}
-- ModGuts/ModDetails/EPS version
data VectInfo
= VectInfo {
- vectInfoCCVar :: VarEnv (Var, Var) -- (f, f_CC) keyed on f
- -- always tidy, even in ModGuts
+ vectInfoVar :: VarEnv (Var , Var ), -- (f, f_v) keyed on f
+ vectInfoTyCon :: NameEnv (TyCon , TyCon), -- (T, T_v) keyed on T
+ vectInfoDataCon :: NameEnv (DataCon, DataCon), -- (C, C_v) keyed on C
+ vectInfoPADFun :: NameEnv (TyCon , Var), -- (T_v, paT) keyed on T_v
+ vectInfoIso :: NameEnv (TyCon , Var) -- (T, isoT) keyed on T
}
+ -- all of this is always tidy, even in ModGuts
-- ModIface version
data IfaceVectInfo
= IfaceVectInfo {
- ifaceVectInfoCCVar :: [Name] -- all variables in here have
- -- a closure-converted variant
- -- the name of the CC'ed variant
- -- is determined by `mkCloOcc'
+ ifaceVectInfoVar :: [Name],
+ -- all variables in here have a vectorised variant;
+ -- the name of the vectorised variant is determined by `mkCloVect'
+ ifaceVectInfoTyCon :: [Name],
+ -- all tycons in here have a vectorised variant;
+ -- the name of the vectorised variant and those of its
+ -- data constructors are determined by `mkVectTyConOcc'
+ -- and `mkVectDataConOcc'; the names of
+ -- the isomorphisms is determined by `mkVectIsoOcc'
+ ifaceVectInfoTyConReuse :: [Name]
+ -- the vectorised form of all the tycons in here coincids with
+ -- the unconverted from; the names of the isomorphisms is determined
+ -- by `mkVectIsoOcc'
}
noVectInfo :: VectInfo
-noVectInfo = VectInfo emptyVarEnv
+noVectInfo = VectInfo emptyVarEnv emptyNameEnv emptyNameEnv emptyNameEnv emptyNameEnv
plusVectInfo :: VectInfo -> VectInfo -> VectInfo
plusVectInfo vi1 vi2 =
- VectInfo (vectInfoCCVar vi1 `plusVarEnv` vectInfoCCVar vi2)
+ VectInfo (vectInfoVar vi1 `plusVarEnv` vectInfoVar vi2)
+ (vectInfoTyCon vi1 `plusNameEnv` vectInfoTyCon vi2)
+ (vectInfoDataCon vi1 `plusNameEnv` vectInfoDataCon vi2)
+ (vectInfoPADFun vi1 `plusNameEnv` vectInfoPADFun vi2)
+ (vectInfoIso vi1 `plusNameEnv` vectInfoIso vi2)
noIfaceVectInfo :: IfaceVectInfo
-noIfaceVectInfo = IfaceVectInfo []
+noIfaceVectInfo = IfaceVectInfo [] [] []
\end{code}
%************************************************************************
= DotO FilePath
| DotA FilePath
| DotDLL FilePath
- | BCOs CompiledByteCode
+ | BCOs CompiledByteCode ModBreaks
#ifndef GHCI
-data CompiledByteCode = NoByteCode
+data CompiledByteCode
#endif
instance Outputable Unlinked where
ppr (DotA path) = text "DotA" <+> text path
ppr (DotDLL path) = text "DotDLL" <+> text path
#ifdef GHCI
- ppr (BCOs bcos) = text "BCOs" <+> ppr bcos
+ ppr (BCOs bcos _) = text "BCOs" <+> ppr bcos
#else
- ppr (BCOs bcos) = text "No byte code"
+ ppr (BCOs _ _) = text "No byte code"
#endif
+isObject :: Unlinked -> Bool
isObject (DotO _) = True
isObject (DotA _) = True
isObject (DotDLL _) = True
isObject _ = False
+isInterpretable :: Unlinked -> Bool
isInterpretable = not . isObject
+nameOfObject :: Unlinked -> FilePath
nameOfObject (DotO fn) = fn
nameOfObject (DotA fn) = fn
nameOfObject (DotDLL fn) = fn
nameOfObject other = pprPanic "nameOfObject" (ppr other)
-byteCodeOfObject (BCOs bc) = bc
-byteCodeOfObject other = pprPanic "byteCodeOfObject" (ppr other)
+byteCodeOfObject :: Unlinked -> CompiledByteCode
+byteCodeOfObject (BCOs bc _) = bc
+byteCodeOfObject other = pprPanic "byteCodeOfObject" (ppr other)
\end{code}
%************************************************************************