summaryrefslogtreecommitdiff
path: root/compiler/GHC
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2020-08-05 11:32:17 +0200
committerSylvain Henry <sylvain@haskus.fr>2020-08-13 09:49:56 -0400
commitffc0d578ea22de02a68c64c094602701e65d8895 (patch)
tree168171a5fb54632f5f4fdd1130a31ed730248e73 /compiler/GHC
parentcf97889a38edc3314a7b61e6e0b6e6d0f434c8a2 (diff)
downloadhaskell-ffc0d578ea22de02a68c64c094602701e65d8895.tar.gz
Add HomeUnit type
Since Backpack the "home unit" is much more involved than what it was before (just an identifier obtained with `-this-unit-id`). Now it is used in conjunction with `-component-id` and `-instantiated-with` to configure module instantiations and to detect if we are type-checking an indefinite unit or compiling a definite one. This patch introduces a new HomeUnit datatype which is much easier to understand. Moreover to make GHC support several packages in the same instances, we will need to handle several HomeUnits so having a dedicated (documented) type is helpful. Finally in #14335 we will also need to handle the case where we have no HomeUnit at all because we are only loading existing interfaces for plugins which live in a different space compared to units used to produce target code. Several functions will have to be refactored to accept "Maybe HomeUnit" parameters instead of implicitly querying the HomeUnit fields in DynFlags. Having a dedicated type will make this easier. Bump haddock submodule
Diffstat (limited to 'compiler/GHC')
-rw-r--r--compiler/GHC/Core/Opt/Pipeline.hs7
-rw-r--r--compiler/GHC/CoreToStg/Prep.hs7
-rw-r--r--compiler/GHC/Driver/Backpack.hs17
-rw-r--r--compiler/GHC/Driver/Finder.hs51
-rw-r--r--compiler/GHC/Driver/Main.hs25
-rw-r--r--compiler/GHC/Driver/Make.hs17
-rw-r--r--compiler/GHC/Driver/Pipeline.hs58
-rw-r--r--compiler/GHC/Driver/Session.hs68
-rw-r--r--compiler/GHC/Driver/Types.hs34
-rw-r--r--compiler/GHC/HsToCore.hs14
-rw-r--r--compiler/GHC/HsToCore/Monad.hs5
-rw-r--r--compiler/GHC/HsToCore/Usage.hs10
-rw-r--r--compiler/GHC/Iface/Load.hs49
-rw-r--r--compiler/GHC/Iface/Make.hs12
-rw-r--r--compiler/GHC/Iface/Recomp.hs26
-rw-r--r--compiler/GHC/Iface/Recomp/Flags.hs2
-rw-r--r--compiler/GHC/Iface/Rename.hs3
-rw-r--r--compiler/GHC/Iface/Tidy.hs5
-rw-r--r--compiler/GHC/Parser/Lexer.x6
-rw-r--r--compiler/GHC/Rename/Module.hs6
-rw-r--r--compiler/GHC/Rename/Names.hs6
-rw-r--r--compiler/GHC/Runtime/Eval.hs4
-rw-r--r--compiler/GHC/Runtime/Linker.hs7
-rw-r--r--compiler/GHC/SysTools.hs21
-rw-r--r--compiler/GHC/SysTools/ExtraObj.hs5
-rw-r--r--compiler/GHC/Tc/Module.hs13
-rw-r--r--compiler/GHC/Tc/TyCl.hs9
-rw-r--r--compiler/GHC/Tc/Utils/Backpack.hs22
-rw-r--r--compiler/GHC/Tc/Utils/Env.hs4
-rw-r--r--compiler/GHC/Tc/Utils/Monad.hs12
-rw-r--r--compiler/GHC/Types/Name.hs7
-rw-r--r--compiler/GHC/Unit.hs2
-rw-r--r--compiler/GHC/Unit/Home.hs213
-rw-r--r--compiler/GHC/Unit/Info.hs14
-rw-r--r--compiler/GHC/Unit/Module.hs5
-rw-r--r--compiler/GHC/Unit/State.hs149
-rw-r--r--compiler/GHC/Unit/State.hs-boot1
-rw-r--r--compiler/GHC/Unit/Types.hs106
38 files changed, 649 insertions, 373 deletions
diff --git a/compiler/GHC/Core/Opt/Pipeline.hs b/compiler/GHC/Core/Opt/Pipeline.hs
index a9dc3ec4a5..1a308d11af 100644
--- a/compiler/GHC/Core/Opt/Pipeline.hs
+++ b/compiler/GHC/Core/Opt/Pipeline.hs
@@ -101,7 +101,10 @@ core2core hsc_env guts@(ModGuts { mg_module = mod
dflags = hsc_dflags hsc_env
home_pkg_rules = hptRules hsc_env (dep_mods deps)
hpt_rule_base = mkRuleBase home_pkg_rules
- print_unqual = mkPrintUnqualified dflags rdr_env
+ print_unqual = mkPrintUnqualified
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ rdr_env
-- mod: get the module out of the current HscEnv so we can retrieve it from the monad.
-- This is very convienent for the users of the monad (e.g. plugins do not have to
-- consume the ModGuts to find the module) but somewhat ugly because mg_module may
@@ -663,7 +666,7 @@ simplifyPgmIO pass@(CoreDoSimplify max_iterations mode)
}
where
dflags = hsc_dflags hsc_env
- print_unqual = mkPrintUnqualified dflags rdr_env
+ print_unqual = mkPrintUnqualified (unitState dflags) (mkHomeUnitFromFlags dflags) rdr_env
simpl_env = mkSimplEnv mode
active_rule = activeRule mode
active_unf = activeUnfolding mode
diff --git a/compiler/GHC/CoreToStg/Prep.hs b/compiler/GHC/CoreToStg/Prep.hs
index 831517f21c..4ecb29da7a 100644
--- a/compiler/GHC/CoreToStg/Prep.hs
+++ b/compiler/GHC/CoreToStg/Prep.hs
@@ -48,7 +48,7 @@ import GHC.Types.Id.Info
import GHC.Builtin.Types
import GHC.Core.DataCon
import GHC.Types.Basic
-import GHC.Unit.Module
+import GHC.Unit
import GHC.Types.Unique.Supply
import GHC.Data.Maybe
import GHC.Data.OrdList
@@ -1496,10 +1496,11 @@ mkConvertNumLiteral hsc_env = do
let
dflags = hsc_dflags hsc_env
platform = targetPlatform dflags
+ home_unit = mkHomeUnitFromFlags dflags
guardBignum act
- | homeUnitId dflags == primUnitId
+ | isHomeUnitInstanceOf home_unit primUnitId
= return $ panic "Bignum literals are not supported in ghc-prim"
- | homeUnitId dflags == bignumUnitId
+ | isHomeUnitInstanceOf home_unit bignumUnitId
= return $ panic "Bignum literals are not supported in ghc-bignum"
| otherwise = act
diff --git a/compiler/GHC/Driver/Backpack.hs b/compiler/GHC/Driver/Backpack.hs
index c103955ab8..2523fb55d5 100644
--- a/compiler/GHC/Driver/Backpack.hs
+++ b/compiler/GHC/Driver/Backpack.hs
@@ -137,7 +137,7 @@ withBkpSession :: IndefUnitId
-> BkpM a
withBkpSession cid insts deps session_type do_this = do
dflags <- getDynFlags
- let cid_fs = unitIdFS (indefUnit cid)
+ let cid_fs = unitFS (indefUnit cid)
is_primary = False
uid_str = unpackFS (mkInstantiatedUnitHash cid insts)
cid_str = unpackFS cid_fs
@@ -172,12 +172,12 @@ withBkpSession cid insts deps session_type do_this = do
backend = case session_type of
TcSession -> NoBackend
_ -> backend dflags,
- homeUnitInstantiations = insts,
+ homeUnitInstantiations_ = insts,
-- if we don't have any instantiation, don't
-- fill `homeUnitInstanceOfId` as it makes no
-- sense (we're not instantiating anything)
- homeUnitInstanceOfId = if null insts then Nothing else Just cid,
- homeUnitId =
+ homeUnitInstanceOf_ = if null insts then Nothing else Just (indefUnit cid),
+ homeUnitId_ =
case session_type of
TcSession -> newUnitId cid Nothing
-- No hash passed if no instances
@@ -286,7 +286,6 @@ buildUnit session cid insts lunit = do
dflags <- getDynFlags
mod_graph <- hsunitModuleGraph dflags (unLoc lunit)
- -- pprTrace "mod_graph" (ppr mod_graph) $ return ()
msg <- mkBackpackMsg
ok <- load' LoadAllTargets (Just msg) mod_graph
@@ -310,6 +309,7 @@ buildUnit session cid insts lunit = do
let compat_fs = unitIdFS (indefUnit cid)
compat_pn = PackageName compat_fs
+ unit_id = homeUnitId (mkHomeUnitFromFlags (hsc_dflags hsc_env))
return GenericUnitInfo {
-- Stub data
@@ -317,7 +317,7 @@ buildUnit session cid insts lunit = do
unitPackageId = PackageId compat_fs,
unitPackageName = compat_pn,
unitPackageVersion = makeVersion [],
- unitId = toUnitId (homeUnit dflags),
+ unitId = unit_id,
unitComponentName = Nothing,
unitInstanceOf = cid,
unitInstantiations = insts,
@@ -562,7 +562,7 @@ type PackageNameMap a = Map PackageName a
-- to use this for anything
unitDefines :: UnitState -> LHsUnit PackageName -> (PackageName, HsComponentId)
unitDefines pkgstate (L _ HsUnit{ hsunitName = L _ pn@(PackageName fs) })
- = (pn, HsComponentId pn (updateIndefUnitId pkgstate (Indefinite (UnitId fs) Nothing)))
+ = (pn, HsComponentId pn (mkIndefUnitId pkgstate (UnitId fs)))
bkpPackageNameMap :: UnitState -> [LHsUnit PackageName] -> PackageNameMap HsComponentId
bkpPackageNameMap pkgstate units = Map.fromList (map (unitDefines pkgstate) units)
@@ -642,6 +642,7 @@ hsunitModuleGraph :: DynFlags -> HsUnit HsComponentId -> BkpM ModuleGraph
hsunitModuleGraph dflags unit = do
let decls = hsunitBody unit
pn = hsPackageName (unLoc (hsunitName unit))
+ home_unit = mkHomeUnitFromFlags dflags
-- 1. Create a HsSrcFile/HsigFile summary for every
-- explicitly mentioned module/signature.
@@ -655,7 +656,7 @@ hsunitModuleGraph dflags unit = do
-- requirement.
let node_map = Map.fromList [ ((ms_mod_name n, ms_hsc_src n == HsigFile), n)
| n <- nodes ]
- req_nodes <- fmap catMaybes . forM (homeUnitInstantiations dflags) $ \(mod_name, _) ->
+ req_nodes <- fmap catMaybes . forM (homeUnitInstantiations home_unit) $ \(mod_name, _) ->
let has_local = Map.member (mod_name, True) node_map
in if has_local
then return Nothing
diff --git a/compiler/GHC/Driver/Finder.hs b/compiler/GHC/Driver/Finder.hs
index 22408ca149..0b9ad24371 100644
--- a/compiler/GHC/Driver/Finder.hs
+++ b/compiler/GHC/Driver/Finder.hs
@@ -76,10 +76,9 @@ flushFinderCaches :: HscEnv -> IO ()
flushFinderCaches hsc_env =
atomicModifyIORef' fc_ref $ \fm -> (filterInstalledModuleEnv is_ext fm, ())
where
- this_pkg = homeUnit (hsc_dflags hsc_env)
- fc_ref = hsc_FC hsc_env
- is_ext mod _ | not (moduleUnit mod `unitIdEq` this_pkg) = True
- | otherwise = False
+ fc_ref = hsc_FC hsc_env
+ home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
+ is_ext mod _ = not (isHomeInstalledModule home_unit mod)
addToFinderCache :: IORef FinderCache -> InstalledModule -> InstalledFindResult -> IO ()
addToFinderCache ref key val =
@@ -136,8 +135,8 @@ findPluginModule hsc_env mod_name =
findExactModule :: HscEnv -> InstalledModule -> IO InstalledFindResult
findExactModule hsc_env mod =
- let dflags = hsc_dflags hsc_env
- in if moduleUnit mod `unitIdEq` homeUnit dflags
+ let home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
+ in if isHomeInstalledModule home_unit mod
then findInstalledHomeModule hsc_env (moduleName mod)
else findPackageModule hsc_env mod
@@ -176,7 +175,8 @@ orIfNotFound this or_this = do
-- was successful.)
homeSearchCache :: HscEnv -> ModuleName -> IO InstalledFindResult -> IO InstalledFindResult
homeSearchCache hsc_env mod_name do_this = do
- let mod = mkHomeInstalledModule (hsc_dflags hsc_env) mod_name
+ let home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
+ mod = mkHomeInstalledModule home_unit mod_name
modLocationCache hsc_env mod do_this
findExposedPackageModule :: HscEnv -> ModuleName -> Maybe FastString
@@ -248,21 +248,18 @@ modLocationCache hsc_env mod do_this = do
addToFinderCache (hsc_FC hsc_env) mod result
return result
-mkHomeInstalledModule :: DynFlags -> ModuleName -> InstalledModule
-mkHomeInstalledModule dflags mod_name =
- let iuid = homeUnitId dflags
- in Module iuid mod_name
-
-- This returns a module because it's more convenient for users
addHomeModuleToFinder :: HscEnv -> ModuleName -> ModLocation -> IO Module
addHomeModuleToFinder hsc_env mod_name loc = do
- let mod = mkHomeInstalledModule (hsc_dflags hsc_env) mod_name
+ let home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
+ mod = mkHomeInstalledModule home_unit mod_name
addToFinderCache (hsc_FC hsc_env) mod (InstalledFound loc mod)
- return (mkHomeModule (hsc_dflags hsc_env) mod_name)
+ return (mkHomeModule home_unit mod_name)
uncacheModule :: HscEnv -> ModuleName -> IO ()
uncacheModule hsc_env mod_name = do
- let mod = mkHomeInstalledModule (hsc_dflags hsc_env) mod_name
+ let home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
+ mod = mkHomeInstalledModule home_unit mod_name
removeFromFinderCache (hsc_FC hsc_env) mod
-- -----------------------------------------------------------------------------
@@ -272,7 +269,7 @@ findHomeModule :: HscEnv -> ModuleName -> IO FindResult
findHomeModule hsc_env mod_name = do
r <- findInstalledHomeModule hsc_env mod_name
return $ case r of
- InstalledFound loc _ -> Found loc (mkModule uid mod_name)
+ InstalledFound loc _ -> Found loc (mkHomeModule home_unit mod_name)
InstalledNoPackage _ -> NoPackage uid -- impossible
InstalledNotFound fps _ -> NotFound {
fr_paths = fps,
@@ -283,8 +280,9 @@ findHomeModule hsc_env mod_name = do
fr_suggestions = []
}
where
- dflags = hsc_dflags hsc_env
- uid = homeUnit dflags
+ dflags = hsc_dflags hsc_env
+ home_unit = mkHomeUnitFromFlags dflags
+ uid = homeUnitAsUnit (mkHomeUnitFromFlags dflags)
-- | Implements the search for a module name in the home package only. Calling
-- this function directly is usually *not* what you want; currently, it's used
@@ -307,9 +305,10 @@ findInstalledHomeModule hsc_env mod_name =
homeSearchCache hsc_env mod_name $
let
dflags = hsc_dflags hsc_env
+ home_unit = mkHomeUnitFromFlags dflags
home_path = importPaths dflags
hisuf = hiSuf dflags
- mod = mkHomeInstalledModule dflags mod_name
+ mod = mkHomeInstalledModule home_unit mod_name
source_exts =
[ ("hs", mkHomeModLocationSearched dflags mod_name "hs")
@@ -675,6 +674,7 @@ cantFindErr cannot_find _ dflags mod_name find_result
$$ more_info
where
pkgs = unitState dflags
+ home_unit = mkHomeUnitFromFlags dflags
more_info
= case find_result of
NoPackage pkg
@@ -684,7 +684,7 @@ cantFindErr cannot_find _ dflags mod_name find_result
NotFound { fr_paths = files, fr_pkg = mb_pkg
, fr_mods_hidden = mod_hiddens, fr_pkgs_hidden = pkg_hiddens
, fr_unusables = unusables, fr_suggestions = suggest }
- | Just pkg <- mb_pkg, pkg /= homeUnit dflags
+ | Just pkg <- mb_pkg, not (isHomeUnit home_unit pkg)
-> not_found_in_package pkg files
| not (null suggest)
@@ -793,6 +793,10 @@ cantFindInstalledErr cannot_find _ dflags mod_name find_result
= ptext cannot_find <+> quotes (ppr mod_name)
$$ more_info
where
+ home_unit = mkHomeUnitFromFlags dflags
+ unit_state = unitState dflags
+ build_tag = waysBuildTag (ways dflags)
+
more_info
= case find_result of
InstalledNoPackage pkg
@@ -800,7 +804,7 @@ cantFindInstalledErr cannot_find _ dflags mod_name find_result
text "was found" $$ looks_like_srcpkgid pkg
InstalledNotFound files mb_pkg
- | Just pkg <- mb_pkg, not (pkg `unitIdEq` homeUnit dflags)
+ | Just pkg <- mb_pkg, not (isHomeUnitId home_unit pkg)
-> not_found_in_package pkg files
| null files
@@ -811,14 +815,11 @@ cantFindInstalledErr cannot_find _ dflags mod_name find_result
_ -> panic "cantFindInstalledErr"
- build_tag = waysBuildTag (ways dflags)
- pkgstate = unitState dflags
-
looks_like_srcpkgid :: UnitId -> SDoc
looks_like_srcpkgid pk
-- Unsafely coerce a unit id (i.e. an installed package component
-- identifier) into a PackageId and see if it means anything.
- | (pkg:pkgs) <- searchPackageId pkgstate (PackageId (unitIdFS pk))
+ | (pkg:pkgs) <- searchPackageId unit_state (PackageId (unitIdFS pk))
= parens (text "This unit ID looks like the source package ID;" $$
text "the real unit ID is" <+> quotes (ftext (unitIdFS (unitId pkg))) $$
(if null pkgs then Outputable.empty
diff --git a/compiler/GHC/Driver/Main.hs b/compiler/GHC/Driver/Main.hs
index 42e9a35724..ab27efc832 100644
--- a/compiler/GHC/Driver/Main.hs
+++ b/compiler/GHC/Driver/Main.hs
@@ -101,8 +101,7 @@ import GHC.Utils.Panic
import GHC.Core.ConLike
import GHC.Parser.Annotation
-import GHC.Unit.Module
-import GHC.Unit.State
+import GHC.Unit
import GHC.Types.Name.Reader
import GHC.Hs
import GHC.Hs.Dump
@@ -194,7 +193,8 @@ import GHC.Iface.Ext.Debug ( diffFile, validateScopes )
newHscEnv :: DynFlags -> IO HscEnv
newHscEnv dflags = do
- eps_var <- newIORef (initExternalPackageState dflags)
+ let home_unit = mkHomeUnitFromFlags dflags
+ eps_var <- newIORef (initExternalPackageState home_unit)
us <- mkSplitUniqSupply 'r'
nc_var <- newIORef (initNameCache us knownKeyNames)
fc_var <- newIORef emptyInstalledModuleEnv
@@ -469,14 +469,15 @@ hsc_typecheck keep_rn mod_summary mb_rdr_module = do
hsc_env <- getHscEnv
let hsc_src = ms_hsc_src mod_summary
dflags = hsc_dflags hsc_env
+ home_unit = mkHomeUnitFromFlags dflags
outer_mod = ms_mod mod_summary
mod_name = moduleName outer_mod
- outer_mod' = mkHomeModule dflags mod_name
- inner_mod = canonicalizeHomeModule dflags mod_name
+ outer_mod' = mkHomeModule home_unit mod_name
+ inner_mod = homeModuleNameInstantiation home_unit mod_name
src_filename = ms_hspp_file mod_summary
real_loc = realSrcLocSpan $ mkRealSrcLoc (mkFastString src_filename) 1 1
keep_rn' = gopt Opt_WriteHie dflags || keep_rn
- MASSERT( isHomeModule dflags outer_mod )
+ MASSERT( isHomeModule home_unit outer_mod )
tc_result <- if hsc_src == HsigFile && not (isHoleModule inner_mod)
then ioMsgMaybe $ tcRnInstantiateSignature hsc_env outer_mod' real_loc
else
@@ -1115,10 +1116,11 @@ hscCheckSafe' :: Module -> SrcSpan
-> Hsc (Maybe UnitId, Set UnitId)
hscCheckSafe' m l = do
dflags <- getDynFlags
+ let home_unit = mkHomeUnitFromFlags dflags
(tw, pkgs) <- isModSafe m l
case tw of
- False -> return (Nothing, pkgs)
- True | isHomeModule dflags m -> return (Nothing, pkgs)
+ False -> return (Nothing, pkgs)
+ True | isHomeModule home_unit m -> return (Nothing, pkgs)
-- TODO: do we also have to check the trust of the instantiation?
-- Not necessary if that is reflected in dependencies
| otherwise -> return (Just $ toUnitId (moduleUnit m), pkgs)
@@ -1193,7 +1195,7 @@ hscCheckSafe' m l = do
packageTrusted _ Sf_Safe False _ = True
packageTrusted _ Sf_SafeInferred False _ = True
packageTrusted dflags _ _ m
- | isHomeModule dflags m = True
+ | isHomeModule (mkHomeUnitFromFlags dflags) m = True
| otherwise = unitIsTrusted $ unsafeLookupUnit (unitState dflags) (moduleUnit m)
lookup' :: Module -> Hsc (Maybe ModIface)
@@ -1486,14 +1488,15 @@ hscInteractive hsc_env cgguts location = do
hscCompileCmmFile :: HscEnv -> FilePath -> FilePath -> IO ()
hscCompileCmmFile hsc_env filename output_filename = runHsc hsc_env $ do
- let dflags = hsc_dflags hsc_env
+ let dflags = hsc_dflags hsc_env
+ home_unit = mkHomeUnitFromFlags dflags
cmm <- ioMsgMaybe $ parseCmmFile dflags filename
liftIO $ do
dumpIfSet_dyn dflags Opt_D_dump_cmm_verbose_by_proc "Parsed Cmm" FormatCMM (ppr cmm)
let -- Make up a module name to give the NCG. We can't pass bottom here
-- lest we reproduce #11784.
mod_name = mkModuleName $ "Cmm$" ++ FilePath.takeFileName filename
- cmm_mod = mkHomeModule dflags mod_name
+ cmm_mod = mkHomeModule home_unit mod_name
-- Compile decls in Cmm files one decl at a time, to avoid re-ordering
-- them in SRT analysis.
diff --git a/compiler/GHC/Driver/Make.hs b/compiler/GHC/Driver/Make.hs
index 74c3f9efa8..9e7870c638 100644
--- a/compiler/GHC/Driver/Make.hs
+++ b/compiler/GHC/Driver/Make.hs
@@ -46,7 +46,7 @@ import GHC.Driver.Finder
import GHC.Driver.Monad
import GHC.Parser.Header
import GHC.Driver.Types
-import GHC.Unit.Module
+import GHC.Unit
import GHC.IfaceToCore ( typecheckIface )
import GHC.Tc.Utils.Monad ( initIfaceCheck )
import GHC.Driver.Main
@@ -66,7 +66,6 @@ import GHC.Data.StringBuffer
import GHC.Types.Unique.FM
import GHC.Types.Unique.DSet
import GHC.Tc.Utils.Backpack
-import GHC.Unit.State
import GHC.Types.Unique.Set
import GHC.Utils.Misc
import qualified GHC.LanguageExtensions as LangExt
@@ -655,10 +654,10 @@ discardIC hsc_env
old_ic = hsc_IC hsc_env
empty_ic = emptyInteractiveContext dflags
keep_external_name ic_name
- | nameIsFromExternalPackage this_pkg old_name = old_name
+ | nameIsFromExternalPackage home_unit old_name = old_name
| otherwise = ic_name empty_ic
where
- this_pkg = homeUnit dflags
+ home_unit = mkHomeUnitFromFlags dflags
old_name = ic_name old_ic
-- | If there is no -o option, guess the name of target executable
@@ -1202,13 +1201,14 @@ parUpsweep_one mod home_mod_map comp_graph_loops lcl_dflags mHscMessage cleanup
let home_imps = map unLoc $ ms_home_imps mod
let home_src_imps = map unLoc $ ms_home_srcimps mod
+ let home_unit = mkHomeUnitFromFlags lcl_dflags
-- All the textual imports of this module.
let textual_deps = Set.fromList $
zipWith f home_imps (repeat NotBoot) ++
zipWith f home_src_imps (repeat IsBoot)
where f mn isBoot = GWIB
- { gwib_mod = mkHomeModule lcl_dflags mn
+ { gwib_mod = mkHomeModule home_unit mn
, gwib_isBoot = isBoot
}
@@ -2210,7 +2210,7 @@ enableCodeGenForTH =
backend dflags == NoBackend &&
-- Don't enable codegen for TH on indefinite packages; we
-- can't compile anything anyway! See #16219.
- homeUnitIsDefinite dflags
+ isHomeUnitDefinite (mkHomeUnitFromFlags dflags)
-- | Update the every ModSummary that is depended on
-- by a module that needs unboxed tuples. We enable codegen to
@@ -2499,6 +2499,7 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod)
| otherwise = find_it
where
dflags = hsc_dflags hsc_env
+ home_unit = mkHomeUnitFromFlags dflags
check_timestamp old_summary location src_fn =
checkSummaryTimestamp
@@ -2557,12 +2558,12 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod)
$$ text "Saw:" <+> quotes (ppr pi_mod_name)
$$ text "Expected:" <+> quotes (ppr wanted_mod)
- when (hsc_src == HsigFile && isNothing (lookup pi_mod_name (homeUnitInstantiations dflags))) $
+ when (hsc_src == HsigFile && isNothing (lookup pi_mod_name (homeUnitInstantiations home_unit))) $
let suggested_instantiated_with =
hcat (punctuate comma $
[ ppr k <> text "=" <> ppr v
| (k,v) <- ((pi_mod_name, mkHoleModule pi_mod_name)
- : homeUnitInstantiations dflags)
+ : homeUnitInstantiations home_unit)
])
in throwE $ unitBag $ mkPlainErrMsg pi_local_dflags pi_mod_name_loc $
text "Unexpected signature:" <+> quotes (ppr pi_mod_name)
diff --git a/compiler/GHC/Driver/Pipeline.hs b/compiler/GHC/Driver/Pipeline.hs
index f87fd1380d..ca82e216d9 100644
--- a/compiler/GHC/Driver/Pipeline.hs
+++ b/compiler/GHC/Driver/Pipeline.hs
@@ -40,7 +40,7 @@ module GHC.Driver.Pipeline (
import GHC.Prelude
import GHC.Driver.Pipeline.Monad
-import GHC.Unit.State
+import GHC.Unit
import GHC.Platform.Ways
import GHC.Platform.ArchOS
import GHC.Parser.Header
@@ -51,7 +51,6 @@ import GHC.Driver.Main
import GHC.Driver.Finder
import GHC.Driver.Types hiding ( Hsc )
import GHC.Utils.Outputable
-import GHC.Unit.Module
import GHC.Utils.Error
import GHC.Driver.Session
import GHC.Driver.Backend
@@ -382,7 +381,8 @@ compileEmptyStub dflags hsc_env basename location mod_name = do
-- https://gitlab.haskell.org/ghc/ghc/issues/12673
-- and https://github.com/haskell/cabal/issues/2257
empty_stub <- newTempName dflags TFL_CurrentModule "c"
- let src = text "int" <+> ppr (mkHomeModule dflags mod_name) <+> text "= 0;"
+ let home_unit = mkHomeUnitFromFlags dflags
+ src = text "int" <+> ppr (mkHomeModule home_unit mod_name) <+> text "= 0;"
writeFile empty_stub (showSDoc dflags (pprCode CStyle src))
_ <- runPipeline StopLn hsc_env
(empty_stub, Nothing, Nothing)
@@ -516,9 +516,9 @@ linkingNeeded dflags staticLink linkables pkg_deps = do
-- next, check libraries. XXX this only checks Haskell libraries,
-- not extra_libraries or -l things from the command line.
- let pkgstate = unitState dflags
- let pkg_hslibs = [ (collectLibraryPaths dflags [c], lib)
- | Just c <- map (lookupUnitId pkgstate) pkg_deps,
+ let unit_state = unitState dflags
+ let pkg_hslibs = [ (collectLibraryPaths (ways dflags) [c], lib)
+ | Just c <- map (lookupUnitId unit_state) pkg_deps,
lib <- packageHsLibs dflags c ]
pkg_libfiles <- mapM (uncurry (findHSLib dflags)) pkg_hslibs
@@ -1227,6 +1227,7 @@ runPhase (RealPhase cc_phase) input_fn dflags
= do
let platform = targetPlatform dflags
hcc = cc_phase `eqPhase` HCc
+ home_unit = mkHomeUnitFromFlags dflags
let cmdline_include_paths = includePaths dflags
@@ -1236,7 +1237,11 @@ runPhase (RealPhase cc_phase) input_fn dflags
-- add package include paths even if we're just compiling .c
-- files; this is the Value Add(TM) that using ghc instead of
-- gcc gives you :)
- pkg_include_dirs <- liftIO $ getUnitIncludePath dflags pkgs
+ pkg_include_dirs <- liftIO $ getUnitIncludePath
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ pkgs
let include_paths_global = foldr (\ x xs -> ("-I" ++ x) : xs) []
(includePathsGlobal cmdline_include_paths ++ pkg_include_dirs)
let include_paths_quote = foldr (\ x xs -> ("-iquote" ++ x) : xs) []
@@ -1264,11 +1269,19 @@ runPhase (RealPhase cc_phase) input_fn dflags
pkg_extra_cc_opts <- liftIO $
if hcc
then return []
- else getUnitExtraCcOpts dflags pkgs
+ else getUnitExtraCcOpts
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ pkgs
framework_paths <-
if platformUsesFrameworks platform
- then do pkgFrameworkPaths <- liftIO $ getUnitFrameworkPath dflags pkgs
+ then do pkgFrameworkPaths <- liftIO $ getUnitFrameworkPath
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ pkgs
let cmdlineFrameworkPaths = frameworkPaths dflags
return $ map ("-F"++)
(cmdlineFrameworkPaths ++ pkgFrameworkPaths)
@@ -1315,7 +1328,7 @@ runPhase (RealPhase cc_phase) input_fn dflags
-- way we do the import depends on whether we're currently compiling
-- the base package or not.
++ (if platformOS platform == OSMinGW32 &&
- homeUnitId dflags == baseUnitId
+ isHomeUnitId home_unit baseUnitId
then [ "-DCOMPILING_BASE_PACKAGE" ]
else [])
@@ -1671,7 +1684,12 @@ linkBinary' staticLink dflags o_files dep_units = do
then return output_fn
else do d <- getCurrentDirectory
return $ normalise (d </> output_fn)
- pkg_lib_paths <- getUnitLibraryPath dflags dep_units
+ pkg_lib_paths <- getUnitLibraryPath
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ (ways dflags)
+ dep_units
let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths
get_pkg_lib_path_opts l
| osElfTarget (platformOS platform) &&
@@ -1940,7 +1958,11 @@ linkStaticLib dflags o_files dep_units = do
output_exists <- doesFileExist full_output_fn
(when output_exists) $ removeFile full_output_fn
- pkg_cfgs_init <- getPreloadUnitsAnd dflags dep_units
+ pkg_cfgs_init <- getPreloadUnitsAnd
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ dep_units
let pkg_cfgs
| gopt Opt_LinkRts dflags
@@ -1969,7 +1991,11 @@ doCpp dflags raw input_fn output_fn = do
let hscpp_opts = picPOpts dflags
let cmdline_include_paths = includePaths dflags
- pkg_include_dirs <- getUnitIncludePath dflags []
+ pkg_include_dirs <- getUnitIncludePath
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ []
let include_paths_global = foldr (\ x xs -> ("-I" ++ x) : xs) []
(includePathsGlobal cmdline_include_paths ++ pkg_include_dirs)
let include_paths_quote = foldr (\ x xs -> ("-iquote" ++ x) : xs) []
@@ -2235,7 +2261,11 @@ getGhcVersionPathName dflags = do
candidates <- case ghcVersionFile dflags of
Just path -> return [path]
Nothing -> (map (</> "ghcversion.h")) <$>
- (getUnitIncludePath dflags [rtsUnitId])
+ (getUnitIncludePath
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ [rtsUnitId])
found <- filterM doesFileExist candidates
case found of
diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs
index 5ec163c54a..45f6d4328d 100644
--- a/compiler/GHC/Driver/Session.hs
+++ b/compiler/GHC/Driver/Session.hs
@@ -65,7 +65,7 @@ module GHC.Driver.Session (
addWay', targetProfile,
- homeUnit, mkHomeModule, isHomeModule,
+ mkHomeUnitFromFlags,
-- ** Log output
putLogMsg,
@@ -168,8 +168,6 @@ module GHC.Driver.Session (
updOptLevel,
setTmpDir,
setUnitId,
- canonicalizeHomeModule,
- canonicalizeModuleIfHome,
TurnOnFlag,
turnOn,
@@ -241,6 +239,7 @@ import GHC.Platform
import GHC.Platform.Ways
import GHC.Platform.Profile
import GHC.UniqueSubdir (uniqueSubdir)
+import GHC.Unit.Home
import GHC.Unit.Types
import GHC.Unit.Parser
import GHC.Unit.Module
@@ -248,7 +247,7 @@ import GHC.Driver.Ppr
import {-# SOURCE #-} GHC.Driver.Plugins
import {-# SOURCE #-} GHC.Driver.Hooks
import GHC.Builtin.Names ( mAIN )
-import {-# SOURCE #-} GHC.Unit.State (UnitState, emptyUnitState, UnitDatabase, updateIndefUnitId)
+import {-# SOURCE #-} GHC.Unit.State (UnitState, emptyUnitState, UnitDatabase)
import GHC.Driver.Phases ( Phase(..), phaseInputExt )
import GHC.Driver.Flags
import GHC.Driver.Backend
@@ -530,9 +529,9 @@ data DynFlags = DynFlags {
solverIterations :: IntWithInf, -- ^ Number of iterations in the constraints solver
-- Typically only 1 is needed
- homeUnitId :: UnitId, -- ^ Target home unit-id
- homeUnitInstanceOfId :: Maybe IndefUnitId, -- ^ Unit-id to instantiate
- homeUnitInstantiations:: [(ModuleName, Module)], -- ^ How to instantiate `homeUnitInstanceOfId` unit
+ homeUnitId_ :: UnitId, -- ^ Target home unit-id
+ homeUnitInstanceOf_ :: Maybe UnitId, -- ^ Id of the unit to instantiate
+ homeUnitInstantiations_ :: [(ModuleName, Module)], -- ^ Module instantiations
-- ways
ways :: Ways, -- ^ Way flags from the command line
@@ -1273,9 +1272,9 @@ defaultDynFlags mySettings llvmConfig =
reductionDepth = treatZeroAsInf mAX_REDUCTION_DEPTH,
solverIterations = treatZeroAsInf mAX_SOLVER_ITERATIONS,
- homeUnitId = mainUnitId,
- homeUnitInstanceOfId = Nothing,
- homeUnitInstantiations = [],
+ homeUnitId_ = mainUnitId,
+ homeUnitInstanceOf_ = Nothing,
+ homeUnitInstantiations_ = [],
objectDir = Nothing,
dylibInstallName = Nothing,
@@ -1908,31 +1907,27 @@ setOutputHi f d = d { outputHi = f}
setJsonLogAction :: DynFlags -> DynFlags
setJsonLogAction d = d { log_action = jsonLogAction }
--- | Make a module in home unit
-mkHomeModule :: DynFlags -> ModuleName -> Module
-mkHomeModule dflags = mkModule (homeUnit dflags)
-
--- | Test if the module comes from the home unit
-isHomeModule :: DynFlags -> Module -> Bool
-isHomeModule dflags m = moduleUnit m == homeUnit dflags
-
-- | Get home unit
-homeUnit :: DynFlags -> Unit
-homeUnit dflags =
- case (homeUnitInstanceOfId dflags, homeUnitInstantiations dflags) of
- (Nothing,[]) -> RealUnit (Definite (homeUnitId dflags))
+mkHomeUnitFromFlags :: DynFlags -> HomeUnit
+mkHomeUnitFromFlags dflags =
+ let !hu_id = homeUnitId_ dflags
+ !hu_instanceof = homeUnitInstanceOf_ dflags
+ !hu_instantiations = homeUnitInstantiations_ dflags
+ in case (hu_instanceof, hu_instantiations) of
+ (Nothing,[]) -> DefiniteHomeUnit hu_id Nothing
(Nothing, _) -> throwGhcException $ CmdLineError ("Use of -instantiated-with requires -this-component-id")
(Just _, []) -> throwGhcException $ CmdLineError ("Use of -this-component-id requires -instantiated-with")
(Just u, is)
-- detect fully indefinite units: all their instantiations are hole
-- modules and the home unit id is the same as the instantiating unit
-- id (see Note [About units] in GHC.Unit)
- | all (isHoleModule . snd) is && indefUnit u == homeUnitId dflags
- -> mkVirtUnit (updateIndefUnitId (unitState dflags) u) is
- -- otherwise it must be that we compile a fully definite units
+ | all (isHoleModule . snd) is && u == hu_id
+ -> IndefiniteHomeUnit u is
+ -- otherwise it must be that we (fully) instantiate an indefinite unit
+ -- to make it definite.
-- TODO: error when the unit is partially instantiated??
| otherwise
- -> RealUnit (Definite (homeUnitId dflags))
+ -> DefiniteHomeUnit hu_id (Just (u, is))
parseUnitInsts :: String -> Instantiations
parseUnitInsts str = case filter ((=="").snd) (readP_to_S parse str) of
@@ -1947,11 +1942,11 @@ parseUnitInsts str = case filter ((=="").snd) (readP_to_S parse str) of
setUnitInstantiations :: String -> DynFlags -> DynFlags
setUnitInstantiations s d =
- d { homeUnitInstantiations = parseUnitInsts s }
+ d { homeUnitInstantiations_ = parseUnitInsts s }
setUnitInstanceOf :: String -> DynFlags -> DynFlags
setUnitInstanceOf s d =
- d { homeUnitInstanceOfId = Just (Indefinite (UnitId (fsLit s)) Nothing) }
+ d { homeUnitInstanceOf_ = Just (UnitId (fsLit s)) }
addPluginModuleName :: String -> DynFlags -> DynFlags
addPluginModuleName name d = d { pluginModNames = (mkModuleName name) : (pluginModNames d) }
@@ -4533,22 +4528,7 @@ parseUnitArg =
fmap UnitIdArg parseUnit
setUnitId :: String -> DynFlags -> DynFlags
-setUnitId p d = d { homeUnitId = stringToUnitId p }
-
--- | Given a 'ModuleName' of a signature in the home library, find
--- out how it is instantiated. E.g., the canonical form of
--- A in @p[A=q[]:A]@ is @q[]:A@.
-canonicalizeHomeModule :: DynFlags -> ModuleName -> Module
-canonicalizeHomeModule dflags mod_name =
- case lookup mod_name (homeUnitInstantiations dflags) of
- Nothing -> mkHomeModule dflags mod_name
- Just mod -> mod
-
-canonicalizeModuleIfHome :: DynFlags -> Module -> Module
-canonicalizeModuleIfHome dflags mod
- = if homeUnit dflags == moduleUnit mod
- then canonicalizeHomeModule dflags (moduleName mod)
- else mod
+setUnitId p d = d { homeUnitId_ = stringToUnitId p }
-- If we're linking a binary, then only backends that produce object
-- code are allowed (requests for other target types are ignored).
diff --git a/compiler/GHC/Driver/Types.hs b/compiler/GHC/Driver/Types.hs
index e6cc556121..502ec07569 100644
--- a/compiler/GHC/Driver/Types.hs
+++ b/compiler/GHC/Driver/Types.hs
@@ -80,7 +80,7 @@ module GHC.Driver.Types (
extendInteractiveContext, extendInteractiveContextWithIds,
substInteractiveContext,
setInteractivePrintName, icInteractiveModule,
- InteractiveImport(..), setInteractivePackage,
+ InteractiveImport(..),
mkPrintUnqualified, pprModulePrefix,
mkQualPackage, mkQualModule, pkgQual,
@@ -1797,9 +1797,9 @@ icInScopeTTs :: InteractiveContext -> [TyThing]
icInScopeTTs = ic_tythings
-- | Get the PrintUnqualified function based on the flags and this InteractiveContext
-icPrintUnqual :: DynFlags -> InteractiveContext -> PrintUnqualified
-icPrintUnqual dflags InteractiveContext{ ic_rn_gbl_env = grenv } =
- mkPrintUnqualified dflags grenv
+icPrintUnqual :: UnitState -> HomeUnit -> InteractiveContext -> PrintUnqualified
+icPrintUnqual unit_state home_unit InteractiveContext{ ic_rn_gbl_env = grenv } =
+ mkPrintUnqualified unit_state home_unit grenv
-- | extendInteractiveContext is called with new TyThings recently defined to update the
-- InteractiveContext to include them. Ids are easily removed when shadowed,
@@ -1852,12 +1852,6 @@ shadowed_by ids = shadowed
shadowed id = getOccName id `elemOccSet` new_occs
new_occs = mkOccSet (map getOccName ids)
--- | Set the 'DynFlags.homeUnitId' to 'interactive'
-setInteractivePackage :: HscEnv -> HscEnv
-setInteractivePackage hsc_env
- = hsc_env { hsc_dflags = (hsc_dflags hsc_env)
- { homeUnitId = interactiveUnitId } }
-
setInteractivePrintName :: InteractiveContext -> Name -> InteractiveContext
setInteractivePrintName ic n = ic{ic_int_print = n}
@@ -1956,12 +1950,12 @@ with some holes, we should try to give the user some more useful information.
-- | Creates some functions that work out the best ways to format
-- names for the user according to a set of heuristics.
-mkPrintUnqualified :: DynFlags -> GlobalRdrEnv -> PrintUnqualified
-mkPrintUnqualified dflags env = QueryQualify qual_name
- (mkQualModule dflags)
- (mkQualPackage pkgs)
+mkPrintUnqualified :: UnitState -> HomeUnit -> GlobalRdrEnv -> PrintUnqualified
+mkPrintUnqualified unit_state home_unit env
+ = QueryQualify qual_name
+ (mkQualModule unit_state home_unit)
+ (mkQualPackage unit_state)
where
- pkgs = unitState dflags
qual_name mod occ
| [gre] <- unqual_gres
, right_name gre
@@ -2016,9 +2010,9 @@ mkPrintUnqualified dflags env = QueryQualify qual_name
-- | Creates a function for formatting modules based on two heuristics:
-- (1) if the module is the current module, don't qualify, and (2) if there
-- is only one exposed package which exports this module, don't qualify.
-mkQualModule :: DynFlags -> QueryQualifyModule
-mkQualModule dflags mod
- | isHomeModule dflags mod = False
+mkQualModule :: UnitState -> HomeUnit -> QueryQualifyModule
+mkQualModule unit_state home_unit mod
+ | isHomeModule home_unit mod = False
| [(_, pkgconfig)] <- lookup,
mkUnit pkgconfig == moduleUnit mod
@@ -2027,7 +2021,7 @@ mkQualModule dflags mod
= False
| otherwise = True
- where lookup = lookupModuleInAllUnits (unitState dflags) (moduleName mod)
+ where lookup = lookupModuleInAllUnits unit_state (moduleName mod)
-- | Creates a function for formatting packages based on two heuristics:
-- (1) don't qualify if the package in question is "main", and (2) only qualify
@@ -2308,7 +2302,7 @@ lookupType dflags hpt pte name
where
mod = ASSERT2( isExternalName name, ppr name )
if isHoleName name
- then mkHomeModule dflags (moduleName (nameModule name))
+ then mkHomeModule (mkHomeUnitFromFlags dflags) (moduleName (nameModule name))
else nameModule name
-- | As 'lookupType', but with a marginally easier-to-use interface
diff --git a/compiler/GHC/HsToCore.hs b/compiler/GHC/HsToCore.hs
index 3d96b38ccc..2b98d9343f 100644
--- a/compiler/GHC/HsToCore.hs
+++ b/compiler/GHC/HsToCore.hs
@@ -50,7 +50,7 @@ import GHC.Core.Coercion
import GHC.Builtin.Types
import GHC.Core.DataCon ( dataConWrapId )
import GHC.Core.Make
-import GHC.Unit.Module
+import GHC.Unit
import GHC.Types.Name.Set
import GHC.Types.Name.Env
import GHC.Core.Rules
@@ -119,7 +119,11 @@ deSugar hsc_env
})
= do { let dflags = hsc_dflags hsc_env
- print_unqual = mkPrintUnqualified dflags rdr_env
+ home_unit = mkHomeUnitFromFlags dflags
+ print_unqual = mkPrintUnqualified
+ (unitState dflags)
+ home_unit
+ rdr_env
; withTiming dflags
(text "Desugar"<+>brackets (ppr mod))
(const ()) $
@@ -174,9 +178,9 @@ deSugar hsc_env
; endPassIO hsc_env print_unqual CoreDesugarOpt ds_binds ds_rules_for_imps
; let used_names = mkUsedNames tcg_env
- pluginModules =
- map lpModule (cachedPlugins (hsc_dflags hsc_env))
- ; deps <- mkDependencies (homeUnitId (hsc_dflags hsc_env))
+ pluginModules = map lpModule (cachedPlugins (hsc_dflags hsc_env))
+ home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
+ ; deps <- mkDependencies (homeUnitId home_unit)
(map mi_module pluginModules) tcg_env
; used_th <- readIORef tc_splice_used
diff --git a/compiler/GHC/HsToCore/Monad.hs b/compiler/GHC/HsToCore/Monad.hs
index 43b4376752..b6b0305a25 100644
--- a/compiler/GHC/HsToCore/Monad.hs
+++ b/compiler/GHC/HsToCore/Monad.hs
@@ -294,7 +294,10 @@ mkDsEnvs dflags mod rdr_env type_env fam_inst_env msg_var cc_st_var
gbl_env = DsGblEnv { ds_mod = mod
, ds_fam_inst_env = fam_inst_env
, ds_if_env = (if_genv, if_lenv)
- , ds_unqual = mkPrintUnqualified dflags rdr_env
+ , ds_unqual = mkPrintUnqualified
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ rdr_env
, ds_msgs = msg_var
, ds_complete_matches = completeMatchMap
, ds_cc_st = cc_st_var
diff --git a/compiler/GHC/HsToCore/Usage.hs b/compiler/GHC/HsToCore/Usage.hs
index ef42890302..7fe799ebe4 100644
--- a/compiler/GHC/HsToCore/Usage.hs
+++ b/compiler/GHC/HsToCore/Usage.hs
@@ -60,7 +60,7 @@ its dep_orphs. This was the cause of #14128.
-- | Extract information from the rename and typecheck phases to produce
-- a dependencies information for the module being compiled.
--
--- The first argument is additional dependencies from plugins
+-- The second argument is additional dependencies from plugins
mkDependencies :: UnitId -> [Module] -> TcGblEnv -> IO Dependencies
mkDependencies iuid pluginModules
(TcGblEnv{ tcg_mod = mod,
@@ -174,7 +174,7 @@ mkPluginUsage hsc_env pluginModule
LookupFound _ pkg -> do
-- The plugin is from an external package:
-- search for the library files containing the plugin.
- let searchPaths = collectLibraryPaths dflags [pkg]
+ let searchPaths = collectLibraryPaths (ways dflags) [pkg]
useDyn = WayDyn `elem` ways dflags
suffix = if useDyn then soExt platform else "a"
libLocs = [ searchPath </> "lib" ++ libLoc <.> suffix
@@ -252,7 +252,7 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
where
hpt = hsc_HPT hsc_env
dflags = hsc_dflags hsc_env
- this_pkg = homeUnit dflags
+ home_unit = mkHomeUnitFromFlags dflags
used_mods = moduleEnvKeys ent_map
dir_imp_mods = moduleEnvKeys direct_imports
@@ -278,7 +278,7 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
Just mod ->
-- See Note [Identity versus semantic module]
let mod' = if isHoleModule mod
- then mkModule this_pkg (moduleName mod)
+ then mkHomeModule home_unit (moduleName mod)
else mod
-- This lambda function is really just a
-- specialised (++); originally came about to
@@ -298,7 +298,7 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
-- things in *this* module
= Nothing
- | moduleUnit mod /= this_pkg
+ | not (isHomeModule home_unit mod)
= Just UsagePackageModule{ usg_mod = mod,
usg_mod_hash = mod_hash,
usg_safe = imp_safe }
diff --git a/compiler/GHC/Iface/Load.hs b/compiler/GHC/Iface/Load.hs
index b7ed66734e..508a6b8281 100644
--- a/compiler/GHC/Iface/Load.hs
+++ b/compiler/GHC/Iface/Load.hs
@@ -82,6 +82,7 @@ import GHC.Types.FieldLabel
import GHC.Iface.Rename
import GHC.Types.Unique.DSet
import GHC.Driver.Plugins
+import GHC.Unit.Home
import Control.Monad
import Control.Exception
@@ -402,8 +403,9 @@ loadInterface doc_str mod from
| isHoleModule mod
-- Hole modules get special treatment
= do dflags <- getDynFlags
+ let home_unit = mkHomeUnitFromFlags dflags
-- Redo search for our local hole module
- loadInterface doc_str (mkHomeModule dflags (moduleName mod)) from
+ loadInterface doc_str (mkHomeModule home_unit (moduleName mod)) from
| otherwise
= withTimingSilentD (text "loading interface") (pure ()) $
do { -- Read the state
@@ -414,6 +416,7 @@ loadInterface doc_str mod from
-- Check whether we have the interface already
; dflags <- getDynFlags
+ ; let home_unit = mkHomeUnitFromFlags dflags
; case lookupIfaceByModule hpt (eps_PIT eps) mod of {
Just iface
-> return (Succeeded iface) ; -- Already loaded
@@ -423,7 +426,7 @@ loadInterface doc_str mod from
_ -> do {
-- READ THE MODULE IN
- ; read_result <- case (wantHiBootFile dflags eps mod from) of
+ ; read_result <- case (wantHiBootFile home_unit eps mod from) of
Failed err -> return (Failed err)
Succeeded hi_boot_file -> computeInterface doc_str hi_boot_file mod
; case read_result of {
@@ -494,7 +497,7 @@ loadInterface doc_str mod from
; WARN( bad_boot, ppr mod )
updateEps_ $ \ eps ->
- if elemModuleEnv mod (eps_PIT eps) || is_external_sig dflags iface
+ if elemModuleEnv mod (eps_PIT eps) || is_external_sig home_unit iface
then eps
else if bad_boot
-- See Note [Loading your own hi-boot file]
@@ -616,12 +619,12 @@ dontLeakTheHPT thing_inside = do
-- | Returns @True@ if a 'ModIface' comes from an external package.
-- In this case, we should NOT load it into the EPS; the entities
-- should instead come from the local merged signature interface.
-is_external_sig :: DynFlags -> ModIface -> Bool
-is_external_sig dflags iface =
+is_external_sig :: HomeUnit -> ModIface -> Bool
+is_external_sig home_unit iface =
-- It's a signature iface...
mi_semantic_module iface /= mi_module iface &&
-- and it's not from the local package
- moduleUnit (mi_module iface) /= homeUnit dflags
+ not (isHomeModule home_unit (mi_module iface))
-- | This is an improved version of 'findAndReadIface' which can also
-- handle the case when a user requests @p[A=<B>]:M@ but we only
@@ -643,8 +646,9 @@ computeInterface ::
computeInterface doc_str hi_boot_file mod0 = do
MASSERT( not (isHoleModule mod0) )
dflags <- getDynFlags
+ let home_unit = mkHomeUnitFromFlags dflags
case getModuleInstantiation mod0 of
- (imod, Just indef) | homeUnitIsIndefinite dflags -> do
+ (imod, Just indef) | isHomeUnitIndefinite home_unit -> do
r <- findAndReadIface doc_str imod mod0 hi_boot_file
case r of
Succeeded (iface0, path) -> do
@@ -702,13 +706,13 @@ moduleFreeHolesPrecise doc_str mod
return (Succeeded (renameFreeHoles ifhs insts))
Failed err -> return (Failed err)
-wantHiBootFile :: DynFlags -> ExternalPackageState -> Module -> WhereFrom
+wantHiBootFile :: HomeUnit -> ExternalPackageState -> Module -> WhereFrom
-> MaybeErr MsgDoc IsBootInterface
-- Figure out whether we want Foo.hi or Foo.hi-boot
-wantHiBootFile dflags eps mod from
+wantHiBootFile home_unit eps mod from
= case from of
ImportByUser usr_boot
- | usr_boot == IsBoot && not this_package
+ | usr_boot == IsBoot && notHomeModule home_unit mod
-> Failed (badSourceImport mod)
| otherwise -> Succeeded usr_boot
@@ -716,10 +720,12 @@ wantHiBootFile dflags eps mod from
-> Succeeded NotBoot
ImportBySystem
- | not this_package -- If the module to be imported is not from this package
- -> Succeeded NotBoot -- don't look it up in eps_is_boot, because that is keyed
- -- on the ModuleName of *home-package* modules only.
- -- We never import boot modules from other packages!
+ | notHomeModule home_unit mod
+ -> Succeeded NotBoot
+ -- If the module to be imported is not from this package
+ -- don't look it up in eps_is_boot, because that is keyed
+ -- on the ModuleName of *home-package* modules only.
+ -- We never import boot modules from other packages!
| otherwise
-> case lookupUFM (eps_is_boot eps) (moduleName mod) of
@@ -729,8 +735,6 @@ wantHiBootFile dflags eps mod from
Succeeded NotBoot
-- The boot-ness of the requested interface,
-- based on the dependencies in directly-imported modules
- where
- this_package = homeUnit dflags == moduleUnit mod
badSourceImport :: Module -> SDoc
badSourceImport mod
@@ -922,6 +926,7 @@ findAndReadIface doc_str mod wanted_mod_with_insts hi_boot_file
-- Look for the file
hsc_env <- getTopEnv
mb_found <- liftIO (findExactModule hsc_env mod)
+ let home_unit = mkHomeUnitFromFlags dflags
case mb_found of
InstalledFound loc mod -> do
-- Found file, so read it
@@ -929,7 +934,7 @@ findAndReadIface doc_str mod wanted_mod_with_insts hi_boot_file
(ml_hi_file loc)
-- See Note [Home module load error]
- if moduleUnit mod `unitIdEq` homeUnit dflags &&
+ if isHomeInstalledModule home_unit mod &&
not (isOneShot (ghcMode dflags))
then return (Failed (homeModError mod loc))
else do r <- read_file file_path
@@ -1020,8 +1025,8 @@ readIface wanted_mod file_path
*********************************************************
-}
-initExternalPackageState :: DynFlags -> ExternalPackageState
-initExternalPackageState dflags
+initExternalPackageState :: HomeUnit -> ExternalPackageState
+initExternalPackageState home_unit
= EPS {
eps_is_boot = emptyUFM,
eps_PIT = emptyPackageIfaceTable,
@@ -1041,9 +1046,9 @@ initExternalPackageState dflags
}
where
enableBignumRules
- | homeUnitId dflags == primUnitId = EnableBignumRules False
- | homeUnitId dflags == bignumUnitId = EnableBignumRules False
- | otherwise = EnableBignumRules True
+ | isHomeUnitInstanceOf home_unit primUnitId = EnableBignumRules False
+ | isHomeUnitInstanceOf home_unit bignumUnitId = EnableBignumRules False
+ | otherwise = EnableBignumRules True
builtinRules' = builtinRules enableBignumRules
{-
diff --git a/compiler/GHC/Iface/Make.hs b/compiler/GHC/Iface/Make.hs
index 3c33c0a3b6..575ef06a11 100644
--- a/compiler/GHC/Iface/Make.hs
+++ b/compiler/GHC/Iface/Make.hs
@@ -57,7 +57,7 @@ import GHC.Types.Avail
import GHC.Types.Name.Reader
import GHC.Types.Name.Env
import GHC.Types.Name.Set
-import GHC.Unit.Module
+import GHC.Unit
import GHC.Utils.Error
import GHC.Utils.Outputable
import GHC.Utils.Panic
@@ -168,10 +168,9 @@ mkIfaceTc hsc_env safe_mode mod_details
}
= do
let used_names = mkUsedNames tc_result
- let pluginModules =
- map lpModule (cachedPlugins (hsc_dflags hsc_env))
- deps <- mkDependencies
- (homeUnitId (hsc_dflags hsc_env))
+ let pluginModules = map lpModule (cachedPlugins (hsc_dflags hsc_env))
+ let home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
+ deps <- mkDependencies (homeUnitId home_unit)
(map mi_module pluginModules) tc_result
let hpc_info = emptyHpcInfo other_hpc_info
used_th <- readIORef tc_splice_used
@@ -226,7 +225,8 @@ mkIface_ hsc_env
-- to expose in the interface
= do
- let semantic_mod = canonicalizeHomeModule (hsc_dflags hsc_env) (moduleName this_mod)
+ let home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
+ semantic_mod = homeModuleNameInstantiation home_unit (moduleName this_mod)
entities = typeEnvElts type_env
show_linear_types = xopt LangExt.LinearTypes (hsc_dflags hsc_env)
decls = [ tyThingToIfaceDecl show_linear_types entity
diff --git a/compiler/GHC/Iface/Recomp.hs b/compiler/GHC/Iface/Recomp.hs
index 7c8dc9722c..2ffb094b11 100644
--- a/compiler/GHC/Iface/Recomp.hs
+++ b/compiler/GHC/Iface/Recomp.hs
@@ -44,6 +44,7 @@ import GHC.Utils.Fingerprint
import GHC.Utils.Exception
import GHC.Types.Unique.Set
import GHC.Unit.State
+import GHC.Unit.Home
import Control.Monad
import Data.Function
@@ -215,7 +216,7 @@ checkVersions hsc_env mod_summary iface
-- readIface will have verified that the UnitId matches,
-- but we ALSO must make sure the instantiation matches up. See
-- test case bkpcabal04!
- ; if moduleUnit (mi_module iface) /= homeUnit (hsc_dflags hsc_env)
+ ; if not (isHomeModule home_unit (mi_module iface))
then return (RecompBecause "-this-unit-id changed", Nothing) else do {
; recomp <- checkFlagHash hsc_env iface
; if recompileRequired recomp then return (recomp, Nothing) else do {
@@ -249,11 +250,12 @@ checkVersions hsc_env mod_summary iface
-- all the dependent modules should be in the HPT already, so it's
-- quite redundant
; updateEps_ $ \eps -> eps { eps_is_boot = mod_deps }
- ; recomp <- checkList [checkModUsage this_pkg u | u <- mi_usages iface]
+ ; recomp <- checkList [checkModUsage (homeUnitAsUnit home_unit) u
+ | u <- mi_usages iface]
; return (recomp, Just iface)
}}}}}}}}}}
where
- this_pkg = homeUnit (hsc_dflags hsc_env)
+ home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
-- This is a bit of a hack really
mod_deps :: ModuleNameEnv ModuleNameWithIsBoot
mod_deps = mkModDeps (dep_mods (mi_deps iface))
@@ -333,9 +335,10 @@ pluginRecompileToRecompileRequired old_fp new_fp pr
checkHsig :: ModSummary -> ModIface -> IfG RecompileRequired
checkHsig mod_summary iface = do
dflags <- getDynFlags
- let outer_mod = ms_mod mod_summary
- inner_mod = canonicalizeHomeModule dflags (moduleName outer_mod)
- MASSERT( moduleUnit outer_mod == homeUnit dflags )
+ let home_unit = mkHomeUnitFromFlags dflags
+ outer_mod = ms_mod mod_summary
+ inner_mod = homeModuleNameInstantiation home_unit (moduleName outer_mod)
+ MASSERT( isHomeModule home_unit outer_mod )
case inner_mod == mi_semantic_module iface of
True -> up_to_date (text "implementing module unchanged")
False -> return (RecompBecause "implementing module changed")
@@ -449,15 +452,14 @@ checkDependencies hsc_env summary iface
prev_dep_mods = dep_mods (mi_deps iface)
prev_dep_plgn = dep_plgins (mi_deps iface)
prev_dep_pkgs = dep_pkgs (mi_deps iface)
-
- this_pkg = homeUnit (hsc_dflags hsc_env)
+ home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
dep_missing (mb_pkg, L _ mod) = do
find_res <- liftIO $ findImportedModule hsc_env mod (mb_pkg)
let reason = moduleNameString mod ++ " changed"
case find_res of
Found _ mod
- | pkg == this_pkg
+ | isHomeUnit home_unit pkg
-> if moduleName mod `notElem` map gwib_mod prev_dep_mods ++ prev_dep_plgn
then do traceHiDiffs $
text "imported module " <> quotes (ppr mod) <>
@@ -483,7 +485,8 @@ checkDependencies hsc_env summary iface
isOldHomeDeps = flip Set.member old_deps
checkForNewHomeDependency (L _ mname) = do
let
- mod = mkModule this_pkg mname
+ home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
+ mod = mkHomeModule home_unit mname
str_mname = moduleNameString mname
reason = str_mname ++ " changed"
-- We only want to look at home modules to check if any new home dependency
@@ -1351,11 +1354,12 @@ mkHashFun
-> (Name -> IO Fingerprint)
mkHashFun hsc_env eps name
| isHoleModule orig_mod
- = lookup (mkHomeModule dflags (moduleName orig_mod))
+ = lookup (mkHomeModule home_unit (moduleName orig_mod))
| otherwise
= lookup orig_mod
where
dflags = hsc_dflags hsc_env
+ home_unit = mkHomeUnitFromFlags dflags
hpt = hsc_HPT hsc_env
pit = eps_PIT eps
occ = nameOccName name
diff --git a/compiler/GHC/Iface/Recomp/Flags.hs b/compiler/GHC/Iface/Recomp/Flags.hs
index 391aaf2c86..3cbfdd1e3b 100644
--- a/compiler/GHC/Iface/Recomp/Flags.hs
+++ b/compiler/GHC/Iface/Recomp/Flags.hs
@@ -36,7 +36,7 @@ fingerprintDynFlags :: DynFlags -> Module
fingerprintDynFlags dflags@DynFlags{..} this_mod nameio =
let mainis = if mainModIs == this_mod then Just mainFunIs else Nothing
-- see #5878
- -- pkgopts = (homeUnit dflags, sort $ packageFlags dflags)
+ -- pkgopts = (homeUnit home_unit, sort $ packageFlags dflags)
safeHs = setSafeMode safeHaskell
-- oflags = sort $ filter filterOFlags $ flags dflags
diff --git a/compiler/GHC/Iface/Rename.hs b/compiler/GHC/Iface/Rename.hs
index ed8ac78761..376eee8350 100644
--- a/compiler/GHC/Iface/Rename.hs
+++ b/compiler/GHC/Iface/Rename.hs
@@ -299,6 +299,7 @@ rnIfaceGlobal :: Name -> ShIfM Name
rnIfaceGlobal n = do
hsc_env <- getTopEnv
let dflags = hsc_dflags hsc_env
+ home_unit = mkHomeUnitFromFlags dflags
iface_semantic_mod <- fmap sh_if_semantic_module getGblEnv
mb_nsubst <- fmap sh_if_shape getGblEnv
hmap <- getHoleSubst
@@ -342,7 +343,7 @@ rnIfaceGlobal n = do
-- went from <A> to <B>.
let m'' = if isHoleModule m'
-- Pull out the local guy!!
- then mkHomeModule dflags (moduleName m')
+ then mkHomeModule home_unit (moduleName m')
else m'
iface <- liftIO . initIfaceCheck (text "rnIfaceGlobal") hsc_env
$ loadSysInterface (text "rnIfaceGlobal") m''
diff --git a/compiler/GHC/Iface/Tidy.hs b/compiler/GHC/Iface/Tidy.hs
index f687f2951b..557c3e0922 100644
--- a/compiler/GHC/Iface/Tidy.hs
+++ b/compiler/GHC/Iface/Tidy.hs
@@ -368,7 +368,10 @@ tidyProgram hsc_env (ModGuts { mg_module = mod
(const ()) $
do { let { omit_prags = gopt Opt_OmitInterfacePragmas dflags
; expose_all = gopt Opt_ExposeAllUnfoldings dflags
- ; print_unqual = mkPrintUnqualified dflags rdr_env
+ ; print_unqual = mkPrintUnqualified
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ rdr_env
; implicit_binds = concatMap getImplicitBinds tcs
}
diff --git a/compiler/GHC/Parser/Lexer.x b/compiler/GHC/Parser/Lexer.x
index dafc1e0fb0..1a131fc321 100644
--- a/compiler/GHC/Parser/Lexer.x
+++ b/compiler/GHC/Parser/Lexer.x
@@ -2213,7 +2213,8 @@ warnopt f options = f `EnumSet.member` pWarningFlags options
-- See 'mkParserFlags' or 'mkParserFlags'' for ways to construct this.
data ParserFlags = ParserFlags {
pWarningFlags :: EnumSet WarningFlag
- , pHomeUnitId :: UnitId -- ^ unit currently being compiled
+ , pHomeUnitId :: UnitId -- ^ id of the unit currently being compiled
+ -- (only used in Cmm parser)
, pExtsBitmap :: !ExtsBitmap -- ^ bitmap of permitted extensions
}
@@ -2644,6 +2645,7 @@ mkParserFlags'
:: EnumSet WarningFlag -- ^ warnings flags enabled
-> EnumSet LangExt.Extension -- ^ permitted language extensions enabled
-> UnitId -- ^ id of the unit currently being compiled
+ -- (used in Cmm parser)
-> Bool -- ^ are safe imports on?
-> Bool -- ^ keeping Haddock comment tokens
-> Bool -- ^ keep regular comment tokens
@@ -2725,7 +2727,7 @@ mkParserFlags =
mkParserFlags'
<$> DynFlags.warningFlags
<*> DynFlags.extensionFlags
- <*> DynFlags.homeUnitId
+ <*> DynFlags.homeUnitId_
<*> safeImportsOn
<*> gopt Opt_Haddock
<*> gopt Opt_KeepRawTokenStream
diff --git a/compiler/GHC/Rename/Module.hs b/compiler/GHC/Rename/Module.hs
index 8920027e66..581af6e2d4 100644
--- a/compiler/GHC/Rename/Module.hs
+++ b/compiler/GHC/Rename/Module.hs
@@ -43,7 +43,7 @@ import GHC.Tc.Gen.Annotation ( annCtxt )
import GHC.Tc.Utils.Monad
import GHC.Types.ForeignCall ( CCallTarget(..) )
-import GHC.Unit.Module
+import GHC.Unit
import GHC.Driver.Types ( Warnings(..), plusWarns )
import GHC.Builtin.Names( applicativeClassName, pureAName, thenAName
, monadClassName, returnMName, thenMName
@@ -375,8 +375,8 @@ rnHsForeignDecl (ForeignImport { fd_name = name, fd_sig_ty = ty, fd_fi = spec })
; (ty', fvs) <- rnHsSigType (ForeignDeclCtx name) TypeLevel ty
-- Mark any PackageTarget style imports as coming from the current package
- ; let unitId = homeUnit $ hsc_dflags topEnv
- spec' = patchForeignImport unitId spec
+ ; let home_unit = mkHomeUnitFromFlags (hsc_dflags topEnv)
+ spec' = patchForeignImport (homeUnitAsUnit home_unit) spec
; return (ForeignImport { fd_i_ext = noExtField
, fd_name = name', fd_sig_ty = ty'
diff --git a/compiler/GHC/Rename/Names.hs b/compiler/GHC/Rename/Names.hs
index 391c464fdb..7531913a7b 100644
--- a/compiler/GHC/Rename/Names.hs
+++ b/compiler/GHC/Rename/Names.hs
@@ -45,7 +45,7 @@ import GHC.Rename.Utils ( warnUnusedTopBinds, mkFieldEnv )
import GHC.Iface.Load ( loadSrcInterface )
import GHC.Tc.Utils.Monad
import GHC.Builtin.Names
-import GHC.Unit.Module
+import GHC.Unit
import GHC.Types.Name
import GHC.Types.Name.Env
import GHC.Types.Name.Set
@@ -451,8 +451,10 @@ calculateAvails dflags iface mod_safe' want_boot imported_by =
-- to be trusted? See Note [Trust Own Package]
ptrust = trust == Sf_Trustworthy || trust_pkg
+ home_unit = mkHomeUnitFromFlags dflags
+
(dependent_mods, dependent_pkgs, pkg_trust_req)
- | pkg == homeUnit dflags =
+ | isHomeUnit home_unit pkg =
-- Imported module is from the home package
-- Take its dependent modules and add imp_mod itself
-- Take its dependent packages unchanged
diff --git a/compiler/GHC/Runtime/Eval.hs b/compiler/GHC/Runtime/Eval.hs
index 2ee3143f76..7197710cfb 100644
--- a/compiler/GHC/Runtime/Eval.hs
+++ b/compiler/GHC/Runtime/Eval.hs
@@ -85,7 +85,7 @@ import GHC.LanguageExtensions
import GHC.Types.Unique
import GHC.Types.Unique.Supply
import GHC.Utils.Monad
-import GHC.Unit.Module
+import GHC.Unit
import GHC.Builtin.Names ( toDynName, pretendNameIsInScope )
import GHC.Builtin.Types ( isCTupleTyConName )
import GHC.Utils.Panic
@@ -812,7 +812,7 @@ getContext = withSession $ \HscEnv{ hsc_IC=ic } ->
-- its full top-level scope available.
moduleIsInterpreted :: GhcMonad m => Module -> m Bool
moduleIsInterpreted modl = withSession $ \h ->
- if not (isHomeModule (hsc_dflags h) modl)
+ if notHomeModule (mkHomeUnitFromFlags (hsc_dflags h)) modl
then return False
else case lookupHpt (hsc_HPT h) (moduleName modl) of
Just details -> return (isJust (mi_globals (hm_iface details)))
diff --git a/compiler/GHC/Runtime/Linker.hs b/compiler/GHC/Runtime/Linker.hs
index 8c05c38c6c..4a3b03e5eb 100644
--- a/compiler/GHC/Runtime/Linker.hs
+++ b/compiler/GHC/Runtime/Linker.hs
@@ -47,6 +47,7 @@ import GHC.Platform.Ways
import GHC.Types.Name
import GHC.Types.Name.Env
import GHC.Unit.Module
+import GHC.Unit.Home
import GHC.Data.List.SetOps
import GHC.Runtime.Linker.Types (DynLinker(..), PersistentLinkerState(..))
import GHC.Driver.Session
@@ -656,7 +657,6 @@ getLinkDeps hsc_env hpt pls replace_osuf span mods
; return (lnks_needed, pkgs_needed) }
where
dflags = hsc_dflags hsc_env
- this_pkg = homeUnit dflags
-- The ModIface contains the transitive closure of the module dependencies
-- within the current package, *except* for boot modules: if we encounter
@@ -682,6 +682,7 @@ getLinkDeps hsc_env hpt pls replace_osuf span mods
let
pkg = moduleUnit mod
deps = mi_deps iface
+ home_unit = mkHomeUnitFromFlags dflags
pkg_deps = dep_pkgs deps
(boot_deps, mod_deps) = flip partitionWith (dep_mods deps) $
@@ -694,9 +695,9 @@ getLinkDeps hsc_env hpt pls replace_osuf span mods
acc_mods' = addListToUniqDSet acc_mods (moduleName mod : mod_deps)
acc_pkgs' = addListToUniqDSet acc_pkgs $ map fst pkg_deps
--
- if pkg /= this_pkg
+ if not (isHomeUnit home_unit pkg)
then follow_deps mods acc_mods (addOneToUniqDSet acc_pkgs' (toUnitId pkg))
- else follow_deps (map (mkModule this_pkg) boot_deps' ++ mods)
+ else follow_deps (map (mkHomeModule home_unit) boot_deps' ++ mods)
acc_mods' acc_pkgs'
where
msg = text "need to link module" <+> ppr mod <+>
diff --git a/compiler/GHC/SysTools.hs b/compiler/GHC/SysTools.hs
index e309b839f7..f3b4f4cc87 100644
--- a/compiler/GHC/SysTools.hs
+++ b/compiler/GHC/SysTools.hs
@@ -45,6 +45,7 @@ import GHC.Settings.Utils
import GHC.Unit
import GHC.Utils.Error
import GHC.Utils.Panic
+import GHC.Utils.Outputable
import GHC.Platform
import GHC.Driver.Session
import GHC.Platform.Ways
@@ -246,9 +247,13 @@ linkDynLib dflags0 o_files dep_packages
verbFlags = getVerbFlags dflags
o_file = outputFile dflags
- pkgs <- getPreloadUnitsAnd dflags dep_packages
+ pkgs <- getPreloadUnitsAnd
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ dep_packages
- let pkg_lib_paths = collectLibraryPaths dflags pkgs
+ let pkg_lib_paths = collectLibraryPaths (ways dflags) pkgs
let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths
get_pkg_lib_path_opts l
| ( osElfTarget (platformOS (targetPlatform dflags)) ||
@@ -426,11 +431,19 @@ getUnitFrameworkOpts :: DynFlags -> Platform -> [UnitId] -> IO [String]
getUnitFrameworkOpts dflags platform dep_packages
| platformUsesFrameworks platform = do
pkg_framework_path_opts <- do
- pkg_framework_paths <- getUnitFrameworkPath dflags dep_packages
+ pkg_framework_paths <- getUnitFrameworkPath
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ dep_packages
return $ map ("-F" ++) pkg_framework_paths
pkg_framework_opts <- do
- pkg_frameworks <- getUnitFrameworks dflags dep_packages
+ pkg_frameworks <- getUnitFrameworks
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ dep_packages
return $ concat [ ["-framework", fw] | fw <- pkg_frameworks ]
return (pkg_framework_path_opts ++ pkg_framework_opts)
diff --git a/compiler/GHC/SysTools/ExtraObj.hs b/compiler/GHC/SysTools/ExtraObj.hs
index c4247d8496..94443824e3 100644
--- a/compiler/GHC/SysTools/ExtraObj.hs
+++ b/compiler/GHC/SysTools/ExtraObj.hs
@@ -172,8 +172,11 @@ mkNoteObjsToLinkIntoBinary dflags dep_packages = do
getLinkInfo :: DynFlags -> [UnitId] -> IO String
getLinkInfo dflags dep_packages = do
package_link_opts <- getUnitLinkOpts dflags dep_packages
+ let unit_state = unitState dflags
+ home_unit = mkHomeUnitFromFlags dflags
+ ctx = initSDocContext dflags defaultUserStyle
pkg_frameworks <- if platformUsesFrameworks (targetPlatform dflags)
- then getUnitFrameworks dflags dep_packages
+ then getUnitFrameworks ctx unit_state home_unit dep_packages
else return []
let extra_ld_inputs = ldInputs dflags
let
diff --git a/compiler/GHC/Tc/Module.hs b/compiler/GHC/Tc/Module.hs
index d642a15147..8231955063 100644
--- a/compiler/GHC/Tc/Module.hs
+++ b/compiler/GHC/Tc/Module.hs
@@ -110,7 +110,7 @@ import GHC.Utils.Error
import GHC.Types.Id as Id
import GHC.Types.Id.Info( IdDetails(..) )
import GHC.Types.Var.Env
-import GHC.Unit.Module
+import GHC.Unit
import GHC.Types.Unique.FM
import GHC.Types.Name
import GHC.Types.Name.Env
@@ -181,15 +181,14 @@ tcRnModule hsc_env mod_sum save_rn_syntax
where
hsc_src = ms_hsc_src mod_sum
dflags = hsc_dflags hsc_env
- err_msg = mkPlainErrMsg (hsc_dflags hsc_env) loc $
+ home_unit = mkHomeUnitFromFlags dflags
+ err_msg = mkPlainErrMsg dflags loc $
text "Module does not have a RealSrcSpan:" <+> ppr this_mod
- this_pkg = homeUnit (hsc_dflags hsc_env)
-
pair :: (Module, SrcSpan)
pair@(this_mod,_)
| Just (L mod_loc mod) <- hsmodName this_module
- = (mkModule this_pkg mod, mod_loc)
+ = (mkHomeModule home_unit mod, mod_loc)
| otherwise -- 'module M where' is omitted
= (mAIN, srcLocSpan (srcSpanStart loc))
@@ -2839,12 +2838,12 @@ loadUnqualIfaces hsc_env ictxt
= initIfaceTcRn $ do
mapM_ (loadSysInterface doc) (moduleSetElts (mkModuleSet unqual_mods))
where
- this_pkg = homeUnit (hsc_dflags hsc_env)
+ home_unit = mkHomeUnitFromFlags (hsc_dflags hsc_env)
unqual_mods = [ nameModule name
| gre <- globalRdrEnvElts (ic_rn_gbl_env ictxt)
, let name = gre_name gre
- , nameIsFromExternalPackage this_pkg name
+ , nameIsFromExternalPackage home_unit name
, isTcOcc (nameOccName name) -- Types and classes only
, unQualOK gre ] -- In scope unqualified
doc = text "Need interface for module whose export(s) are in scope unqualified"
diff --git a/compiler/GHC/Tc/TyCl.hs b/compiler/GHC/Tc/TyCl.hs
index ccc23c3930..113fadd20d 100644
--- a/compiler/GHC/Tc/TyCl.hs
+++ b/compiler/GHC/Tc/TyCl.hs
@@ -61,8 +61,7 @@ import GHC.Types.Id
import GHC.Types.Var
import GHC.Types.Var.Env
import GHC.Types.Var.Set
-import GHC.Unit.Module
-import GHC.Unit.State
+import GHC.Unit
import GHC.Types.Name
import GHC.Types.Name.Set
import GHC.Types.Name.Env
@@ -174,8 +173,8 @@ tcTyClGroup (TyClGroup { group_tyclds = tyclds
-- Step 1.5: Make sure we don't have any type synonym cycles
; traceTc "Starting synonym cycle check" (ppr tyclss)
- ; this_uid <- fmap homeUnit getDynFlags
- ; checkSynCycles this_uid tyclss tyclds
+ ; home_unit <- mkHomeUnitFromFlags <$> getDynFlags
+ ; checkSynCycles (homeUnitAsUnit home_unit) tyclss tyclds
; traceTc "Done synonym cycle check" (ppr tyclss)
-- Step 2: Perform the validity check on those types/classes
@@ -4136,7 +4135,7 @@ checkValidDataCon dflags existential_ok tc con
-- when we actually fill in the abstract type. As such, don't
-- warn in this case (it gives users the wrong idea about whether
-- or not UNPACK on abstract types is supported; it is!)
- , homeUnitIsDefinite dflags
+ , isHomeUnitDefinite (mkHomeUnitFromFlags dflags)
= addWarnTc NoReason (bad_bang n (text "Ignoring unusable UNPACK pragma"))
where
is_strict = case strict_mark of
diff --git a/compiler/GHC/Tc/Utils/Backpack.hs b/compiler/GHC/Tc/Utils/Backpack.hs
index bddda199a8..5dbc90de86 100644
--- a/compiler/GHC/Tc/Utils/Backpack.hs
+++ b/compiler/GHC/Tc/Utils/Backpack.hs
@@ -21,7 +21,7 @@ module GHC.Tc.Utils.Backpack (
import GHC.Prelude
import GHC.Types.Basic (defaultFixity, TypeOrKind(..))
-import GHC.Unit.State
+import GHC.Unit
import GHC.Tc.Gen.Export
import GHC.Driver.Session
import GHC.Driver.Ppr
@@ -42,7 +42,6 @@ import GHC.Iface.Load
import GHC.Rename.Names
import GHC.Utils.Error
import GHC.Types.Id
-import GHC.Unit.Module
import GHC.Types.Name
import GHC.Types.Name.Env
import GHC.Types.Name.Set
@@ -312,10 +311,11 @@ implicitRequirements' hsc_env normal_imports
forM normal_imports $ \(mb_pkg, L _ imp) -> do
found <- findImportedModule hsc_env imp mb_pkg
case found of
- Found _ mod | not (isHomeModule dflags mod) ->
+ Found _ mod | not (isHomeModule home_unit mod) ->
return (uniqDSetToList (moduleFreeHoles mod))
_ -> return []
where dflags = hsc_dflags hsc_env
+ home_unit = mkHomeUnitFromFlags dflags
-- | Given a 'Unit', make sure it is well typed. This is because
-- unit IDs come from Cabal, which does not know if things are well-typed or
@@ -539,6 +539,7 @@ mergeSignatures
inner_mod = tcg_semantic_mod tcg_env
mod_name = moduleName (tcg_mod tcg_env)
pkgstate = unitState dflags
+ home_unit = mkHomeUnitFromFlags dflags
-- STEP 1: Figure out all of the external signature interfaces
-- we are going to merge in.
@@ -734,7 +735,7 @@ mergeSignatures
-- STEP 4: Rename the interfaces
ext_ifaces <- forM thinned_ifaces $ \((Module iuid _), ireq_iface) ->
tcRnModIface (instUnitInsts iuid) (Just nsubst) ireq_iface
- lcl_iface <- tcRnModIface (homeUnitInstantiations dflags) (Just nsubst) lcl_iface0
+ lcl_iface <- tcRnModIface (homeUnitInstantiations home_unit) (Just nsubst) lcl_iface0
let ifaces = lcl_iface : ext_ifaces
-- STEP 4.1: Merge fixities (we'll verify shortly) tcg_fix_env
@@ -756,7 +757,7 @@ mergeSignatures
let infos = zip ifaces detailss
-- Test for cycles
- checkSynCycles (homeUnit dflags) (typeEnvTyCons type_env) []
+ checkSynCycles (homeUnitAsUnit home_unit) (typeEnvTyCons type_env) []
-- NB on type_env: it contains NO dfuns. DFuns are recorded inside
-- detailss, and given a Name that doesn't correspond to anything real. See
@@ -1000,16 +1001,17 @@ instantiateSignature = do
dflags <- getDynFlags
let outer_mod = tcg_mod tcg_env
inner_mod = tcg_semantic_mod tcg_env
+ home_unit = mkHomeUnitFromFlags dflags
+ unit_state = unitState dflags
-- TODO: setup the local RdrEnv so the error messages look a little better.
-- But this information isn't stored anywhere. Should we RETYPECHECK
-- the local one just to get the information? Hmm...
- MASSERT( isHomeModule dflags outer_mod )
- MASSERT( isJust (homeUnitInstanceOfId dflags) )
- let uid = fromJust (homeUnitInstanceOfId dflags)
+ MASSERT( isHomeModule home_unit outer_mod )
+ MASSERT( isHomeUnitInstantiating home_unit)
-- we need to fetch the most recent ppr infos from the unit
-- database because we might have modified it
- uid' = updateIndefUnitId (unitState dflags) uid
+ let uid = mkIndefUnitId unit_state (homeUnitInstanceOf home_unit)
inner_mod `checkImplements`
Module
- (mkInstantiatedUnit uid' (homeUnitInstantiations dflags))
+ (mkInstantiatedUnit uid (homeUnitInstantiations home_unit))
(moduleName outer_mod)
diff --git a/compiler/GHC/Tc/Utils/Env.hs b/compiler/GHC/Tc/Utils/Env.hs
index 0b92d7b3d2..ea20808f98 100644
--- a/compiler/GHC/Tc/Utils/Env.hs
+++ b/compiler/GHC/Tc/Utils/Env.hs
@@ -106,6 +106,7 @@ import GHC.Driver.Session
import GHC.Types.SrcLoc
import GHC.Types.Basic hiding( SuccessFlag(..) )
import GHC.Unit.Module
+import GHC.Unit.Home
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Utils.Encoding
@@ -146,7 +147,8 @@ lookupGlobal_maybe hsc_env name
= do { -- Try local envt
let mod = icInteractiveModule (hsc_IC hsc_env)
dflags = hsc_dflags hsc_env
- tcg_semantic_mod = canonicalizeModuleIfHome dflags mod
+ home_unit = mkHomeUnitFromFlags dflags
+ tcg_semantic_mod = homeModuleInstantiation home_unit mod
; if nameIsLocalOrFrom tcg_semantic_mod name
then (return
diff --git a/compiler/GHC/Tc/Utils/Monad.hs b/compiler/GHC/Tc/Utils/Monad.hs
index 47e1ab8a9d..abdd670483 100644
--- a/compiler/GHC/Tc/Utils/Monad.hs
+++ b/compiler/GHC/Tc/Utils/Monad.hs
@@ -241,6 +241,7 @@ initTc hsc_env hsc_src keep_rn_syntax mod loc do_this
th_remote_state_var <- newIORef Nothing ;
let {
dflags = hsc_dflags hsc_env ;
+ home_unit = mkHomeUnitFromFlags dflags ;
maybe_rn_syntax :: forall a. a -> Maybe a ;
maybe_rn_syntax empty_val
@@ -266,8 +267,7 @@ initTc hsc_env hsc_src keep_rn_syntax mod loc do_this
tcg_th_remote_state = th_remote_state_var,
tcg_mod = mod,
- tcg_semantic_mod =
- canonicalizeModuleIfHome dflags mod,
+ tcg_semantic_mod = homeModuleInstantiation home_unit mod,
tcg_src = hsc_src,
tcg_rdr_env = emptyGlobalRdrEnv,
tcg_fix_env = emptyNameEnv,
@@ -773,7 +773,9 @@ wrapDocLoc doc = do
getPrintUnqualified :: DynFlags -> TcRn PrintUnqualified
getPrintUnqualified dflags
= do { rdr_env <- getGlobalRdrEnv
- ; return $ mkPrintUnqualified dflags rdr_env }
+ ; let unit_state = unitState dflags
+ ; let home_unit = mkHomeUnitFromFlags dflags
+ ; return $ mkPrintUnqualified unit_state home_unit rdr_env }
-- | Like logInfoTcRn, but for user consumption
printForUserTcRn :: SDoc -> TcRn ()
@@ -1937,10 +1939,10 @@ initIfaceTcRn thing_inside
= do { tcg_env <- getGblEnv
; dflags <- getDynFlags
; let !mod = tcg_semantic_mod tcg_env
+ home_unit = mkHomeUnitFromFlags dflags
-- When we are instantiating a signature, we DEFINITELY
-- do not want to knot tie.
- is_instantiate = homeUnitIsDefinite dflags &&
- not (null (homeUnitInstantiations dflags))
+ is_instantiate = isHomeUnitInstantiating home_unit
; let { if_env = IfGblEnv {
if_doc = text "initIfaceTcRn",
if_rec_types =
diff --git a/compiler/GHC/Types/Name.hs b/compiler/GHC/Types/Name.hs
index 4a03a5bfc9..6cdf6513d6 100644
--- a/compiler/GHC/Types/Name.hs
+++ b/compiler/GHC/Types/Name.hs
@@ -87,6 +87,7 @@ import {-# SOURCE #-} GHC.Core.TyCo.Rep( TyThing )
import GHC.Platform
import GHC.Types.Name.Occurrence
import GHC.Unit.Module
+import GHC.Unit.Home
import GHC.Types.SrcLoc
import GHC.Types.Unique
import GHC.Utils.Misc
@@ -338,10 +339,10 @@ nameIsHomePackageImport this_mod
-- | Returns True if the Name comes from some other package: neither this
-- package nor the interactive package.
-nameIsFromExternalPackage :: Unit -> Name -> Bool
-nameIsFromExternalPackage this_unit name
+nameIsFromExternalPackage :: HomeUnit -> Name -> Bool
+nameIsFromExternalPackage home_unit name
| Just mod <- nameModule_maybe name
- , moduleUnit mod /= this_unit -- Not the current unit
+ , notHomeModule home_unit mod -- Not the current unit
, not (isInteractiveModule mod) -- Not the 'interactive' package
= True
| otherwise
diff --git a/compiler/GHC/Unit.hs b/compiler/GHC/Unit.hs
index c93866ed35..3c167762f4 100644
--- a/compiler/GHC/Unit.hs
+++ b/compiler/GHC/Unit.hs
@@ -10,6 +10,7 @@ module GHC.Unit
, module GHC.Unit.Parser
, module GHC.Unit.State
, module GHC.Unit.Module
+ , module GHC.Unit.Home
)
where
@@ -18,6 +19,7 @@ import GHC.Unit.Info
import GHC.Unit.Parser
import GHC.Unit.State
import GHC.Unit.Module
+import GHC.Unit.Home
{-
diff --git a/compiler/GHC/Unit/Home.hs b/compiler/GHC/Unit/Home.hs
new file mode 100644
index 0000000000..eceebd81d0
--- /dev/null
+++ b/compiler/GHC/Unit/Home.hs
@@ -0,0 +1,213 @@
+-- | The home unit is the unit (i.e. compiled package) that contains the module
+-- we are compiling/typechecking.
+module GHC.Unit.Home
+ ( GenHomeUnit (..)
+ , HomeUnit
+ , homeUnitId
+ , homeUnitInstantiations
+ , homeUnitInstanceOf
+ , homeUnitInstanceOfMaybe
+ , homeUnitAsUnit
+ , homeUnitMap
+ -- * Predicates
+ , isHomeUnitIndefinite
+ , isHomeUnitDefinite
+ , isHomeUnitInstantiating
+ , isHomeUnit
+ , isHomeUnitId
+ , isHomeUnitInstanceOf
+ , isHomeModule
+ , isHomeInstalledModule
+ , notHomeModule
+ , notHomeModuleMaybe
+ , notHomeInstalledModule
+ , notHomeInstalledModuleMaybe
+ -- * Helpers
+ , mkHomeModule
+ , mkHomeInstalledModule
+ , homeModuleInstantiation
+ , homeModuleNameInstantiation
+ )
+where
+
+import GHC.Prelude
+import GHC.Unit.Types
+import GHC.Unit.Module.Name
+import Data.Maybe
+
+-- | Information about the home unit (i.e., the until that will contain the
+-- modules we are compiling)
+--
+-- The unit identifier of the instantiating units is left open to allow
+-- switching from UnitKey (what is provided by the user) to UnitId (internal
+-- unit identifier) with `homeUnitMap`.
+--
+-- TODO: this isn't implemented yet. UnitKeys are still converted too early into
+-- UnitIds in GHC.Unit.State.readUnitDataBase and wiring of home unit
+-- instantiations is done inplace in DynFlags by
+-- GHC.Unit.State.upd_wired_in_home_instantiations.
+data GenHomeUnit u
+ = DefiniteHomeUnit UnitId (Maybe (u, GenInstantiations u))
+ -- ^ Definite home unit (i.e. that we can compile).
+ --
+ -- Nothing: not an instantiated unit
+ -- Just (i,insts): made definite by instantiating "i" with "insts"
+
+ | IndefiniteHomeUnit UnitId (GenInstantiations u)
+ -- ^ Indefinite home unit (i.e. that we can only typecheck)
+ --
+ -- All the holes are instantiated with fake modules from the Hole unit.
+ -- See Note [Representation of module/name variables] in "GHC.Unit"
+
+type HomeUnit = GenHomeUnit UnitId
+
+-- | Return home unit id
+homeUnitId :: GenHomeUnit u -> UnitId
+homeUnitId (DefiniteHomeUnit u _) = u
+homeUnitId (IndefiniteHomeUnit u _) = u
+
+-- | Return home unit instantiations
+homeUnitInstantiations :: GenHomeUnit u -> GenInstantiations u
+homeUnitInstantiations (DefiniteHomeUnit _ Nothing) = []
+homeUnitInstantiations (DefiniteHomeUnit _ (Just (_,is))) = is
+homeUnitInstantiations (IndefiniteHomeUnit _ is) = is
+
+-- | Return the unit id of the unit that is instantiated by the home unit.
+--
+-- E.g. if home unit = q[A=p:B,...] we return q.
+--
+-- If the home unit is not an instance of another unit, we return its own unit
+-- id (it is an instance of itself if you will).
+homeUnitInstanceOf :: HomeUnit -> UnitId
+homeUnitInstanceOf h = fromMaybe (homeUnitId h) (homeUnitInstanceOfMaybe h)
+
+-- | Return the unit id of the unit that is instantiated by the home unit.
+--
+-- E.g. if home unit = q[A=p:B,...] we return (Just q).
+--
+-- If the home unit is not an instance of another unit, we return Nothing.
+homeUnitInstanceOfMaybe :: GenHomeUnit u -> Maybe u
+homeUnitInstanceOfMaybe (DefiniteHomeUnit _ (Just (u,_))) = Just u
+homeUnitInstanceOfMaybe _ = Nothing
+
+-- | Return the home unit as a normal unit.
+--
+-- We infer from the home unit itself the kind of unit we create:
+-- 1. If the home unit is definite, we must be compiling so we return a real
+-- unit. The definite home unit may be the result of a unit instantiation,
+-- say `p = q[A=r:X]`. In this case we could have returned a virtual unit
+-- `q[A=r:X]` but it's not what the clients of this function expect,
+-- especially because `p` is lost when we do this. The unit id of a virtual
+-- unit is made up internally so `unitId(q[A=r:X])` is not equal to `p`.
+--
+-- 2. If the home unit is indefinite we can only create a virtual unit from
+-- it. It's ok because we must be only typechecking the home unit so we won't
+-- produce any code object that rely on the unit id of this virtual unit.
+homeUnitAsUnit :: HomeUnit -> Unit
+homeUnitAsUnit (DefiniteHomeUnit u _) = RealUnit (Definite u)
+homeUnitAsUnit (IndefiniteHomeUnit u is) = mkVirtUnit (Indefinite u Nothing) is
+
+-- | Map over the unit identifier for instantiating units
+homeUnitMap :: IsUnitId v => (u -> v) -> GenHomeUnit u -> GenHomeUnit v
+homeUnitMap _ (DefiniteHomeUnit u Nothing) = DefiniteHomeUnit u Nothing
+homeUnitMap f (DefiniteHomeUnit u (Just (i,is))) = DefiniteHomeUnit u (Just (f i, mapInstantiations f is))
+homeUnitMap f (IndefiniteHomeUnit u is) = IndefiniteHomeUnit u (mapInstantiations f is)
+
+----------------------------
+-- Predicates
+----------------------------
+
+-- | Test if we are type-checking an indefinite unit
+--
+-- (if it is not, we should never use on-the-fly renaming)
+isHomeUnitIndefinite :: GenHomeUnit u -> Bool
+isHomeUnitIndefinite (DefiniteHomeUnit {}) = False
+isHomeUnitIndefinite (IndefiniteHomeUnit {}) = True
+
+-- | Test if we are compiling a definite unit
+--
+-- (if it is, we should never use on-the-fly renaming)
+isHomeUnitDefinite :: GenHomeUnit u -> Bool
+isHomeUnitDefinite (DefiniteHomeUnit {}) = True
+isHomeUnitDefinite (IndefiniteHomeUnit {}) = False
+
+-- | Test if we are compiling by instantiating a definite unit
+isHomeUnitInstantiating :: GenHomeUnit u -> Bool
+isHomeUnitInstantiating u =
+ isHomeUnitDefinite u && not (null (homeUnitInstantiations u))
+
+-- | Test if the unit is the home unit
+isHomeUnit :: HomeUnit -> Unit -> Bool
+isHomeUnit hu u = u == homeUnitAsUnit hu
+
+-- | Test if the unit-id is the home unit-id
+isHomeUnitId :: GenHomeUnit u -> UnitId -> Bool
+isHomeUnitId hu uid = uid == homeUnitId hu
+
+-- | Test if the home unit is an instance of the given unit-id
+isHomeUnitInstanceOf :: HomeUnit -> UnitId -> Bool
+isHomeUnitInstanceOf hu u = homeUnitInstanceOf hu == u
+
+-- | Test if the module comes from the home unit
+isHomeModule :: HomeUnit -> Module -> Bool
+isHomeModule hu m = isHomeUnit hu (moduleUnit m)
+
+-- | Test if the module comes from the home unit
+isHomeInstalledModule :: GenHomeUnit u -> InstalledModule -> Bool
+isHomeInstalledModule hu m = isHomeUnitId hu (moduleUnit m)
+
+
+-- | Test if a module doesn't come from the given home unit
+notHomeInstalledModule :: GenHomeUnit u -> InstalledModule -> Bool
+notHomeInstalledModule hu m = not (isHomeInstalledModule hu m)
+
+-- | Test if a module doesn't come from the given home unit
+notHomeInstalledModuleMaybe :: Maybe (GenHomeUnit u) -> InstalledModule -> Bool
+notHomeInstalledModuleMaybe mh m = fromMaybe True $ fmap (`notHomeInstalledModule` m) mh
+
+
+-- | Test if a module doesn't come from the given home unit
+notHomeModule :: HomeUnit -> Module -> Bool
+notHomeModule hu m = not (isHomeModule hu m)
+
+-- | Test if a module doesn't come from the given home unit
+notHomeModuleMaybe :: Maybe HomeUnit -> Module -> Bool
+notHomeModuleMaybe mh m = fromMaybe True $ fmap (`notHomeModule` m) mh
+
+----------------------------
+-- helpers
+----------------------------
+
+-- | Make a module in home unit
+mkHomeModule :: HomeUnit -> ModuleName -> Module
+mkHomeModule hu = mkModule (homeUnitAsUnit hu)
+
+-- | Make a module in home unit
+mkHomeInstalledModule :: GenHomeUnit u -> ModuleName -> InstalledModule
+mkHomeInstalledModule hu = mkModule (homeUnitId hu)
+
+-- | Return the module that is used to instantiate the given home module name.
+-- If the ModuleName doesn't refer to a signature, return the actual home
+-- module.
+--
+-- E.g., the instantiating module of @A@ in @p[A=q[]:B]@ is @q[]:B@.
+-- the instantiating module of @A@ in @p@ is @p:A@.
+homeModuleNameInstantiation :: HomeUnit -> ModuleName -> Module
+homeModuleNameInstantiation hu mod_name =
+ case lookup mod_name (homeUnitInstantiations hu) of
+ Nothing -> mkHomeModule hu mod_name
+ Just mod -> mod
+
+-- | Return the module that is used to instantiate the given home module.
+--
+-- If the given module isn't a module hole, return the actual home module.
+--
+-- E.g., the instantiating module of @p:A@ in @p[A=q[]:B]@ is @q[]:B@.
+-- the instantiating module of @r:A@ in @p[A=q[]:B]@ is @r:A@.
+-- the instantiating module of @p:A@ in @p@ is @p:A@.
+-- the instantiating module of @r:A@ in @p@ is @r:A@.
+homeModuleInstantiation :: HomeUnit -> Module -> Module
+homeModuleInstantiation hu mod
+ | isHomeModule hu mod = homeModuleNameInstantiation hu (moduleName mod)
+ | otherwise = mod
+
diff --git a/compiler/GHC/Unit/Info.hs b/compiler/GHC/Unit/Info.hs
index 002fb1b6a9..839344804c 100644
--- a/compiler/GHC/Unit/Info.hs
+++ b/compiler/GHC/Unit/Info.hs
@@ -46,12 +46,6 @@ import GHC.Unit.Ppr
-- Units] in "GHC.Unit"
type GenUnitInfo unit = GenericUnitInfo (Indefinite unit) PackageId PackageName unit ModuleName (GenModule (GenUnit unit))
--- | A unit key in the database
-newtype UnitKey = UnitKey FastString
-
-unitKeyFS :: UnitKey -> FastString
-unitKeyFS (UnitKey fs) = fs
-
-- | Information about an installed unit (units are identified by their database
-- UnitKey)
type UnitKeyInfo = GenUnitInfo UnitKey
@@ -76,21 +70,21 @@ mkUnitKeyInfo = mapGenericUnitInfo
mkModuleName' = mkModuleNameFS . mkFastStringByteString
mkIndefUnitKey' cid = Indefinite (mkUnitKey' cid) Nothing
mkVirtUnitKey' i = case i of
- DbInstUnitId cid insts -> mkGenVirtUnit unitKeyFS (mkIndefUnitKey' cid) (fmap (bimap mkModuleName' mkModule') insts)
+ DbInstUnitId cid insts -> mkVirtUnit (mkIndefUnitKey' cid) (fmap (bimap mkModuleName' mkModule') insts)
DbUnitId uid -> RealUnit (Definite (mkUnitKey' uid))
mkModule' m = case m of
DbModule uid n -> mkModule (mkVirtUnitKey' uid) (mkModuleName' n)
DbModuleVar n -> mkHoleModule (mkModuleName' n)
-- | Map over the unit parameter
-mapUnitInfo :: (u -> v) -> (v -> FastString) -> GenUnitInfo u -> GenUnitInfo v
-mapUnitInfo f gunitFS = mapGenericUnitInfo
+mapUnitInfo :: IsUnitId v => (u -> v) -> GenUnitInfo u -> GenUnitInfo v
+mapUnitInfo f = mapGenericUnitInfo
f -- unit identifier
(fmap f) -- indefinite unit identifier
id -- package identifier
id -- package name
id -- module name
- (fmap (mapGenUnit f gunitFS)) -- instantiating modules
+ (fmap (mapGenUnit f)) -- instantiating modules
-- TODO: there's no need for these to be FastString, as we don't need the uniq
-- feature, but ghc doesn't currently have convenient support for any
diff --git a/compiler/GHC/Unit/Module.hs b/compiler/GHC/Unit/Module.hs
index 6ec97c027a..cb8e6c3fe9 100644
--- a/compiler/GHC/Unit/Module.hs
+++ b/compiler/GHC/Unit/Module.hs
@@ -43,7 +43,6 @@ module GHC.Unit.Module
, moduleIsDefinite
, HasModule(..)
, ContainsModule(..)
- , unitIdEq
, installedModuleEq
) where
@@ -89,10 +88,6 @@ installedModuleEq :: InstalledModule -> Module -> Bool
installedModuleEq imod mod =
fst (getModuleInstantiation mod) == imod
--- | Test if a 'Unit' corresponds to a given 'UnitId',
--- modulo instantiation.
-unitIdEq :: UnitId -> Unit -> Bool
-unitIdEq iuid uid = toUnitId uid == iuid
{-
************************************************************************
diff --git a/compiler/GHC/Unit/State.hs b/compiler/GHC/Unit/State.hs
index db99ffa2ac..123d9a8027 100644
--- a/compiler/GHC/Unit/State.hs
+++ b/compiler/GHC/Unit/State.hs
@@ -71,9 +71,7 @@ module GHC.Unit.State (
-- * Utils
mkIndefUnitId,
updateIndefUnitId,
- unwireUnit,
- homeUnitIsIndefinite,
- homeUnitIsDefinite,
+ unwireUnit
)
where
@@ -82,6 +80,7 @@ where
import GHC.Prelude
import GHC.Platform
+import GHC.Unit.Home
import GHC.Unit.Database
import GHC.Unit.Info
import GHC.Unit.Ppr
@@ -316,6 +315,7 @@ instance Monoid UnitVisibility where
data UnitConfig = UnitConfig
{ unitConfigPlatformArchOS :: !ArchOS -- ^ Platform arch and OS
, unitConfigWays :: !Ways -- ^ Ways to use
+ , unitConfigHomeUnit :: !HomeUnit -- ^ Home unit
, unitConfigProgramName :: !String
-- ^ Name of the compiler (e.g. "GHC", "GHCJS"). Used to fetch environment
-- variables such as "GHC[JS]_PACKAGE_PATH".
@@ -329,11 +329,6 @@ data UnitConfig = UnitConfig
, unitConfigHideAll :: !Bool -- ^ Hide all units by default
, unitConfigHideAllPlugins :: !Bool -- ^ Hide all plugins units by default
- , unitConfigAllowVirtualUnits :: !Bool
- -- ^ Allow the use of virtual units instantiated on-the-fly (see Note
- -- [About units] in GHC.Unit). This should only be used when we are
- -- type-checking an indefinite unit (not producing any code).
-
, unitConfigDBCache :: Maybe [UnitDatabase UnitId]
-- ^ Cache of databases to use, in the order they were specified on the
-- command line (later databases shadow earlier ones).
@@ -349,16 +344,18 @@ data UnitConfig = UnitConfig
initUnitConfig :: DynFlags -> UnitConfig
initUnitConfig dflags =
- let autoLink
+ let home_unit = mkHomeUnitFromFlags dflags
+ autoLink
| not (gopt Opt_AutoLinkPackages dflags) = []
-- By default we add base & rts to the preload units (when they are
-- found in the unit database) except when we are building them
- | otherwise = filter (/= homeUnitId dflags) [baseUnitId, rtsUnitId]
+ | otherwise = filter (not . isHomeUnitId home_unit) [baseUnitId, rtsUnitId]
in UnitConfig
{ unitConfigPlatformArchOS = platformArchOS (targetPlatform dflags)
, unitConfigProgramName = programName dflags
, unitConfigWays = ways dflags
+ , unitConfigHomeUnit = home_unit
, unitConfigGlobalDB = globalPackageDatabasePath dflags
, unitConfigGHCDir = topDir dflags
@@ -369,11 +366,6 @@ initUnitConfig dflags =
, unitConfigHideAll = gopt Opt_HideAllPackages dflags
, unitConfigHideAllPlugins = gopt Opt_HideAllPluginPackages dflags
- -- when the home unit is indefinite, it means we are type-checking it
- -- only (not producing any code). Hence we can use virtual units
- -- instantiated on-the-fly (see Note [About units] in GHC.Unit)
- , unitConfigAllowVirtualUnits = homeUnitIsIndefinite dflags
-
, unitConfigDBCache = unitDatabases dflags
, unitConfigFlagsDB = packageDBFlags dflags
, unitConfigFlagsExposed = packageFlags dflags
@@ -679,7 +671,7 @@ readUnitDatabase printer cfg conf_file = do
conf_file' = dropTrailingPathSeparator conf_file
top_dir = unitConfigGHCDir cfg
pkgroot = takeDirectory conf_file'
- pkg_configs1 = map (mungeUnitInfo top_dir pkgroot . mapUnitInfo (\(UnitKey x) -> UnitId x) unitIdFS . mkUnitKeyInfo)
+ pkg_configs1 = map (mungeUnitInfo top_dir pkgroot . mapUnitInfo (\(UnitKey x) -> UnitId x) . mkUnitKeyInfo)
proto_pkg_configs
--
return $ UnitDatabase conf_file' pkg_configs1
@@ -778,16 +770,6 @@ applyTrustFlag ctx prec_map unusable pkgs flag =
Left ps -> trustFlagErr ctx flag ps
Right (ps,qs) -> return (distrustAllUnits ps ++ qs)
--- | A little utility to tell if the home unit is indefinite
--- (if it is not, we should never use on-the-fly renaming.)
-homeUnitIsIndefinite :: DynFlags -> Bool
-homeUnitIsIndefinite dflags = not (homeUnitIsDefinite dflags)
-
--- | A little utility to tell if the home unit is definite
--- (if it is, we should never use on-the-fly renaming.)
-homeUnitIsDefinite :: DynFlags -> Bool
-homeUnitIsDefinite dflags = unitIsDefinite (homeUnit dflags)
-
applyPackageFlag
:: SDocContext
-> UnitPrecedenceMap
@@ -1128,11 +1110,11 @@ findWiredInUnits printer prec_map pkgs vis_map = do
-- | Some wired units can be used to instantiate the home unit. We need to
-- replace their unit keys with their wired unit ids.
upd_wired_in_home_instantiations :: DynFlags -> DynFlags
-upd_wired_in_home_instantiations dflags = dflags { homeUnitInstantiations = wiredInsts }
+upd_wired_in_home_instantiations dflags = dflags { homeUnitInstantiations_ = wiredInsts }
where
state = unitState dflags
wiringMap = wireMap state
- unwiredInsts = homeUnitInstantiations dflags
+ unwiredInsts = homeUnitInstantiations_ dflags
wiredInsts = map (fmap (upd_wired_in_mod wiringMap)) unwiredInsts
@@ -1647,6 +1629,16 @@ mkUnitState ctx printer cfg = do
return (state, raw_dbs)
+-- | Do we allow the use of virtual units instantiated on-the-fly (see Note
+-- [About units] in GHC.Unit). This should only be true when we are
+-- type-checking an indefinite unit (not producing any code).
+unitConfigAllowVirtualUnits :: UnitConfig -> Bool
+unitConfigAllowVirtualUnits cfg =
+ -- when the home unit is indefinite, it means we are type-checking it only
+ -- (not producing any code). Hence we can use virtual units instantiated
+ -- on-the-fly (see Note [About units] in GHC.Unit)
+ isHomeUnitIndefinite (unitConfigHomeUnit cfg)
+
-- | Given a wired-in 'Unit', "unwire" it into the 'Unit'
-- that it was recorded as in the package database.
unwireUnit :: UnitState -> Unit-> Unit
@@ -1796,27 +1788,31 @@ mkModMap pkg mod = Map.singleton (mkModule pkg mod)
-- use.
-- | Find all the include directories in these and the preload packages
-getUnitIncludePath :: DynFlags -> [UnitId] -> IO [String]
-getUnitIncludePath dflags pkgs =
- collectIncludeDirs `fmap` getPreloadUnitsAnd dflags pkgs
+getUnitIncludePath :: SDocContext -> UnitState -> HomeUnit -> [UnitId] -> IO [String]
+getUnitIncludePath ctx unit_state home_unit pkgs =
+ collectIncludeDirs `fmap` getPreloadUnitsAnd ctx unit_state home_unit pkgs
collectIncludeDirs :: [UnitInfo] -> [FilePath]
collectIncludeDirs ps = ordNub (filter notNull (concatMap unitIncludeDirs ps))
-- | Find all the library paths in these and the preload packages
-getUnitLibraryPath :: DynFlags -> [UnitId] -> IO [String]
-getUnitLibraryPath dflags pkgs =
- collectLibraryPaths dflags `fmap` getPreloadUnitsAnd dflags pkgs
+getUnitLibraryPath :: SDocContext -> UnitState -> HomeUnit -> Ways -> [UnitId] -> IO [String]
+getUnitLibraryPath ctx unit_state home_unit ws pkgs =
+ collectLibraryPaths ws `fmap` getPreloadUnitsAnd ctx unit_state home_unit pkgs
-collectLibraryPaths :: DynFlags -> [UnitInfo] -> [FilePath]
-collectLibraryPaths dflags = ordNub . filter notNull
- . concatMap (libraryDirsForWay dflags)
+collectLibraryPaths :: Ways -> [UnitInfo] -> [FilePath]
+collectLibraryPaths ws = ordNub . filter notNull
+ . concatMap (libraryDirsForWay ws)
-- | Find all the link options in these and the preload packages,
-- returning (package hs lib options, extra library options, other flags)
getUnitLinkOpts :: DynFlags -> [UnitId] -> IO ([String], [String], [String])
getUnitLinkOpts dflags pkgs =
- collectLinkOpts dflags `fmap` getPreloadUnitsAnd dflags pkgs
+ collectLinkOpts dflags `fmap` getPreloadUnitsAnd
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ pkgs
collectLinkOpts :: DynFlags -> [UnitInfo] -> ([String], [String], [String])
collectLinkOpts dflags ps =
@@ -1830,14 +1826,18 @@ collectArchives dflags pc =
filterM doesFileExist [ searchPath </> ("lib" ++ lib ++ ".a")
| searchPath <- searchPaths
, lib <- libs ]
- where searchPaths = ordNub . filter notNull . libraryDirsForWay dflags $ pc
+ where searchPaths = ordNub . filter notNull . libraryDirsForWay (ways dflags) $ pc
libs = packageHsLibs dflags pc ++ unitExtDepLibsSys pc
getLibs :: DynFlags -> [UnitId] -> IO [(String,String)]
getLibs dflags pkgs = do
- ps <- getPreloadUnitsAnd dflags pkgs
+ ps <- getPreloadUnitsAnd
+ (initSDocContext dflags defaultUserStyle)
+ (unitState dflags)
+ (mkHomeUnitFromFlags dflags)
+ pkgs
fmap concat . forM ps $ \p -> do
- let candidates = [ (l </> f, f) | l <- collectLibraryPaths dflags [p]
+ let candidates = [ (l </> f, f) | l <- collectLibraryPaths (ways dflags) [p]
, f <- (\n -> "lib" ++ n ++ ".a") <$> packageHsLibs dflags p ]
filterM (doesFileExist . fst) candidates
@@ -1890,27 +1890,27 @@ packageHsLibs dflags p = map (mkDynName . addSuffix) (unitLibraries p)
| otherwise = '_':t
-- | Either the 'unitLibraryDirs' or 'unitLibraryDynDirs' as appropriate for the way.
-libraryDirsForWay :: DynFlags -> UnitInfo -> [String]
-libraryDirsForWay dflags
- | WayDyn `elem` ways dflags = unitLibraryDynDirs
- | otherwise = unitLibraryDirs
+libraryDirsForWay :: Ways -> UnitInfo -> [String]
+libraryDirsForWay ws
+ | WayDyn `elem` ws = unitLibraryDynDirs
+ | otherwise = unitLibraryDirs
-- | Find all the C-compiler options in these and the preload packages
-getUnitExtraCcOpts :: DynFlags -> [UnitId] -> IO [String]
-getUnitExtraCcOpts dflags pkgs = do
- ps <- getPreloadUnitsAnd dflags pkgs
+getUnitExtraCcOpts :: SDocContext -> UnitState -> HomeUnit -> [UnitId] -> IO [String]
+getUnitExtraCcOpts ctx unit_state home_unit pkgs = do
+ ps <- getPreloadUnitsAnd ctx unit_state home_unit pkgs
return (concatMap unitCcOptions ps)
-- | Find all the package framework paths in these and the preload packages
-getUnitFrameworkPath :: DynFlags -> [UnitId] -> IO [String]
-getUnitFrameworkPath dflags pkgs = do
- ps <- getPreloadUnitsAnd dflags pkgs
+getUnitFrameworkPath :: SDocContext -> UnitState -> HomeUnit -> [UnitId] -> IO [String]
+getUnitFrameworkPath ctx unit_state home_unit pkgs = do
+ ps <- getPreloadUnitsAnd ctx unit_state home_unit pkgs
return (ordNub (filter notNull (concatMap unitExtDepFrameworkDirs ps)))
-- | Find all the package frameworks in these and the preload packages
-getUnitFrameworks :: DynFlags -> [UnitId] -> IO [String]
-getUnitFrameworks dflags pkgs = do
- ps <- getPreloadUnitsAnd dflags pkgs
+getUnitFrameworks :: SDocContext -> UnitState -> HomeUnit -> [UnitId] -> IO [String]
+getUnitFrameworks ctx unit_state home_unit pkgs = do
+ ps <- getPreloadUnitsAnd ctx unit_state home_unit pkgs
return (concatMap unitExtDepFrameworks ps)
-- -----------------------------------------------------------------------------
@@ -2036,27 +2036,24 @@ listVisibleModuleNames state =
map fst (filter visible (Map.toList (moduleNameProvidersMap state)))
where visible (_, ms) = any originVisible (Map.elems ms)
--- | Lookup 'UnitInfo' for every preload unit, for every unit used to
--- instantiate the current unit, and for every unit explicitly passed in the
--- given list of UnitId.
-getPreloadUnitsAnd :: DynFlags -> [UnitId] -> IO [UnitInfo]
-getPreloadUnitsAnd dflags ids0 =
+-- | Lookup 'UnitInfo' for every preload unit from the UnitState, for every unit
+-- used to instantiate the home unit, and for every unit explicitly passed in
+-- the given list of UnitId.
+getPreloadUnitsAnd :: SDocContext -> UnitState -> HomeUnit -> [UnitId] -> IO [UnitInfo]
+getPreloadUnitsAnd ctx unit_state home_unit ids0 =
let
- ids = ids0 ++
- -- An indefinite package will have insts to HOLE,
- -- which is not a real package. Don't look it up.
- -- Fixes #14525
- if homeUnitIsIndefinite dflags
- then []
- else map (toUnitId . moduleUnit . snd)
- (homeUnitInstantiations dflags)
- state = unitState dflags
- pkg_map = unitInfoMap state
- preload = preloadUnits state
- ctx = initSDocContext dflags defaultUserStyle
+ ids = ids0 ++ inst_ids
+ inst_ids
+ -- An indefinite package will have insts to HOLE,
+ -- which is not a real package. Don't look it up.
+ -- Fixes #14525
+ | isHomeUnitIndefinite home_unit = []
+ | otherwise = map (toUnitId . moduleUnit . snd) (homeUnitInstantiations home_unit)
+ pkg_map = unitInfoMap unit_state
+ preload = preloadUnits unit_state
in do
all_pkgs <- throwErr ctx (closeUnitDeps' pkg_map preload (ids `zip` repeat Nothing))
- return (map (unsafeLookupUnitId state) all_pkgs)
+ return (map (unsafeLookupUnitId unit_state) all_pkgs)
throwErr :: SDocContext -> MaybeErr MsgDoc a -> IO a
throwErr ctx m = case m of
@@ -2131,14 +2128,12 @@ lookupUnitPprInfo :: UnitState -> UnitId -> Maybe UnitPprInfo
lookupUnitPprInfo state uid = fmap (mkUnitPprInfo unitIdFS) (lookupUnitId state uid)
-- | Create a IndefUnitId.
-mkIndefUnitId :: UnitState -> FastString -> IndefUnitId
-mkIndefUnitId state raw =
- let uid = UnitId raw
- in Indefinite uid $! lookupUnitPprInfo state uid
+mkIndefUnitId :: UnitState -> UnitId -> IndefUnitId
+mkIndefUnitId state uid = Indefinite uid $! lookupUnitPprInfo state uid
-- | Update component ID details from the database
updateIndefUnitId :: UnitState -> IndefUnitId -> IndefUnitId
-updateIndefUnitId pkgstate uid = mkIndefUnitId pkgstate (unitIdFS (indefUnit uid))
+updateIndefUnitId pkgstate uid = mkIndefUnitId pkgstate (indefUnit uid)
-- -----------------------------------------------------------------------------
diff --git a/compiler/GHC/Unit/State.hs-boot b/compiler/GHC/Unit/State.hs-boot
index a3bc8fa7d6..4107962941 100644
--- a/compiler/GHC/Unit/State.hs-boot
+++ b/compiler/GHC/Unit/State.hs-boot
@@ -7,5 +7,6 @@ data UnitState
data UnitDatabase unit
emptyUnitState :: UnitState
+mkIndefUnitId :: UnitState -> UnitId -> IndefUnitId
pprUnitIdForUser :: UnitState -> UnitId -> SDoc
updateIndefUnitId :: UnitState -> IndefUnitId -> IndefUnitId
diff --git a/compiler/GHC/Unit/Types.hs b/compiler/GHC/Unit/Types.hs
index c8847c8215..c402461630 100644
--- a/compiler/GHC/Unit/Types.hs
+++ b/compiler/GHC/Unit/Types.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveTraversable #-}
@@ -20,21 +19,22 @@ module GHC.Unit.Types
, moduleFreeHoles
-- * Units
+ , IsUnitId
, GenUnit (..)
, Unit
, UnitId (..)
+ , UnitKey (..)
, GenInstantiatedUnit (..)
, InstantiatedUnit
, IndefUnitId
, DefUnitId
, Instantiations
, GenInstantiations
- , mkGenInstantiatedUnit
, mkInstantiatedUnit
, mkInstantiatedUnitHash
- , mkGenVirtUnit
, mkVirtUnit
, mapGenUnit
+ , mapInstantiations
, unitFreeModuleHoles
, fsToUnit
, unitFS
@@ -44,6 +44,7 @@ module GHC.Unit.Types
, stringToUnit
, stableUnitCmp
, unitIsDefinite
+ , isHoleUnit
-- * Unit Ids
, unitIdString
@@ -166,6 +167,30 @@ instance Outputable InstantiatedUnit where
cid = instUnitInstanceOf uid
insts = instUnitInsts uid
+-- | Class for types that are used as unit identifiers (UnitKey, UnitId, Unit)
+--
+-- We need this class because we create new unit ids for virtual units (see
+-- VirtUnit) and they have to to be made from units with different kinds of
+-- identifiers.
+class IsUnitId u where
+ unitFS :: u -> FastString
+
+instance IsUnitId UnitKey where
+ unitFS (UnitKey fs) = fs
+
+instance IsUnitId UnitId where
+ unitFS (UnitId fs) = fs
+
+instance IsUnitId u => IsUnitId (GenUnit u) where
+ unitFS (VirtUnit x) = instUnitFS x
+ unitFS (RealUnit (Definite x)) = unitFS x
+ unitFS HoleUnit = holeFS
+
+instance IsUnitId u => IsUnitId (Definite u) where
+ unitFS (Definite x) = unitFS x
+
+instance IsUnitId u => IsUnitId (Indefinite u) where
+ unitFS (Indefinite x _) = unitFS x
pprModule :: Module -> SDoc
pprModule mod@(Module p n) = getPprStyle doc
@@ -192,6 +217,9 @@ pprInstantiatedModule (Module uid m) =
-- UNITS
---------------------------------------------------------------------
+-- | A unit key in the database
+newtype UnitKey = UnitKey FastString
+
-- | A unit identifier identifies a (possibly partially) instantiated library.
-- It is primarily used as part of 'Module', which in turn is used in 'Name',
-- which is used to give names to entities when typechecking.
@@ -261,6 +289,10 @@ holeUnique = getUnique holeFS
holeFS :: FastString
holeFS = fsLit "<hole>"
+isHoleUnit :: GenUnit u -> Bool
+isHoleUnit HoleUnit = True
+isHoleUnit _ = False
+
instance Eq (GenInstantiatedUnit unit) where
u1 == u2 = instUnitKey u1 == instUnitKey u2
@@ -284,10 +316,10 @@ instance Binary InstantiatedUnit where
instUnitKey = getUnique fs
}
-instance Eq Unit where
+instance IsUnitId u => Eq (GenUnit u) where
uid1 == uid2 = unitUnique uid1 == unitUnique uid2
-instance Uniquable Unit where
+instance IsUnitId u => Uniquable (GenUnit u) where
getUnique = unitUnique
instance Ord Unit where
@@ -357,8 +389,8 @@ moduleFreeHoles (Module u _ ) = unitFreeModuleHoles u
-- | Create a new 'GenInstantiatedUnit' given an explicit module substitution.
-mkGenInstantiatedUnit :: (unit -> FastString) -> Indefinite unit -> GenInstantiations unit -> GenInstantiatedUnit unit
-mkGenInstantiatedUnit gunitFS cid insts =
+mkInstantiatedUnit :: IsUnitId u => Indefinite u -> GenInstantiations u -> GenInstantiatedUnit u
+mkInstantiatedUnit cid insts =
InstantiatedUnit {
instUnitInstanceOf = cid,
instUnitInsts = sorted_insts,
@@ -367,22 +399,14 @@ mkGenInstantiatedUnit gunitFS cid insts =
instUnitKey = getUnique fs
}
where
- fs = mkGenInstantiatedUnitHash gunitFS cid sorted_insts
+ fs = mkInstantiatedUnitHash cid sorted_insts
sorted_insts = sortBy (stableModuleNameCmp `on` fst) insts
--- | Create a new 'InstantiatedUnit' given an explicit module substitution.
-mkInstantiatedUnit :: IndefUnitId -> Instantiations -> InstantiatedUnit
-mkInstantiatedUnit = mkGenInstantiatedUnit unitIdFS
-
-- | Smart constructor for instantiated GenUnit
-mkGenVirtUnit :: (unit -> FastString) -> Indefinite unit -> [(ModuleName, GenModule (GenUnit unit))] -> GenUnit unit
-mkGenVirtUnit _gunitFS uid [] = RealUnit $ Definite (indefUnit uid) -- huh? indefinite unit without any instantiation/hole?
-mkGenVirtUnit gunitFS uid insts = VirtUnit $ mkGenInstantiatedUnit gunitFS uid insts
-
--- | Smart constructor for VirtUnit
-mkVirtUnit :: IndefUnitId -> Instantiations -> Unit
-mkVirtUnit = mkGenVirtUnit unitIdFS
+mkVirtUnit :: IsUnitId u => Indefinite u -> [(ModuleName, GenModule (GenUnit u))] -> GenUnit u
+mkVirtUnit uid [] = RealUnit $ Definite (indefUnit uid) -- huh? indefinite unit without any instantiation/hole?
+mkVirtUnit uid insts = VirtUnit $ mkInstantiatedUnit uid insts
-- | Generate a uniquely identifying hash (internal unit-id) for an instantiated
-- unit.
@@ -392,24 +416,21 @@ mkVirtUnit = mkGenVirtUnit unitIdFS
-- This hash is completely internal to GHC and is not used for symbol names or
-- file paths. It is different from the hash Cabal would produce for the same
-- instantiated unit.
-mkGenInstantiatedUnitHash :: (unit -> FastString) -> Indefinite unit -> [(ModuleName, GenModule (GenUnit unit))] -> FastString
-mkGenInstantiatedUnitHash gunitFS cid sorted_holes =
+mkInstantiatedUnitHash :: IsUnitId u => Indefinite u -> [(ModuleName, GenModule (GenUnit u))] -> FastString
+mkInstantiatedUnitHash cid sorted_holes =
mkFastStringByteString
- . fingerprintUnitId (bytesFS (gunitFS (indefUnit cid)))
- $ hashInstantiations gunitFS sorted_holes
-
-mkInstantiatedUnitHash :: IndefUnitId -> Instantiations -> FastString
-mkInstantiatedUnitHash = mkGenInstantiatedUnitHash unitIdFS
+ . fingerprintUnitId (bytesFS (unitFS cid))
+ $ hashInstantiations sorted_holes
-- | Generate a hash for a sorted module instantiation.
-hashInstantiations :: (unit -> FastString) -> [(ModuleName, GenModule (GenUnit unit))] -> Fingerprint
-hashInstantiations gunitFS sorted_holes =
+hashInstantiations :: IsUnitId u => [(ModuleName, GenModule (GenUnit u))] -> Fingerprint
+hashInstantiations sorted_holes =
fingerprintByteString
. BS.concat $ do
(m, b) <- sorted_holes
- [ bytesFS (moduleNameFS m), BS.Char8.singleton ' ',
- bytesFS (genUnitFS gunitFS (moduleUnit b)), BS.Char8.singleton ':',
- bytesFS (moduleNameFS (moduleName b)), BS.Char8.singleton '\n']
+ [ bytesFS (moduleNameFS m), BS.Char8.singleton ' ',
+ bytesFS (unitFS (moduleUnit b)), BS.Char8.singleton ':',
+ bytesFS (moduleNameFS (moduleName b)), BS.Char8.singleton '\n']
fingerprintUnitId :: BS.ByteString -> Fingerprint -> BS.ByteString
fingerprintUnitId prefix (Fingerprint a b)
@@ -419,42 +440,37 @@ fingerprintUnitId prefix (Fingerprint a b)
, BS.Char8.pack (toBase62Padded a)
, BS.Char8.pack (toBase62Padded b) ]
-unitUnique :: Unit -> Unique
+unitUnique :: IsUnitId u => GenUnit u -> Unique
unitUnique (VirtUnit x) = instUnitKey x
-unitUnique (RealUnit (Definite x)) = getUnique x
+unitUnique (RealUnit (Definite x)) = getUnique (unitFS x)
unitUnique HoleUnit = holeUnique
-unitFS :: Unit -> FastString
-unitFS = genUnitFS unitIdFS
-
-genUnitFS :: (unit -> FastString) -> GenUnit unit -> FastString
-genUnitFS _gunitFS (VirtUnit x) = instUnitFS x
-genUnitFS gunitFS (RealUnit (Definite x)) = gunitFS x
-genUnitFS _gunitFS HoleUnit = holeFS
-
-- | Create a new simple unit identifier from a 'FastString'. Internally,
-- this is primarily used to specify wired-in unit identifiers.
fsToUnit :: FastString -> Unit
fsToUnit = RealUnit . Definite . UnitId
-unitString :: Unit -> String
+unitString :: IsUnitId u => u -> String
unitString = unpackFS . unitFS
stringToUnit :: String -> Unit
stringToUnit = fsToUnit . mkFastString
-- | Map over the unit type of a 'GenUnit'
-mapGenUnit :: (u -> v) -> (v -> FastString) -> GenUnit u -> GenUnit v
-mapGenUnit f gunitFS = go
+mapGenUnit :: IsUnitId v => (u -> v) -> GenUnit u -> GenUnit v
+mapGenUnit f = go
where
go gu = case gu of
HoleUnit -> HoleUnit
RealUnit d -> RealUnit (fmap f d)
VirtUnit i ->
- VirtUnit $ mkGenInstantiatedUnit gunitFS
+ VirtUnit $ mkInstantiatedUnit
(fmap f (instUnitInstanceOf i))
(fmap (second (fmap go)) (instUnitInsts i))
+-- | Map over the unit identifier of unit instantiations.
+mapInstantiations :: IsUnitId v => (u -> v) -> GenInstantiations u -> GenInstantiations v
+mapInstantiations f = map (second (fmap (mapGenUnit f)))
-- | Return the UnitId of the Unit. For on-the-fly instantiated units, return
-- the UnitId of the indefinite unit this unit is an instance of.