diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2020-04-11 17:03:18 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-04-30 01:56:56 -0400 |
commit | 8bfb0219587b969d5c8f723c46d433e9493958b4 (patch) | |
tree | 7ed243039324e5a85905985589d7defd91543625 /compiler/GHC/Driver | |
parent | 10d15f1ec4bab4dd6152d87fc66e61658a705eb3 (diff) | |
download | haskell-8bfb0219587b969d5c8f723c46d433e9493958b4.tar.gz |
Unit: split and rename modules
Introduce GHC.Unit.* hierarchy for everything concerning units, packages
and modules.
Update Haddock submodule
Diffstat (limited to 'compiler/GHC/Driver')
-rw-r--r-- | compiler/GHC/Driver/Backpack.hs | 15 | ||||
-rw-r--r-- | compiler/GHC/Driver/Backpack/Syntax.hs | 3 | ||||
-rw-r--r-- | compiler/GHC/Driver/CodeOutput.hs | 3 | ||||
-rw-r--r-- | compiler/GHC/Driver/Finder.hs | 3 | ||||
-rw-r--r-- | compiler/GHC/Driver/Hooks.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Driver/Main.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/Driver/Make.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/Driver/MakeFile.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Driver/Packages.hs | 2188 | ||||
-rw-r--r-- | compiler/GHC/Driver/Packages.hs-boot | 16 | ||||
-rw-r--r-- | compiler/GHC/Driver/Pipeline.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/Driver/Pipeline/Monad.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Driver/Plugins.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Driver/Session.hs | 8 | ||||
-rw-r--r-- | compiler/GHC/Driver/Session.hs-boot | 2 | ||||
-rw-r--r-- | compiler/GHC/Driver/Types.hs | 3 |
16 files changed, 28 insertions, 2233 deletions
diff --git a/compiler/GHC/Driver/Backpack.hs b/compiler/GHC/Driver/Backpack.hs index 8dfada00af..041c63c60d 100644 --- a/compiler/GHC/Driver/Backpack.hs +++ b/compiler/GHC/Driver/Backpack.hs @@ -25,14 +25,13 @@ import GHC.Driver.Backpack.Syntax import GHC.Parser.Annotation import GHC hiding (Failed, Succeeded) -import GHC.Driver.Packages hiding (packageNameMap) import GHC.Parser import GHC.Parser.Lexer import GHC.Driver.Monad import GHC.Driver.Session import GHC.Tc.Utils.Monad import GHC.Tc.Module -import GHC.Types.Module +import GHC.Unit import GHC.Driver.Types import GHC.Data.StringBuffer import GHC.Data.FastString @@ -88,7 +87,7 @@ doBackpack [src_filename] = do -- OK, so we have an LHsUnit PackageName, but we want an -- LHsUnit HsComponentId. So let's rename it. let pkgstate = pkgState dflags - let bkp = renameHsUnits pkgstate (packageNameMap pkgstate pkgname_bkp) pkgname_bkp + let bkp = renameHsUnits pkgstate (bkpPackageNameMap pkgstate pkgname_bkp) pkgname_bkp initBkpM src_filename bkp $ forM_ (zip [1..] bkp) $ \(i, lunit) -> do let comp_name = unLoc (hsunitName (unLoc lunit)) @@ -192,7 +191,7 @@ withBkpSession cid insts deps session_type do_this = do importPaths = [], -- Synthesized the flags packageFlags = packageFlags dflags ++ map (\(uid0, rn) -> - let uid = unwireUnit dflags (improveUnit (getUnitInfoMap dflags) $ renameHoleUnit dflags (listToUFM insts) uid0) + let uid = unwireUnit dflags (improveUnit (unitInfoMap (pkgState dflags)) $ renameHoleUnit (pkgState dflags) (listToUFM insts) uid0) in ExposePackage (showSDoc dflags (text "-unit-id" <+> ppr uid <+> ppr rn)) @@ -260,7 +259,7 @@ buildUnit session cid insts lunit = do -- The compilation dependencies are just the appropriately filled -- in unit IDs which must be compiled before we can compile. let hsubst = listToUFM insts - deps0 = map (renameHoleUnit dflags hsubst) raw_deps + deps0 = map (renameHoleUnit (pkgState dflags) hsubst) raw_deps -- Build dependencies OR make sure they make sense. BUT NOTE, -- we can only check the ones that are fully filled; the rest @@ -273,7 +272,7 @@ buildUnit session cid insts lunit = do dflags <- getDynFlags -- IMPROVE IT - let deps = map (improveUnit (getUnitInfoMap dflags)) deps0 + let deps = map (improveUnit (unitInfoMap (pkgState dflags))) deps0 mb_old_eps <- case session of TcSession -> fmap Just getEpsGhc @@ -562,8 +561,8 @@ unitDefines :: PackageState -> LHsUnit PackageName -> (PackageName, HsComponentI unitDefines pkgstate (L _ HsUnit{ hsunitName = L _ pn@(PackageName fs) }) = (pn, HsComponentId pn (mkIndefUnitId pkgstate fs)) -packageNameMap :: PackageState -> [LHsUnit PackageName] -> PackageNameMap HsComponentId -packageNameMap pkgstate units = Map.fromList (map (unitDefines pkgstate) units) +bkpPackageNameMap :: PackageState -> [LHsUnit PackageName] -> PackageNameMap HsComponentId +bkpPackageNameMap pkgstate units = Map.fromList (map (unitDefines pkgstate) units) renameHsUnits :: PackageState -> PackageNameMap HsComponentId -> [LHsUnit PackageName] -> [LHsUnit HsComponentId] renameHsUnits pkgstate m units = map (fmap renameHsUnit) units diff --git a/compiler/GHC/Driver/Backpack/Syntax.hs b/compiler/GHC/Driver/Backpack/Syntax.hs index e579fe42a1..d4d36b59b2 100644 --- a/compiler/GHC/Driver/Backpack/Syntax.hs +++ b/compiler/GHC/Driver/Backpack/Syntax.hs @@ -22,8 +22,7 @@ import GHC.Driver.Phases import GHC.Hs import GHC.Types.SrcLoc import GHC.Utils.Outputable -import GHC.Types.Module -import GHC.Unit.Info +import GHC.Unit {- ************************************************************************ diff --git a/compiler/GHC/Driver/CodeOutput.hs b/compiler/GHC/Driver/CodeOutput.hs index 446deb2c99..bc29a4a654 100644 --- a/compiler/GHC/Driver/CodeOutput.hs +++ b/compiler/GHC/Driver/CodeOutput.hs @@ -25,7 +25,6 @@ import GHC.Types.Unique.Supply ( mkSplitUniqSupply ) import GHC.Driver.Finder ( mkStubPaths ) import GHC.CmmToC ( writeC ) import GHC.Cmm.Lint ( cmmLint ) -import GHC.Driver.Packages import GHC.Cmm ( RawCmmGroup ) import GHC.Cmm.CLabel import GHC.Driver.Types @@ -36,7 +35,7 @@ import GHC.SysTools.FileCleanup import GHC.Utils.Error import GHC.Utils.Outputable -import GHC.Types.Module +import GHC.Unit import GHC.Types.SrcLoc import GHC.Types.CostCentre diff --git a/compiler/GHC/Driver/Finder.hs b/compiler/GHC/Driver/Finder.hs index 1b50d280a6..b5bd91e3cb 100644 --- a/compiler/GHC/Driver/Finder.hs +++ b/compiler/GHC/Driver/Finder.hs @@ -36,9 +36,8 @@ module GHC.Driver.Finder ( import GHC.Prelude -import GHC.Types.Module +import GHC.Unit import GHC.Driver.Types -import GHC.Driver.Packages import GHC.Data.FastString import GHC.Utils.Misc import GHC.Builtin.Names ( gHC_PRIM ) diff --git a/compiler/GHC/Driver/Hooks.hs b/compiler/GHC/Driver/Hooks.hs index b7915ed3af..474b30aa77 100644 --- a/compiler/GHC/Driver/Hooks.hs +++ b/compiler/GHC/Driver/Hooks.hs @@ -48,7 +48,7 @@ import GHC.Types.SrcLoc import GHC.Core.Type import System.Process import GHC.Types.Basic -import GHC.Types.Module +import GHC.Unit.Module import GHC.Core.TyCon import GHC.Types.CostCentre import GHC.Stg.Syntax diff --git a/compiler/GHC/Driver/Main.hs b/compiler/GHC/Driver/Main.hs index c62b40cf0d..b2649ff0d3 100644 --- a/compiler/GHC/Driver/Main.hs +++ b/compiler/GHC/Driver/Main.hs @@ -101,8 +101,8 @@ import GHC.Utils.Panic import GHC.Core.ConLike import GHC.Parser.Annotation -import GHC.Types.Module -import GHC.Driver.Packages +import GHC.Unit.Module +import GHC.Unit.State import GHC.Types.Name.Reader import GHC.Hs import GHC.Hs.Dump diff --git a/compiler/GHC/Driver/Make.hs b/compiler/GHC/Driver/Make.hs index 866d1a080b..874bd2b253 100644 --- a/compiler/GHC/Driver/Make.hs +++ b/compiler/GHC/Driver/Make.hs @@ -45,7 +45,7 @@ import GHC.Driver.Finder import GHC.Driver.Monad import GHC.Parser.Header import GHC.Driver.Types -import GHC.Types.Module +import GHC.Unit.Module import GHC.IfaceToCore ( typecheckIface ) import GHC.Tc.Utils.Monad ( initIfaceCheck ) import GHC.Driver.Main @@ -65,7 +65,7 @@ import GHC.Data.StringBuffer import GHC.Types.Unique.FM import GHC.Types.Unique.DSet import GHC.Tc.Utils.Backpack -import GHC.Driver.Packages +import GHC.Unit.State import GHC.Types.Unique.Set import GHC.Utils.Misc import qualified GHC.LanguageExtensions as LangExt diff --git a/compiler/GHC/Driver/MakeFile.hs b/compiler/GHC/Driver/MakeFile.hs index 01af21d461..f0de5b75c8 100644 --- a/compiler/GHC/Driver/MakeFile.hs +++ b/compiler/GHC/Driver/MakeFile.hs @@ -24,7 +24,7 @@ import GHC.Driver.Ways import GHC.Utils.Misc import GHC.Driver.Types import qualified GHC.SysTools as SysTools -import GHC.Types.Module +import GHC.Unit.Module import GHC.Data.Graph.Directed ( SCC(..) ) import GHC.Driver.Finder import GHC.Utils.Outputable diff --git a/compiler/GHC/Driver/Packages.hs b/compiler/GHC/Driver/Packages.hs deleted file mode 100644 index c6dac71e06..0000000000 --- a/compiler/GHC/Driver/Packages.hs +++ /dev/null @@ -1,2188 +0,0 @@ --- (c) The University of Glasgow, 2006 - -{-# LANGUAGE CPP, ScopedTypeVariables, BangPatterns, FlexibleContexts #-} - --- | Package manipulation -module GHC.Driver.Packages ( - module GHC.Unit.Info, - - -- * Reading the package config, and processing cmdline args - PackageState(..), - PackageDatabase (..), - UnitInfoMap, - emptyPackageState, - initPackages, - readPackageDatabases, - readPackageDatabase, - getPackageConfRefs, - resolvePackageDatabase, - listUnitInfoMap, - - -- * Querying the package config - lookupUnit, - lookupUnit', - lookupInstalledPackage, - lookupPackageName, - improveUnit, - searchPackageId, - unsafeGetUnitInfo, - getInstalledPackageDetails, - displayUnitId, - listVisibleModuleNames, - lookupModuleInAllPackages, - lookupModuleWithSuggestions, - lookupPluginModuleWithSuggestions, - LookupResult(..), - ModuleSuggestion(..), - ModuleOrigin(..), - UnusablePackageReason(..), - pprReason, - - -- * Inspecting the set of packages in scope - getPackageIncludePath, - getPackageLibraryPath, - getPackageLinkOpts, - getPackageExtraCcOpts, - getPackageFrameworkPath, - getPackageFrameworks, - getUnitInfoMap, - getPackageState, - getPreloadPackagesAnd, - - collectArchives, - collectIncludeDirs, collectLibraryPaths, collectLinkOpts, - packageHsLibs, getLibs, - - -- * Utils - mkIndefUnitId, - updateIndefUnitId, - unwireUnit, - pprFlag, - pprPackages, - pprPackagesSimple, - pprModuleMap, - isIndefinite, - isDynLinkName - ) -where - -#include "HsVersions.h" - -import GHC.Prelude - -import GHC.PackageDb -import GHC.Unit.Info -import GHC.Driver.Session -import GHC.Driver.Ways -import GHC.Types.Name ( Name, nameModule_maybe ) -import GHC.Types.Unique.FM -import GHC.Types.Unique.DFM -import GHC.Types.Unique.Set -import GHC.Types.Module -import GHC.Utils.Misc -import GHC.Utils.Panic -import GHC.Platform -import GHC.Utils.Outputable as Outputable -import GHC.Data.Maybe - -import System.Environment ( getEnv ) -import GHC.Data.FastString -import GHC.Utils.Error ( debugTraceMsg, MsgDoc, dumpIfSet_dyn, - withTiming, DumpFormat (..) ) -import GHC.Utils.Exception - -import System.Directory -import System.FilePath as FilePath -import Control.Monad -import Data.Graph (stronglyConnComp, SCC(..)) -import Data.Char ( toUpper ) -import Data.List as List -import Data.Map (Map) -import Data.Set (Set) -import Data.Monoid (First(..)) -import qualified Data.Semigroup as Semigroup -import qualified Data.Map as Map -import qualified Data.Map.Strict as MapStrict -import qualified Data.Set as Set - --- --------------------------------------------------------------------------- --- The Package state - --- | Package state is all stored in 'DynFlags', including the details of --- all packages, which packages are exposed, and which modules they --- provide. --- --- The package state is computed by 'initPackages', and kept in DynFlags. --- It is influenced by various package flags: --- --- * @-package <pkg>@ and @-package-id <pkg>@ cause @<pkg>@ to become exposed. --- If @-hide-all-packages@ was not specified, these commands also cause --- all other packages with the same name to become hidden. --- --- * @-hide-package <pkg>@ causes @<pkg>@ to become hidden. --- --- * (there are a few more flags, check below for their semantics) --- --- The package state has the following properties. --- --- * Let @exposedPackages@ be the set of packages thus exposed. --- Let @depExposedPackages@ be the transitive closure from @exposedPackages@ of --- their dependencies. --- --- * When searching for a module from a preload import declaration, --- only the exposed modules in @exposedPackages@ are valid. --- --- * When searching for a module from an implicit import, all modules --- from @depExposedPackages@ are valid. --- --- * When linking in a compilation manager mode, we link in packages the --- program depends on (the compiler knows this list by the --- time it gets to the link step). Also, we link in all packages --- which were mentioned with preload @-package@ flags on the command-line, --- or are a transitive dependency of same, or are \"base\"\/\"rts\". --- The reason for this is that we might need packages which don't --- contain any Haskell modules, and therefore won't be discovered --- by the normal mechanism of dependency tracking. - --- Notes on DLLs --- ~~~~~~~~~~~~~ --- When compiling module A, which imports module B, we need to --- know whether B will be in the same DLL as A. --- If it's in the same DLL, we refer to B_f_closure --- If it isn't, we refer to _imp__B_f_closure --- When compiling A, we record in B's Module value whether it's --- in a different DLL, by setting the DLL flag. - --- | Given a module name, there may be multiple ways it came into scope, --- possibly simultaneously. This data type tracks all the possible ways --- it could have come into scope. Warning: don't use the record functions, --- they're partial! -data ModuleOrigin = - -- | Module is hidden, and thus never will be available for import. - -- (But maybe the user didn't realize), so we'll still keep track - -- of these modules.) - ModHidden - -- | Module is unavailable because the package is unusable. - | ModUnusable UnusablePackageReason - -- | Module is public, and could have come from some places. - | ModOrigin { - -- | @Just False@ means that this module is in - -- someone's @exported-modules@ list, but that package is hidden; - -- @Just True@ means that it is available; @Nothing@ means neither - -- applies. - fromOrigPackage :: Maybe Bool - -- | Is the module available from a reexport of an exposed package? - -- There could be multiple. - , fromExposedReexport :: [UnitInfo] - -- | Is the module available from a reexport of a hidden package? - , fromHiddenReexport :: [UnitInfo] - -- | Did the module export come from a package flag? (ToDo: track - -- more information. - , fromPackageFlag :: Bool - } - -instance Outputable ModuleOrigin where - ppr ModHidden = text "hidden module" - ppr (ModUnusable _) = text "unusable module" - ppr (ModOrigin e res rhs f) = sep (punctuate comma ( - (case e of - Nothing -> [] - Just False -> [text "hidden package"] - Just True -> [text "exposed package"]) ++ - (if null res - then [] - else [text "reexport by" <+> - sep (map (ppr . mkUnit) res)]) ++ - (if null rhs - then [] - else [text "hidden reexport by" <+> - sep (map (ppr . mkUnit) res)]) ++ - (if f then [text "package flag"] else []) - )) - --- | Smart constructor for a module which is in @exposed-modules@. Takes --- as an argument whether or not the defining package is exposed. -fromExposedModules :: Bool -> ModuleOrigin -fromExposedModules e = ModOrigin (Just e) [] [] False - --- | Smart constructor for a module which is in @reexported-modules@. Takes --- as an argument whether or not the reexporting package is exposed, and --- also its 'UnitInfo'. -fromReexportedModules :: Bool -> UnitInfo -> ModuleOrigin -fromReexportedModules True pkg = ModOrigin Nothing [pkg] [] False -fromReexportedModules False pkg = ModOrigin Nothing [] [pkg] False - --- | Smart constructor for a module which was bound by a package flag. -fromFlag :: ModuleOrigin -fromFlag = ModOrigin Nothing [] [] True - -instance Semigroup ModuleOrigin where - ModOrigin e res rhs f <> ModOrigin e' res' rhs' f' = - ModOrigin (g e e') (res ++ res') (rhs ++ rhs') (f || f') - where g (Just b) (Just b') - | b == b' = Just b - | otherwise = panic "ModOrigin: package both exposed/hidden" - g Nothing x = x - g x Nothing = x - _x <> _y = panic "ModOrigin: hidden module redefined" - -instance Monoid ModuleOrigin where - mempty = ModOrigin Nothing [] [] False - mappend = (Semigroup.<>) - --- | Is the name from the import actually visible? (i.e. does it cause --- ambiguity, or is it only relevant when we're making suggestions?) -originVisible :: ModuleOrigin -> Bool -originVisible ModHidden = False -originVisible (ModUnusable _) = False -originVisible (ModOrigin b res _ f) = b == Just True || not (null res) || f - --- | Are there actually no providers for this module? This will never occur --- except when we're filtering based on package imports. -originEmpty :: ModuleOrigin -> Bool -originEmpty (ModOrigin Nothing [] [] False) = True -originEmpty _ = False - --- | Map from 'UnitId' to 'UnitInfo', plus --- the transitive closure of preload units. -data UnitInfoMap = UnitInfoMap - { unUnitInfoMap :: UniqDFM UnitInfo - -- ^ Map from 'UnitId' to 'UnitInfo' - - , preloadClosure :: UniqSet UnitId - -- ^ The set of transitively reachable units according - -- to the explicitly provided command line arguments. - -- A fully instantiated VirtUnit may only be replaced by a RealUnit from - -- this set. - -- See Note [VirtUnit to RealUnit improvement] - } - --- | 'UniqFM' map from 'Unit' to a 'UnitVisibility'. -type VisibilityMap = Map Unit UnitVisibility - --- | 'UnitVisibility' records the various aspects of visibility of a particular --- 'Unit'. -data UnitVisibility = UnitVisibility - { uv_expose_all :: Bool - -- ^ Should all modules in exposed-modules should be dumped into scope? - , uv_renamings :: [(ModuleName, ModuleName)] - -- ^ Any custom renamings that should bring extra 'ModuleName's into - -- scope. - , uv_package_name :: First FastString - -- ^ The package name associated with the 'Unit'. This is used - -- to implement legacy behavior where @-package foo-0.1@ implicitly - -- hides any packages named @foo@ - , uv_requirements :: Map ModuleName (Set InstantiatedModule) - -- ^ The signatures which are contributed to the requirements context - -- from this unit ID. - , uv_explicit :: Bool - -- ^ Whether or not this unit was explicitly brought into scope, - -- as opposed to implicitly via the 'exposed' fields in the - -- package database (when @-hide-all-packages@ is not passed.) - } - -instance Outputable UnitVisibility where - ppr (UnitVisibility { - uv_expose_all = b, - uv_renamings = rns, - uv_package_name = First mb_pn, - uv_requirements = reqs, - uv_explicit = explicit - }) = ppr (b, rns, mb_pn, reqs, explicit) - -instance Semigroup UnitVisibility where - uv1 <> uv2 - = UnitVisibility - { uv_expose_all = uv_expose_all uv1 || uv_expose_all uv2 - , uv_renamings = uv_renamings uv1 ++ uv_renamings uv2 - , uv_package_name = mappend (uv_package_name uv1) (uv_package_name uv2) - , uv_requirements = Map.unionWith Set.union (uv_requirements uv1) (uv_requirements uv2) - , uv_explicit = uv_explicit uv1 || uv_explicit uv2 - } - -instance Monoid UnitVisibility where - mempty = UnitVisibility - { uv_expose_all = False - , uv_renamings = [] - , uv_package_name = First Nothing - , uv_requirements = Map.empty - , uv_explicit = False - } - mappend = (Semigroup.<>) - -type WiredUnitId = DefUnitId -type PreloadUnitId = UnitId - --- | Map from 'ModuleName' to a set of of module providers (i.e. a 'Module' and --- its 'ModuleOrigin'). --- --- NB: the set is in fact a 'Map Module ModuleOrigin', probably to keep only one --- origin for a given 'Module' -type ModuleNameProvidersMap = - Map ModuleName (Map Module ModuleOrigin) - -data PackageState = PackageState { - -- | A mapping of 'Unit' to 'UnitInfo'. This list is adjusted - -- so that only valid packages are here. 'UnitInfo' reflects - -- what was stored *on disk*, except for the 'trusted' flag, which - -- is adjusted at runtime. (In particular, some packages in this map - -- may have the 'exposed' flag be 'False'.) - unitInfoMap :: UnitInfoMap, - - -- | A mapping of 'PackageName' to 'IndefUnitId'. This is used when - -- users refer to packages in Backpack includes. - packageNameMap :: Map PackageName IndefUnitId, - - -- | A mapping from wired in names to the original names from the - -- package database. - unwireMap :: Map WiredUnitId WiredUnitId, - - -- | The packages we're going to link in eagerly. This list - -- should be in reverse dependency order; that is, a package - -- is always mentioned before the packages it depends on. - preloadPackages :: [PreloadUnitId], - - -- | Packages which we explicitly depend on (from a command line flag). - -- We'll use this to generate version macros. - explicitPackages :: [Unit], - - -- | This is a full map from 'ModuleName' to all modules which may possibly - -- be providing it. These providers may be hidden (but we'll still want - -- to report them in error messages), or it may be an ambiguous import. - moduleNameProvidersMap :: !ModuleNameProvidersMap, - - -- | A map, like 'moduleNameProvidersMap', but controlling plugin visibility. - pluginModuleNameProvidersMap :: !ModuleNameProvidersMap, - - -- | A map saying, for each requirement, what interfaces must be merged - -- together when we use them. For example, if our dependencies - -- are @p[A=<A>]@ and @q[A=<A>,B=r[C=<A>]:B]@, then the interfaces - -- to merge for A are @p[A=<A>]:A@, @q[A=<A>,B=r[C=<A>]:B]:A@ - -- and @r[C=<A>]:C@. - -- - -- There's an entry in this map for each hole in our home library. - requirementContext :: Map ModuleName [InstantiatedModule] - } - -emptyPackageState :: PackageState -emptyPackageState = PackageState { - unitInfoMap = emptyUnitInfoMap, - packageNameMap = Map.empty, - unwireMap = Map.empty, - preloadPackages = [], - explicitPackages = [], - moduleNameProvidersMap = Map.empty, - pluginModuleNameProvidersMap = Map.empty, - requirementContext = Map.empty - } - --- | Package database -data PackageDatabase unit = PackageDatabase - { packageDatabasePath :: FilePath - , packageDatabaseUnits :: [GenUnitInfo unit] - } - -type InstalledPackageIndex = Map UnitId UnitInfo - --- | Empty package configuration map -emptyUnitInfoMap :: UnitInfoMap -emptyUnitInfoMap = UnitInfoMap emptyUDFM emptyUniqSet - --- | Find the unit we know about with the given unit id, if any -lookupUnit :: DynFlags -> Unit -> Maybe UnitInfo -lookupUnit dflags = lookupUnit' (isIndefinite dflags) (unitInfoMap (pkgState dflags)) - --- | A more specialized interface, which takes a boolean specifying --- whether or not to look for on-the-fly renamed interfaces, and --- just a 'UnitInfoMap' rather than a 'DynFlags' (so it can --- be used while we're initializing 'DynFlags' -lookupUnit' :: Bool -> UnitInfoMap -> Unit -> Maybe UnitInfo -lookupUnit' False (UnitInfoMap pkg_map _) uid = lookupUDFM pkg_map uid -lookupUnit' True m@(UnitInfoMap pkg_map _) uid = case uid of - HoleUnit -> error "Hole unit" - RealUnit _ -> lookupUDFM pkg_map uid - VirtUnit i -> fmap (renamePackage m (instUnitInsts i)) - (lookupUDFM pkg_map (instUnitInstanceOf i)) - -{- --- | Find the indefinite package for a given 'IndefUnitId'. --- The way this works is just by fiat'ing that every indefinite package's --- unit key is precisely its component ID; and that they share uniques. -lookupIndefUnitId :: PackageState -> IndefUnitId -> Maybe UnitInfo -lookupIndefUnitId pkgstate (IndefUnitId cid_fs) = lookupUDFM pkg_map cid_fs - where - UnitInfoMap pkg_map = unitInfoMap pkgstate --} - --- | Find the package we know about with the given package name (e.g. @foo@), if any --- (NB: there might be a locally defined unit name which overrides this) -lookupPackageName :: PackageState -> PackageName -> Maybe IndefUnitId -lookupPackageName pkgstate n = Map.lookup n (packageNameMap pkgstate) - --- | Search for packages with a given package ID (e.g. \"foo-0.1\") -searchPackageId :: PackageState -> PackageId -> [UnitInfo] -searchPackageId pkgstate pid = filter ((pid ==) . unitPackageId) - (listUnitInfoMap pkgstate) - --- | Extends the package configuration map with a list of package configs. -extendUnitInfoMap - :: UnitInfoMap -> [UnitInfo] -> UnitInfoMap -extendUnitInfoMap (UnitInfoMap pkg_map closure) new_pkgs - = UnitInfoMap (foldl' add pkg_map new_pkgs) closure - -- We also add the expanded version of the mkUnit, so that - -- 'improveUnit' can find it. - where add pkg_map p = addToUDFM (addToUDFM pkg_map (expandedUnitInfoId p) p) - (unitId p) p - --- | Looks up the package with the given id in the package state, panicing if it is --- not found -unsafeGetUnitInfo :: HasDebugCallStack => DynFlags -> Unit -> UnitInfo -unsafeGetUnitInfo dflags pid = - case lookupUnit dflags pid of - Just config -> config - Nothing -> pprPanic "unsafeGetUnitInfo" (ppr pid) - -lookupInstalledPackage :: PackageState -> UnitId -> Maybe UnitInfo -lookupInstalledPackage pkgstate uid = lookupInstalledPackage' (unitInfoMap pkgstate) uid - -lookupInstalledPackage' :: UnitInfoMap -> UnitId -> Maybe UnitInfo -lookupInstalledPackage' (UnitInfoMap db _) uid = lookupUDFM db uid - -getInstalledPackageDetails :: HasDebugCallStack => PackageState -> UnitId -> UnitInfo -getInstalledPackageDetails pkgstate uid = - case lookupInstalledPackage pkgstate uid of - Just config -> config - Nothing -> pprPanic "getInstalledPackageDetails" (ppr uid) - --- | Get a list of entries from the package database. NB: be careful with --- this function, although all packages in this map are "visible", this --- does not imply that the exposed-modules of the package are available --- (they may have been thinned or renamed). -listUnitInfoMap :: PackageState -> [UnitInfo] -listUnitInfoMap pkgstate = eltsUDFM pkg_map - where - UnitInfoMap pkg_map _ = unitInfoMap pkgstate - --- ---------------------------------------------------------------------------- --- Loading the package db files and building up the package state - --- | Read the package database files, and sets up various internal tables of --- package information, according to the package-related flags on the --- command-line (@-package@, @-hide-package@ etc.) --- --- Returns a list of packages to link in if we're doing dynamic linking. --- This list contains the packages that the user explicitly mentioned with --- @-package@ flags. --- --- 'initPackages' can be called again subsequently after updating the --- 'packageFlags' field of the 'DynFlags', and it will update the --- 'pkgState' in 'DynFlags' and return a list of packages to --- link in. -initPackages :: DynFlags -> IO (DynFlags, [PreloadUnitId]) -initPackages dflags = withTiming dflags - (text "initializing package database") - forcePkgDb $ do - read_pkg_dbs <- - case pkgDatabase dflags of - Nothing -> readPackageDatabases dflags - Just dbs -> return dbs - - let - distrust_all db = db { packageDatabaseUnits = distrustAllUnits (packageDatabaseUnits db) } - - pkg_dbs - | gopt Opt_DistrustAllPackages dflags = map distrust_all read_pkg_dbs - | otherwise = read_pkg_dbs - - (pkg_state, preload, insts) - <- mkPackageState dflags pkg_dbs [] - return (dflags{ pkgDatabase = Just read_pkg_dbs, - pkgState = pkg_state, - thisUnitIdInsts_ = insts }, - preload) - where - forcePkgDb (dflags, _) = unitInfoMap (pkgState dflags) `seq` () - --- ----------------------------------------------------------------------------- --- Reading the package database(s) - -readPackageDatabases :: DynFlags -> IO [PackageDatabase UnitId] -readPackageDatabases dflags = do - conf_refs <- getPackageConfRefs dflags - confs <- liftM catMaybes $ mapM (resolvePackageDatabase dflags) conf_refs - mapM (readPackageDatabase dflags) confs - - -getPackageConfRefs :: DynFlags -> IO [PkgDbRef] -getPackageConfRefs dflags = do - let system_conf_refs = [UserPkgDb, GlobalPkgDb] - - e_pkg_path <- tryIO (getEnv $ map toUpper (programName dflags) ++ "_PACKAGE_PATH") - let base_conf_refs = case e_pkg_path of - Left _ -> system_conf_refs - Right path - | not (null path) && isSearchPathSeparator (last path) - -> map PkgDbPath (splitSearchPath (init path)) ++ system_conf_refs - | otherwise - -> map PkgDbPath (splitSearchPath path) - - -- Apply the package DB-related flags from the command line to get the - -- final list of package DBs. - -- - -- Notes on ordering: - -- * The list of flags is reversed (later ones first) - -- * We work with the package DB list in "left shadows right" order - -- * and finally reverse it at the end, to get "right shadows left" - -- - return $ reverse (foldr doFlag base_conf_refs (packageDBFlags dflags)) - where - doFlag (PackageDB p) dbs = p : dbs - doFlag NoUserPackageDB dbs = filter isNotUser dbs - doFlag NoGlobalPackageDB dbs = filter isNotGlobal dbs - doFlag ClearPackageDBs _ = [] - - isNotUser UserPkgDb = False - isNotUser _ = True - - isNotGlobal GlobalPkgDb = False - isNotGlobal _ = True - --- | Return the path of a package database from a 'PkgDbRef'. Return 'Nothing' --- when the user database filepath is expected but the latter doesn't exist. --- --- NB: This logic is reimplemented in Cabal, so if you change it, --- make sure you update Cabal. (Or, better yet, dump it in the --- compiler info so Cabal can use the info.) -resolvePackageDatabase :: DynFlags -> PkgDbRef -> IO (Maybe FilePath) -resolvePackageDatabase dflags GlobalPkgDb = return $ Just (globalPackageDatabasePath dflags) -resolvePackageDatabase dflags UserPkgDb = runMaybeT $ do - dir <- versionedAppDir dflags - let pkgconf = dir </> "package.conf.d" - exist <- tryMaybeT $ doesDirectoryExist pkgconf - if exist then return pkgconf else mzero -resolvePackageDatabase _ (PkgDbPath name) = return $ Just name - -readPackageDatabase :: DynFlags -> FilePath -> IO (PackageDatabase UnitId) -readPackageDatabase dflags conf_file = do - isdir <- doesDirectoryExist conf_file - - proto_pkg_configs <- - if isdir - then readDirStyleUnitInfo conf_file - else do - isfile <- doesFileExist conf_file - if isfile - then do - mpkgs <- tryReadOldFileStyleUnitInfo - case mpkgs of - Just pkgs -> return pkgs - Nothing -> throwGhcExceptionIO $ InstallationError $ - "ghc no longer supports single-file style package " ++ - "databases (" ++ conf_file ++ - ") use 'ghc-pkg init' to create the database with " ++ - "the correct format." - else throwGhcExceptionIO $ InstallationError $ - "can't find a package database at " ++ conf_file - - let - -- Fix #16360: remove trailing slash from conf_file before calculating pkgroot - conf_file' = dropTrailingPathSeparator conf_file - top_dir = topDir dflags - pkgroot = takeDirectory conf_file' - pkg_configs1 = map (mungeUnitInfo top_dir pkgroot . mapUnitInfo (\(UnitKey x) -> UnitId x) unitIdFS . mkUnitKeyInfo) - proto_pkg_configs - -- - return $ PackageDatabase conf_file' pkg_configs1 - where - readDirStyleUnitInfo conf_dir = do - let filename = conf_dir </> "package.cache" - cache_exists <- doesFileExist filename - if cache_exists - then do - debugTraceMsg dflags 2 $ text "Using binary package database:" - <+> text filename - readPackageDbForGhc filename - else do - -- If there is no package.cache file, we check if the database is not - -- empty by inspecting if the directory contains any .conf file. If it - -- does, something is wrong and we fail. Otherwise we assume that the - -- database is empty. - debugTraceMsg dflags 2 $ text "There is no package.cache in" - <+> text conf_dir - <> text ", checking if the database is empty" - db_empty <- all (not . isSuffixOf ".conf") - <$> getDirectoryContents conf_dir - if db_empty - then do - debugTraceMsg dflags 3 $ text "There are no .conf files in" - <+> text conf_dir <> text ", treating" - <+> text "package database as empty" - return [] - else do - throwGhcExceptionIO $ InstallationError $ - "there is no package.cache in " ++ conf_dir ++ - " even though package database is not empty" - - - -- Single-file style package dbs have been deprecated for some time, but - -- it turns out that Cabal was using them in one place. So this is a - -- workaround to allow older Cabal versions to use this newer ghc. - -- We check if the file db contains just "[]" and if so, we look for a new - -- dir-style db in conf_file.d/, ie in a dir next to the given file. - -- We cannot just replace the file with a new dir style since Cabal still - -- assumes it's a file and tries to overwrite with 'writeFile'. - -- ghc-pkg also cooperates with this workaround. - tryReadOldFileStyleUnitInfo = do - content <- readFile conf_file `catchIO` \_ -> return "" - if take 2 content == "[]" - then do - let conf_dir = conf_file <.> "d" - direxists <- doesDirectoryExist conf_dir - if direxists - then do debugTraceMsg dflags 2 (text "Ignoring old file-style db and trying:" <+> text conf_dir) - liftM Just (readDirStyleUnitInfo conf_dir) - else return (Just []) -- ghc-pkg will create it when it's updated - else return Nothing - -distrustAllUnits :: [UnitInfo] -> [UnitInfo] -distrustAllUnits pkgs = map distrust pkgs - where - distrust pkg = pkg{ unitIsTrusted = False } - -mungeUnitInfo :: FilePath -> FilePath - -> UnitInfo -> UnitInfo -mungeUnitInfo top_dir pkgroot = - mungeDynLibFields - . mungeUnitInfoPaths top_dir pkgroot - -mungeDynLibFields :: UnitInfo -> UnitInfo -mungeDynLibFields pkg = - pkg { - unitLibraryDynDirs = case unitLibraryDynDirs pkg of - [] -> unitLibraryDirs pkg - ds -> ds - } - --- ----------------------------------------------------------------------------- --- Modify our copy of the package database based on trust flags, --- -trust and -distrust. - -applyTrustFlag - :: DynFlags - -> PackagePrecedenceIndex - -> UnusablePackages - -> [UnitInfo] - -> TrustFlag - -> IO [UnitInfo] -applyTrustFlag dflags prec_map unusable pkgs flag = - case flag of - -- we trust all matching packages. Maybe should only trust first one? - -- and leave others the same or set them untrusted - TrustPackage str -> - case selectPackages prec_map (PackageArg str) pkgs unusable of - Left ps -> trustFlagErr dflags flag ps - Right (ps,qs) -> return (map trust ps ++ qs) - where trust p = p {unitIsTrusted=True} - - DistrustPackage str -> - case selectPackages prec_map (PackageArg str) pkgs unusable of - Left ps -> trustFlagErr dflags flag ps - Right (ps,qs) -> return (distrustAllUnits ps ++ qs) - --- | A little utility to tell if the 'thisPackage' is indefinite --- (if it is not, we should never use on-the-fly renaming.) -isIndefinite :: DynFlags -> Bool -isIndefinite dflags = not (unitIsDefinite (thisPackage dflags)) - -applyPackageFlag - :: DynFlags - -> PackagePrecedenceIndex - -> UnitInfoMap - -> UnusablePackages - -> Bool -- if False, if you expose a package, it implicitly hides - -- any previously exposed packages with the same name - -> [UnitInfo] - -> VisibilityMap -- Initially exposed - -> PackageFlag -- flag to apply - -> IO VisibilityMap -- Now exposed - -applyPackageFlag dflags prec_map pkg_db unusable no_hide_others pkgs vm flag = - case flag of - ExposePackage _ arg (ModRenaming b rns) -> - case findPackages prec_map pkg_db arg pkgs unusable of - Left ps -> packageFlagErr dflags flag ps - Right (p:_) -> return vm' - where - n = fsPackageName p - - -- If a user says @-unit-id p[A=<A>]@, this imposes - -- a requirement on us: whatever our signature A is, - -- it must fulfill all of p[A=<A>]:A's requirements. - -- This method is responsible for computing what our - -- inherited requirements are. - reqs | UnitIdArg orig_uid <- arg = collectHoles orig_uid - | otherwise = Map.empty - - collectHoles uid = case uid of - HoleUnit -> Map.empty - RealUnit {} -> Map.empty -- definite units don't have holes - VirtUnit indef -> - let local = [ Map.singleton - (moduleName mod) - (Set.singleton $ Module indef mod_name) - | (mod_name, mod) <- instUnitInsts indef - , isHoleModule mod ] - recurse = [ collectHoles (moduleUnit mod) - | (_, mod) <- instUnitInsts indef ] - in Map.unionsWith Set.union $ local ++ recurse - - uv = UnitVisibility - { uv_expose_all = b - , uv_renamings = rns - , uv_package_name = First (Just n) - , uv_requirements = reqs - , uv_explicit = True - } - vm' = Map.insertWith mappend (mkUnit p) uv vm_cleared - -- In the old days, if you said `ghc -package p-0.1 -package p-0.2` - -- (or if p-0.1 was registered in the pkgdb as exposed: True), - -- the second package flag would override the first one and you - -- would only see p-0.2 in exposed modules. This is good for - -- usability. - -- - -- However, with thinning and renaming (or Backpack), there might be - -- situations where you legitimately want to see two versions of a - -- package at the same time, and this behavior would make it - -- impossible to do so. So we decided that if you pass - -- -hide-all-packages, this should turn OFF the overriding behavior - -- where an exposed package hides all other packages with the same - -- name. This should not affect Cabal at all, which only ever - -- exposes one package at a time. - -- - -- NB: Why a variable no_hide_others? We have to apply this logic to - -- -plugin-package too, and it's more consistent if the switch in - -- behavior is based off of - -- -hide-all-packages/-hide-all-plugin-packages depending on what - -- flag is in question. - vm_cleared | no_hide_others = vm - -- NB: renamings never clear - | (_:_) <- rns = vm - | otherwise = Map.filterWithKey - (\k uv -> k == mkUnit p - || First (Just n) /= uv_package_name uv) vm - _ -> panic "applyPackageFlag" - - HidePackage str -> - case findPackages prec_map pkg_db (PackageArg str) pkgs unusable of - Left ps -> packageFlagErr dflags flag ps - Right ps -> return vm' - where vm' = foldl' (flip Map.delete) vm (map mkUnit ps) - --- | Like 'selectPackages', but doesn't return a list of unmatched --- packages. Furthermore, any packages it returns are *renamed* --- if the 'UnitArg' has a renaming associated with it. -findPackages :: PackagePrecedenceIndex - -> UnitInfoMap -> PackageArg -> [UnitInfo] - -> UnusablePackages - -> Either [(UnitInfo, UnusablePackageReason)] - [UnitInfo] -findPackages prec_map pkg_db arg pkgs unusable - = let ps = mapMaybe (finder arg) pkgs - in if null ps - then Left (mapMaybe (\(x,y) -> finder arg x >>= \x' -> return (x',y)) - (Map.elems unusable)) - else Right (sortByPreference prec_map ps) - where - finder (PackageArg str) p - = if str == unitPackageIdString p || str == unitPackageNameString p - then Just p - else Nothing - finder (UnitIdArg uid) p - = case uid of - RealUnit (Definite iuid) - | iuid == unitId p - -> Just p - VirtUnit inst - | indefUnit (instUnitInstanceOf inst) == unitId p - -> Just (renamePackage pkg_db (instUnitInsts inst) p) - _ -> Nothing - -selectPackages :: PackagePrecedenceIndex -> PackageArg -> [UnitInfo] - -> UnusablePackages - -> Either [(UnitInfo, UnusablePackageReason)] - ([UnitInfo], [UnitInfo]) -selectPackages prec_map arg pkgs unusable - = let matches = matching arg - (ps,rest) = partition matches pkgs - in if null ps - then Left (filter (matches.fst) (Map.elems unusable)) - else Right (sortByPreference prec_map ps, rest) - --- | Rename a 'UnitInfo' according to some module instantiation. -renamePackage :: UnitInfoMap -> [(ModuleName, Module)] - -> UnitInfo -> UnitInfo -renamePackage pkg_map insts conf = - let hsubst = listToUFM insts - smod = renameHoleModule' pkg_map hsubst - new_insts = map (\(k,v) -> (k,smod v)) (unitInstantiations conf) - in conf { - unitInstantiations = new_insts, - unitExposedModules = map (\(mod_name, mb_mod) -> (mod_name, fmap smod mb_mod)) - (unitExposedModules conf) - } - - --- A package named on the command line can either include the --- version, or just the name if it is unambiguous. -matchingStr :: String -> UnitInfo -> Bool -matchingStr str p - = str == unitPackageIdString p - || str == unitPackageNameString p - -matchingId :: UnitId -> UnitInfo -> Bool -matchingId uid p = uid == unitId p - -matching :: PackageArg -> UnitInfo -> Bool -matching (PackageArg str) = matchingStr str -matching (UnitIdArg (RealUnit (Definite uid))) = matchingId uid -matching (UnitIdArg _) = \_ -> False -- TODO: warn in this case - --- | This sorts a list of packages, putting "preferred" packages first. --- See 'compareByPreference' for the semantics of "preference". -sortByPreference :: PackagePrecedenceIndex -> [UnitInfo] -> [UnitInfo] -sortByPreference prec_map = sortBy (flip (compareByPreference prec_map)) - --- | Returns 'GT' if @pkg@ should be preferred over @pkg'@ when picking --- which should be "active". Here is the order of preference: --- --- 1. First, prefer the latest version --- 2. If the versions are the same, prefer the package that --- came in the latest package database. --- --- Pursuant to #12518, we could change this policy to, for example, remove --- the version preference, meaning that we would always prefer the packages --- in later package database. --- --- Instead, we use that preference based policy only when one of the packages --- is integer-gmp and the other is integer-simple. --- This currently only happens when we're looking up which concrete --- package to use in place of @integer-wired-in@ and that two different --- package databases supply a different integer library. For more about --- the fake @integer-wired-in@ package, see Note [The integer library] --- in the @GHC.Builtin.Names@ module. -compareByPreference - :: PackagePrecedenceIndex - -> UnitInfo - -> UnitInfo - -> Ordering -compareByPreference prec_map pkg pkg' - | Just prec <- Map.lookup (unitId pkg) prec_map - , Just prec' <- Map.lookup (unitId pkg') prec_map - , differentIntegerPkgs pkg pkg' - = compare prec prec' - - | otherwise - = case comparing unitPackageVersion pkg pkg' of - GT -> GT - EQ | Just prec <- Map.lookup (unitId pkg) prec_map - , Just prec' <- Map.lookup (unitId pkg') prec_map - -- Prefer the package from the later DB flag (i.e., higher - -- precedence) - -> compare prec prec' - | otherwise - -> EQ - LT -> LT - - where isIntegerPkg p = unitPackageNameString p `elem` - ["integer-simple", "integer-gmp"] - differentIntegerPkgs p p' = - isIntegerPkg p && isIntegerPkg p' && - (unitPackageName p /= unitPackageName p') - -comparing :: Ord a => (t -> a) -> t -> t -> Ordering -comparing f a b = f a `compare` f b - -packageFlagErr :: DynFlags - -> PackageFlag - -> [(UnitInfo, UnusablePackageReason)] - -> IO a -packageFlagErr dflags flag reasons - = packageFlagErr' dflags (pprFlag flag) reasons - -trustFlagErr :: DynFlags - -> TrustFlag - -> [(UnitInfo, UnusablePackageReason)] - -> IO a -trustFlagErr dflags flag reasons - = packageFlagErr' dflags (pprTrustFlag flag) reasons - -packageFlagErr' :: DynFlags - -> SDoc - -> [(UnitInfo, UnusablePackageReason)] - -> IO a -packageFlagErr' dflags flag_doc reasons - = throwGhcExceptionIO (CmdLineError (showSDoc dflags $ err)) - where err = text "cannot satisfy " <> flag_doc <> - (if null reasons then Outputable.empty else text ": ") $$ - nest 4 (ppr_reasons $$ - text "(use -v for more information)") - ppr_reasons = vcat (map ppr_reason reasons) - ppr_reason (p, reason) = - pprReason (ppr (unitId p) <+> text "is") reason - -pprFlag :: PackageFlag -> SDoc -pprFlag flag = case flag of - HidePackage p -> text "-hide-package " <> text p - ExposePackage doc _ _ -> text doc - -pprTrustFlag :: TrustFlag -> SDoc -pprTrustFlag flag = case flag of - TrustPackage p -> text "-trust " <> text p - DistrustPackage p -> text "-distrust " <> text p - --- ----------------------------------------------------------------------------- --- Wired-in packages --- --- See Note [Wired-in packages] in GHC.Types.Module - -type WiredInUnitId = String -type WiredPackagesMap = Map WiredUnitId WiredUnitId - -wired_in_unitids :: [WiredInUnitId] -wired_in_unitids = map unitString wiredInUnitIds - -findWiredInPackages - :: DynFlags - -> PackagePrecedenceIndex - -> [UnitInfo] -- database - -> VisibilityMap -- info on what packages are visible - -- for wired in selection - -> IO ([UnitInfo], -- package database updated for wired in - WiredPackagesMap) -- map from unit id to wired identity - -findWiredInPackages dflags prec_map pkgs vis_map = do - -- Now we must find our wired-in packages, and rename them to - -- their canonical names (eg. base-1.0 ==> base), as described - -- in Note [Wired-in packages] in GHC.Types.Module - let - matches :: UnitInfo -> WiredInUnitId -> Bool - pc `matches` pid - -- See Note [The integer library] in GHC.Builtin.Names - | pid == unitString integerUnitId - = unitPackageNameString pc `elem` ["integer-gmp", "integer-simple"] - pc `matches` pid = unitPackageNameString pc == pid - - -- find which package corresponds to each wired-in package - -- delete any other packages with the same name - -- update the package and any dependencies to point to the new - -- one. - -- - -- When choosing which package to map to a wired-in package - -- name, we try to pick the latest version of exposed packages. - -- However, if there are no exposed wired in packages available - -- (e.g. -hide-all-packages was used), we can't bail: we *have* - -- to assign a package for the wired-in package: so we try again - -- with hidden packages included to (and pick the latest - -- version). - -- - -- You can also override the default choice by using -ignore-package: - -- this works even when there is no exposed wired in package - -- available. - -- - findWiredInPackage :: [UnitInfo] -> WiredInUnitId - -> IO (Maybe (WiredInUnitId, UnitInfo)) - findWiredInPackage pkgs wired_pkg = - let all_ps = [ p | p <- pkgs, p `matches` wired_pkg ] - all_exposed_ps = - [ p | p <- all_ps - , Map.member (mkUnit p) vis_map ] in - case all_exposed_ps of - [] -> case all_ps of - [] -> notfound - many -> pick (head (sortByPreference prec_map many)) - many -> pick (head (sortByPreference prec_map many)) - where - notfound = do - debugTraceMsg dflags 2 $ - text "wired-in package " - <> text wired_pkg - <> text " not found." - return Nothing - pick :: UnitInfo - -> IO (Maybe (WiredInUnitId, UnitInfo)) - pick pkg = do - debugTraceMsg dflags 2 $ - text "wired-in package " - <> text wired_pkg - <> text " mapped to " - <> ppr (unitId pkg) - return (Just (wired_pkg, pkg)) - - - mb_wired_in_pkgs <- mapM (findWiredInPackage pkgs) wired_in_unitids - let - wired_in_pkgs = catMaybes mb_wired_in_pkgs - pkgstate = pkgState dflags - - -- this is old: we used to assume that if there were - -- multiple versions of wired-in packages installed that - -- they were mutually exclusive. Now we're assuming that - -- you have one "main" version of each wired-in package - -- (the latest version), and the others are backward-compat - -- wrappers that depend on this one. e.g. base-4.0 is the - -- latest, base-3.0 is a compat wrapper depending on base-4.0. - {- - deleteOtherWiredInPackages pkgs = filterOut bad pkgs - where bad p = any (p `matches`) wired_in_unitids - && package p `notElem` map fst wired_in_ids - -} - - wiredInMap :: Map WiredUnitId WiredUnitId - wiredInMap = Map.fromList - [ (key, Definite (stringToUnitId wiredInUnitId)) - | (wiredInUnitId, pkg) <- wired_in_pkgs - , Just key <- pure $ definiteUnitInfoId pkg - ] - - updateWiredInDependencies pkgs = map (upd_deps . upd_pkg) pkgs - where upd_pkg pkg - | Just def_uid <- definiteUnitInfoId pkg - , Just wiredInUnitId <- Map.lookup def_uid wiredInMap - = let fs = unitIdFS (unDefinite wiredInUnitId) - in pkg { - unitId = fsToUnitId fs, - unitInstanceOf = mkIndefUnitId pkgstate fs - } - | otherwise - = pkg - upd_deps pkg = pkg { - -- temporary harmless DefUnitId invariant violation - unitDepends = map (unDefinite . upd_wired_in wiredInMap . Definite) (unitDepends pkg), - unitExposedModules - = map (\(k,v) -> (k, fmap (upd_wired_in_mod wiredInMap) v)) - (unitExposedModules pkg) - } - - - return (updateWiredInDependencies pkgs, wiredInMap) - --- Helper functions for rewiring Module and Unit. These --- rewrite Units of modules in wired-in packages to the form known to the --- compiler, as described in Note [Wired-in packages] in GHC.Types.Module. --- --- For instance, base-4.9.0.0 will be rewritten to just base, to match --- what appears in GHC.Builtin.Names. - -upd_wired_in_mod :: WiredPackagesMap -> Module -> Module -upd_wired_in_mod wiredInMap (Module uid m) = Module (upd_wired_in_uid wiredInMap uid) m - -upd_wired_in_uid :: WiredPackagesMap -> Unit -> Unit -upd_wired_in_uid wiredInMap u = case u of - HoleUnit -> HoleUnit - RealUnit def_uid -> RealUnit (upd_wired_in wiredInMap def_uid) - VirtUnit indef_uid -> - VirtUnit $ mkInstantiatedUnit - (instUnitInstanceOf indef_uid) - (map (\(x,y) -> (x,upd_wired_in_mod wiredInMap y)) (instUnitInsts indef_uid)) - -upd_wired_in :: WiredPackagesMap -> DefUnitId -> DefUnitId -upd_wired_in wiredInMap key - | Just key' <- Map.lookup key wiredInMap = key' - | otherwise = key - -updateVisibilityMap :: WiredPackagesMap -> VisibilityMap -> VisibilityMap -updateVisibilityMap wiredInMap vis_map = foldl' f vis_map (Map.toList wiredInMap) - where f vm (from, to) = case Map.lookup (RealUnit from) vis_map of - Nothing -> vm - Just r -> Map.insert (RealUnit to) r - (Map.delete (RealUnit from) vm) - - --- ---------------------------------------------------------------------------- - --- | The reason why a package is unusable. -data UnusablePackageReason - = -- | We ignored it explicitly using @-ignore-package@. - IgnoredWithFlag - -- | This package transitively depends on a package that was never present - -- in any of the provided databases. - | BrokenDependencies [UnitId] - -- | This package transitively depends on a package involved in a cycle. - -- Note that the list of 'UnitId' reports the direct dependencies - -- of this package that (transitively) depended on the cycle, and not - -- the actual cycle itself (which we report separately at high verbosity.) - | CyclicDependencies [UnitId] - -- | This package transitively depends on a package which was ignored. - | IgnoredDependencies [UnitId] - -- | This package transitively depends on a package which was - -- shadowed by an ABI-incompatible package. - | ShadowedDependencies [UnitId] - -instance Outputable UnusablePackageReason where - ppr IgnoredWithFlag = text "[ignored with flag]" - ppr (BrokenDependencies uids) = brackets (text "broken" <+> ppr uids) - ppr (CyclicDependencies uids) = brackets (text "cyclic" <+> ppr uids) - ppr (IgnoredDependencies uids) = brackets (text "ignored" <+> ppr uids) - ppr (ShadowedDependencies uids) = brackets (text "shadowed" <+> ppr uids) - -type UnusablePackages = Map UnitId - (UnitInfo, UnusablePackageReason) - -pprReason :: SDoc -> UnusablePackageReason -> SDoc -pprReason pref reason = case reason of - IgnoredWithFlag -> - pref <+> text "ignored due to an -ignore-package flag" - BrokenDependencies deps -> - pref <+> text "unusable due to missing dependencies:" $$ - nest 2 (hsep (map ppr deps)) - CyclicDependencies deps -> - pref <+> text "unusable due to cyclic dependencies:" $$ - nest 2 (hsep (map ppr deps)) - IgnoredDependencies deps -> - pref <+> text ("unusable because the -ignore-package flag was used to " ++ - "ignore at least one of its dependencies:") $$ - nest 2 (hsep (map ppr deps)) - ShadowedDependencies deps -> - pref <+> text "unusable due to shadowed dependencies:" $$ - nest 2 (hsep (map ppr deps)) - -reportCycles :: DynFlags -> [SCC UnitInfo] -> IO () -reportCycles dflags sccs = mapM_ report sccs - where - report (AcyclicSCC _) = return () - report (CyclicSCC vs) = - debugTraceMsg dflags 2 $ - text "these packages are involved in a cycle:" $$ - nest 2 (hsep (map (ppr . unitId) vs)) - -reportUnusable :: DynFlags -> UnusablePackages -> IO () -reportUnusable dflags pkgs = mapM_ report (Map.toList pkgs) - where - report (ipid, (_, reason)) = - debugTraceMsg dflags 2 $ - pprReason - (text "package" <+> ppr ipid <+> text "is") reason - --- ---------------------------------------------------------------------------- --- --- Utilities on the database --- - --- | A reverse dependency index, mapping an 'UnitId' to --- the 'UnitId's which have a dependency on it. -type RevIndex = Map UnitId [UnitId] - --- | Compute the reverse dependency index of a package database. -reverseDeps :: InstalledPackageIndex -> RevIndex -reverseDeps db = Map.foldl' go Map.empty db - where - go r pkg = foldl' (go' (unitId pkg)) r (unitDepends pkg) - go' from r to = Map.insertWith (++) to [from] r - --- | Given a list of 'UnitId's to remove, a database, --- and a reverse dependency index (as computed by 'reverseDeps'), --- remove those packages, plus any packages which depend on them. --- Returns the pruned database, as well as a list of 'UnitInfo's --- that was removed. -removePackages :: [UnitId] -> RevIndex - -> InstalledPackageIndex - -> (InstalledPackageIndex, [UnitInfo]) -removePackages uids index m = go uids (m,[]) - where - go [] (m,pkgs) = (m,pkgs) - go (uid:uids) (m,pkgs) - | Just pkg <- Map.lookup uid m - = case Map.lookup uid index of - Nothing -> go uids (Map.delete uid m, pkg:pkgs) - Just rdeps -> go (rdeps ++ uids) (Map.delete uid m, pkg:pkgs) - | otherwise - = go uids (m,pkgs) - --- | Given a 'UnitInfo' from some 'InstalledPackageIndex', --- return all entries in 'depends' which correspond to packages --- that do not exist in the index. -depsNotAvailable :: InstalledPackageIndex - -> UnitInfo - -> [UnitId] -depsNotAvailable pkg_map pkg = filter (not . (`Map.member` pkg_map)) (unitDepends pkg) - --- | Given a 'UnitInfo' from some 'InstalledPackageIndex' --- return all entries in 'unitAbiDepends' which correspond to packages --- that do not exist, OR have mismatching ABIs. -depsAbiMismatch :: InstalledPackageIndex - -> UnitInfo - -> [UnitId] -depsAbiMismatch pkg_map pkg = map fst . filter (not . abiMatch) $ unitAbiDepends pkg - where - abiMatch (dep_uid, abi) - | Just dep_pkg <- Map.lookup dep_uid pkg_map - = unitAbiHash dep_pkg == abi - | otherwise - = False - --- ----------------------------------------------------------------------------- --- Ignore packages - -ignorePackages :: [IgnorePackageFlag] -> [UnitInfo] -> UnusablePackages -ignorePackages flags pkgs = Map.fromList (concatMap doit flags) - where - doit (IgnorePackage str) = - case partition (matchingStr str) pkgs of - (ps, _) -> [ (unitId p, (p, IgnoredWithFlag)) - | p <- ps ] - -- missing package is not an error for -ignore-package, - -- because a common usage is to -ignore-package P as - -- a preventative measure just in case P exists. - --- ---------------------------------------------------------------------------- --- --- Merging databases --- - --- | For each package, a mapping from uid -> i indicates that this --- package was brought into GHC by the ith @-package-db@ flag on --- the command line. We use this mapping to make sure we prefer --- packages that were defined later on the command line, if there --- is an ambiguity. -type PackagePrecedenceIndex = Map UnitId Int - --- | Given a list of databases, merge them together, where --- packages with the same unit id in later databases override --- earlier ones. This does NOT check if the resulting database --- makes sense (that's done by 'validateDatabase'). -mergeDatabases :: DynFlags -> [PackageDatabase UnitId] - -> IO (InstalledPackageIndex, PackagePrecedenceIndex) -mergeDatabases dflags = foldM merge (Map.empty, Map.empty) . zip [1..] - where - merge (pkg_map, prec_map) (i, PackageDatabase db_path db) = do - debugTraceMsg dflags 2 $ - text "loading package database" <+> text db_path - forM_ (Set.toList override_set) $ \pkg -> - debugTraceMsg dflags 2 $ - text "package" <+> ppr pkg <+> - text "overrides a previously defined package" - return (pkg_map', prec_map') - where - db_map = mk_pkg_map db - mk_pkg_map = Map.fromList . map (\p -> (unitId p, p)) - - -- The set of UnitIds which appear in both db and pkgs. These are the - -- ones that get overridden. Compute this just to give some - -- helpful debug messages at -v2 - override_set :: Set UnitId - override_set = Set.intersection (Map.keysSet db_map) - (Map.keysSet pkg_map) - - -- Now merge the sets together (NB: in case of duplicate, - -- first argument preferred) - pkg_map' :: InstalledPackageIndex - pkg_map' = Map.union db_map pkg_map - - prec_map' :: PackagePrecedenceIndex - prec_map' = Map.union (Map.map (const i) db_map) prec_map - --- | Validates a database, removing unusable packages from it --- (this includes removing packages that the user has explicitly --- ignored.) Our general strategy: --- --- 1. Remove all broken packages (dangling dependencies) --- 2. Remove all packages that are cyclic --- 3. Apply ignore flags --- 4. Remove all packages which have deps with mismatching ABIs --- -validateDatabase :: DynFlags -> InstalledPackageIndex - -> (InstalledPackageIndex, UnusablePackages, [SCC UnitInfo]) -validateDatabase dflags pkg_map1 = - (pkg_map5, unusable, sccs) - where - ignore_flags = reverse (ignorePackageFlags dflags) - - -- Compute the reverse dependency index - index = reverseDeps pkg_map1 - - -- Helper function - mk_unusable mk_err dep_matcher m uids = - Map.fromList [ (unitId pkg, (pkg, mk_err (dep_matcher m pkg))) - | pkg <- uids ] - - -- Find broken packages - directly_broken = filter (not . null . depsNotAvailable pkg_map1) - (Map.elems pkg_map1) - (pkg_map2, broken) = removePackages (map unitId directly_broken) index pkg_map1 - unusable_broken = mk_unusable BrokenDependencies depsNotAvailable pkg_map2 broken - - -- Find recursive packages - sccs = stronglyConnComp [ (pkg, unitId pkg, unitDepends pkg) - | pkg <- Map.elems pkg_map2 ] - getCyclicSCC (CyclicSCC vs) = map unitId vs - getCyclicSCC (AcyclicSCC _) = [] - (pkg_map3, cyclic) = removePackages (concatMap getCyclicSCC sccs) index pkg_map2 - unusable_cyclic = mk_unusable CyclicDependencies depsNotAvailable pkg_map3 cyclic - - -- Apply ignore flags - directly_ignored = ignorePackages ignore_flags (Map.elems pkg_map3) - (pkg_map4, ignored) = removePackages (Map.keys directly_ignored) index pkg_map3 - unusable_ignored = mk_unusable IgnoredDependencies depsNotAvailable pkg_map4 ignored - - -- Knock out packages whose dependencies don't agree with ABI - -- (i.e., got invalidated due to shadowing) - directly_shadowed = filter (not . null . depsAbiMismatch pkg_map4) - (Map.elems pkg_map4) - (pkg_map5, shadowed) = removePackages (map unitId directly_shadowed) index pkg_map4 - unusable_shadowed = mk_unusable ShadowedDependencies depsAbiMismatch pkg_map5 shadowed - - unusable = directly_ignored `Map.union` unusable_ignored - `Map.union` unusable_broken - `Map.union` unusable_cyclic - `Map.union` unusable_shadowed - --- ----------------------------------------------------------------------------- --- When all the command-line options are in, we can process our package --- settings and populate the package state. - -mkPackageState - :: DynFlags - -- initial databases, in the order they were specified on - -- the command line (later databases shadow earlier ones) - -> [PackageDatabase UnitId] - -> [PreloadUnitId] -- preloaded packages - -> IO (PackageState, - [PreloadUnitId], -- new packages to preload - Maybe [(ModuleName, Module)]) - -mkPackageState dflags dbs preload0 = do -{- - Plan. - - There are two main steps for making the package state: - - 1. We want to build a single, unified package database based - on all of the input databases, which upholds the invariant that - there is only one package per any UnitId and there are no - dangling dependencies. We'll do this by merging, and - then successively filtering out bad dependencies. - - a) Merge all the databases together. - If an input database defines unit ID that is already in - the unified database, that package SHADOWS the existing - package in the current unified database. Note that - order is important: packages defined later in the list of - command line arguments shadow those defined earlier. - - b) Remove all packages with missing dependencies, or - mutually recursive dependencies. - - b) Remove packages selected by -ignore-package from input database - - c) Remove all packages which depended on packages that are now - shadowed by an ABI-incompatible package - - d) report (with -v) any packages that were removed by steps 1-3 - - 2. We want to look at the flags controlling package visibility, - and build a mapping of what module names are in scope and - where they live. - - a) on the final, unified database, we apply -trust/-distrust - flags directly, modifying the database so that the 'trusted' - field has the correct value. - - b) we use the -package/-hide-package flags to compute a - visibility map, stating what packages are "exposed" for - the purposes of computing the module map. - * if any flag refers to a package which was removed by 1-5, then - we can give an error message explaining why - * if -hide-all-packages was not specified, this step also - hides packages which are superseded by later exposed packages - * this step is done TWICE if -plugin-package/-hide-all-plugin-packages - are used - - c) based on the visibility map, we pick wired packages and rewrite - them to have the expected unitId. - - d) finally, using the visibility map and the package database, - we build a mapping saying what every in scope module name points to. --} - - -- This, and the other reverse's that you will see, are due to the fact that - -- packageFlags, pluginPackageFlags, etc. are all specified in *reverse* order - -- than they are on the command line. - let other_flags = reverse (packageFlags dflags) - debugTraceMsg dflags 2 $ - text "package flags" <+> ppr other_flags - - -- Merge databases together, without checking validity - (pkg_map1, prec_map) <- mergeDatabases dflags dbs - - -- Now that we've merged everything together, prune out unusable - -- packages. - let (pkg_map2, unusable, sccs) = validateDatabase dflags pkg_map1 - - reportCycles dflags sccs - reportUnusable dflags unusable - - -- Apply trust flags (these flags apply regardless of whether - -- or not packages are visible or not) - pkgs1 <- foldM (applyTrustFlag dflags prec_map unusable) - (Map.elems pkg_map2) (reverse (trustFlags dflags)) - let prelim_pkg_db = extendUnitInfoMap emptyUnitInfoMap pkgs1 - - -- - -- Calculate the initial set of units from package databases, prior to any package flags. - -- - -- Conceptually, we select the latest versions of all valid (not unusable) *packages* - -- (not units). This is empty if we have -hide-all-packages. - -- - -- Then we create an initial visibility map with default visibilities for all - -- exposed, definite units which belong to the latest valid packages. - -- - let preferLater unit unit' = - case compareByPreference prec_map unit unit' of - GT -> unit - _ -> unit' - addIfMorePreferable m unit = addToUDFM_C preferLater m (fsPackageName unit) unit - -- This is the set of maximally preferable packages. In fact, it is a set of - -- most preferable *units* keyed by package name, which act as stand-ins in - -- for "a package in a database". We use units here because we don't have - -- "a package in a database" as a type currently. - mostPreferablePackageReps = if gopt Opt_HideAllPackages dflags - then emptyUDFM - else foldl' addIfMorePreferable emptyUDFM pkgs1 - -- When exposing units, we want to consider all of those in the most preferable - -- packages. We can implement that by looking for units that are equi-preferable - -- with the most preferable unit for package. Being equi-preferable means that - -- they must be in the same database, with the same version, and the same package name. - -- - -- We must take care to consider all these units and not just the most - -- preferable one, otherwise we can end up with problems like #16228. - mostPreferable u = - case lookupUDFM mostPreferablePackageReps (fsPackageName u) of - Nothing -> False - Just u' -> compareByPreference prec_map u u' == EQ - vis_map1 = foldl' (\vm p -> - -- Note: we NEVER expose indefinite packages by - -- default, because it's almost assuredly not - -- what you want (no mix-in linking has occurred). - if unitIsExposed p && unitIsDefinite (mkUnit p) && mostPreferable p - then Map.insert (mkUnit p) - UnitVisibility { - uv_expose_all = True, - uv_renamings = [], - uv_package_name = First (Just (fsPackageName p)), - uv_requirements = Map.empty, - uv_explicit = False - } - vm - else vm) - Map.empty pkgs1 - - -- - -- Compute a visibility map according to the command-line flags (-package, - -- -hide-package). This needs to know about the unusable packages, since if a - -- user tries to enable an unusable package, we should let them know. - -- - vis_map2 <- foldM (applyPackageFlag dflags prec_map prelim_pkg_db unusable - (gopt Opt_HideAllPackages dflags) pkgs1) - vis_map1 other_flags - - -- - -- Sort out which packages are wired in. This has to be done last, since - -- it modifies the unit ids of wired in packages, but when we process - -- package arguments we need to key against the old versions. - -- - (pkgs2, wired_map) <- findWiredInPackages dflags prec_map pkgs1 vis_map2 - let pkg_db = extendUnitInfoMap emptyUnitInfoMap pkgs2 - - -- Update the visibility map, so we treat wired packages as visible. - let vis_map = updateVisibilityMap wired_map vis_map2 - - let hide_plugin_pkgs = gopt Opt_HideAllPluginPackages dflags - plugin_vis_map <- - case pluginPackageFlags dflags of - -- common case; try to share the old vis_map - [] | not hide_plugin_pkgs -> return vis_map - | otherwise -> return Map.empty - _ -> do let plugin_vis_map1 - | hide_plugin_pkgs = Map.empty - -- Use the vis_map PRIOR to wired in, - -- because otherwise applyPackageFlag - -- won't work. - | otherwise = vis_map2 - plugin_vis_map2 - <- foldM (applyPackageFlag dflags prec_map prelim_pkg_db unusable - (gopt Opt_HideAllPluginPackages dflags) pkgs1) - plugin_vis_map1 - (reverse (pluginPackageFlags dflags)) - -- Updating based on wired in packages is mostly - -- good hygiene, because it won't matter: no wired in - -- package has a compiler plugin. - -- TODO: If a wired in package had a compiler plugin, - -- and you tried to pick different wired in packages - -- with the plugin flags and the normal flags... what - -- would happen? I don't know! But this doesn't seem - -- likely to actually happen. - return (updateVisibilityMap wired_map plugin_vis_map2) - - -- - -- Here we build up a set of the packages mentioned in -package - -- flags on the command line; these are called the "preload" - -- packages. we link these packages in eagerly. The preload set - -- should contain at least rts & base, which is why we pretend that - -- the command line contains -package rts & -package base. - -- - -- NB: preload IS important even for type-checking, because we - -- need the correct include path to be set. - -- - let preload1 = Map.keys (Map.filter uv_explicit vis_map) - - let pkgname_map = foldl' add Map.empty pkgs2 - where add pn_map p - = Map.insert (unitPackageName p) (unitInstanceOf p) pn_map - - -- The explicitPackages accurately reflects the set of packages we have turned - -- on; as such, it also is the only way one can come up with requirements. - -- The requirement context is directly based off of this: we simply - -- look for nested unit IDs that are directly fed holes: the requirements - -- of those units are precisely the ones we need to track - let explicit_pkgs = Map.keys vis_map - req_ctx = Map.map (Set.toList) - $ Map.unionsWith Set.union (map uv_requirements (Map.elems vis_map)) - - - let preload2 = preload1 - - let - -- add base & rts to the preload packages - basicLinkedPackages - | gopt Opt_AutoLinkPackages dflags - = filter (flip elemUDFM (unUnitInfoMap pkg_db)) - [baseUnitId, rtsUnitId] - | otherwise = [] - -- but in any case remove the current package from the set of - -- preloaded packages so that base/rts does not end up in the - -- set up preloaded package when we are just building it - -- (NB: since this is only relevant for base/rts it doesn't matter - -- that thisUnitIdInsts_ is not wired yet) - -- - preload3 = ordNub $ filter (/= thisPackage dflags) - $ (basicLinkedPackages ++ preload2) - - -- Close the preload packages with their dependencies - dep_preload <- closeDeps dflags pkg_db (zip (map toUnitId preload3) (repeat Nothing)) - let new_dep_preload = filter (`notElem` preload0) dep_preload - - let mod_map1 = mkModuleNameProvidersMap dflags pkg_db vis_map - mod_map2 = mkUnusableModuleNameProvidersMap unusable - mod_map = Map.union mod_map1 mod_map2 - - dumpIfSet_dyn (dflags { pprCols = 200 }) Opt_D_dump_mod_map "Mod Map" - FormatText - (pprModuleMap mod_map) - - -- Force pstate to avoid leaking the dflags0 passed to mkPackageState - let !pstate = PackageState{ - preloadPackages = dep_preload, - explicitPackages = explicit_pkgs, - unitInfoMap = pkg_db, - moduleNameProvidersMap = mod_map, - pluginModuleNameProvidersMap = mkModuleNameProvidersMap dflags pkg_db plugin_vis_map, - packageNameMap = pkgname_map, - unwireMap = Map.fromList [ (v,k) | (k,v) <- Map.toList wired_map ], - requirementContext = req_ctx - } - let new_insts = fmap (map (fmap (upd_wired_in_mod wired_map))) (thisUnitIdInsts_ dflags) - return (pstate, new_dep_preload, new_insts) - --- | Given a wired-in 'Unit', "unwire" it into the 'Unit' --- that it was recorded as in the package database. -unwireUnit :: DynFlags -> Unit-> Unit -unwireUnit dflags uid@(RealUnit def_uid) = - maybe uid RealUnit (Map.lookup def_uid (unwireMap (pkgState dflags))) -unwireUnit _ uid = uid - --- ----------------------------------------------------------------------------- --- | Makes the mapping from module to package info - --- Slight irritation: we proceed by leafing through everything --- in the installed package database, which makes handling indefinite --- packages a bit bothersome. - -mkModuleNameProvidersMap - :: DynFlags - -> UnitInfoMap - -> VisibilityMap - -> ModuleNameProvidersMap -mkModuleNameProvidersMap dflags pkg_db vis_map = - -- What should we fold on? Both situations are awkward: - -- - -- * Folding on the visibility map means that we won't create - -- entries for packages that aren't mentioned in vis_map - -- (e.g., hidden packages, causing #14717) - -- - -- * Folding on pkg_db is awkward because if we have an - -- Backpack instantiation, we need to possibly add a - -- package from pkg_db multiple times to the actual - -- ModuleNameProvidersMap. Also, we don't really want - -- definite package instantiations to show up in the - -- list of possibilities. - -- - -- So what will we do instead? We'll extend vis_map with - -- entries for every definite (for non-Backpack) and - -- indefinite (for Backpack) package, so that we get the - -- hidden entries we need. - Map.foldlWithKey extend_modmap emptyMap vis_map_extended - where - vis_map_extended = Map.union vis_map {- preferred -} default_vis - - default_vis = Map.fromList - [ (mkUnit pkg, mempty) - | pkg <- eltsUDFM (unUnitInfoMap pkg_db) - -- Exclude specific instantiations of an indefinite - -- package - , unitIsIndefinite pkg || null (unitInstantiations pkg) - ] - - emptyMap = Map.empty - setOrigins m os = fmap (const os) m - extend_modmap modmap uid - UnitVisibility { uv_expose_all = b, uv_renamings = rns } - = addListTo modmap theBindings - where - pkg = unit_lookup uid - - theBindings :: [(ModuleName, Map Module ModuleOrigin)] - theBindings = newBindings b rns - - newBindings :: Bool - -> [(ModuleName, ModuleName)] - -> [(ModuleName, Map Module ModuleOrigin)] - newBindings e rns = es e ++ hiddens ++ map rnBinding rns - - rnBinding :: (ModuleName, ModuleName) - -> (ModuleName, Map Module ModuleOrigin) - rnBinding (orig, new) = (new, setOrigins origEntry fromFlag) - where origEntry = case lookupUFM esmap orig of - Just r -> r - Nothing -> throwGhcException (CmdLineError (showSDoc dflags - (text "package flag: could not find module name" <+> - ppr orig <+> text "in package" <+> ppr pk))) - - es :: Bool -> [(ModuleName, Map Module ModuleOrigin)] - es e = do - (m, exposedReexport) <- exposed_mods - let (pk', m', origin') = - case exposedReexport of - Nothing -> (pk, m, fromExposedModules e) - Just (Module pk' m') -> - let pkg' = unit_lookup pk' - in (pk', m', fromReexportedModules e pkg') - return (m, mkModMap pk' m' origin') - - esmap :: UniqFM (Map Module ModuleOrigin) - esmap = listToUFM (es False) -- parameter here doesn't matter, orig will - -- be overwritten - - hiddens = [(m, mkModMap pk m ModHidden) | m <- hidden_mods] - - pk = mkUnit pkg - unit_lookup uid = lookupUnit' (isIndefinite dflags) pkg_db uid - `orElse` pprPanic "unit_lookup" (ppr uid) - - exposed_mods = unitExposedModules pkg - hidden_mods = unitHiddenModules pkg - --- | Make a 'ModuleNameProvidersMap' covering a set of unusable packages. -mkUnusableModuleNameProvidersMap :: UnusablePackages -> ModuleNameProvidersMap -mkUnusableModuleNameProvidersMap unusables = - Map.foldl' extend_modmap Map.empty unusables - where - extend_modmap modmap (pkg, reason) = addListTo modmap bindings - where bindings :: [(ModuleName, Map Module ModuleOrigin)] - bindings = exposed ++ hidden - - origin = ModUnusable reason - pkg_id = mkUnit pkg - - exposed = map get_exposed exposed_mods - hidden = [(m, mkModMap pkg_id m origin) | m <- hidden_mods] - - get_exposed (mod, Just mod') = (mod, Map.singleton mod' origin) - get_exposed (mod, _) = (mod, mkModMap pkg_id mod origin) - - exposed_mods = unitExposedModules pkg - hidden_mods = unitHiddenModules pkg - --- | Add a list of key/value pairs to a nested map. --- --- The outer map is processed with 'Data.Map.Strict' to prevent memory leaks --- when reloading modules in GHCi (see #4029). This ensures that each --- value is forced before installing into the map. -addListTo :: (Monoid a, Ord k1, Ord k2) - => Map k1 (Map k2 a) - -> [(k1, Map k2 a)] - -> Map k1 (Map k2 a) -addListTo = foldl' merge - where merge m (k, v) = MapStrict.insertWith (Map.unionWith mappend) k v m - --- | Create a singleton module mapping -mkModMap :: Unit -> ModuleName -> ModuleOrigin -> Map Module ModuleOrigin -mkModMap pkg mod = Map.singleton (mkModule pkg mod) - --- ----------------------------------------------------------------------------- --- Extracting information from the packages in scope - --- Many of these functions take a list of packages: in those cases, --- the list is expected to contain the "dependent packages", --- i.e. those packages that were found to be depended on by the --- current module/program. These can be auto or non-auto packages, it --- doesn't really matter. The list is always combined with the list --- of preload (command-line) packages to determine which packages to --- use. - --- | Find all the include directories in these and the preload packages -getPackageIncludePath :: DynFlags -> [PreloadUnitId] -> IO [String] -getPackageIncludePath dflags pkgs = - collectIncludeDirs `fmap` getPreloadPackagesAnd dflags pkgs - -collectIncludeDirs :: [UnitInfo] -> [FilePath] -collectIncludeDirs ps = ordNub (filter notNull (concatMap unitIncludeDirs ps)) - --- | Find all the library paths in these and the preload packages -getPackageLibraryPath :: DynFlags -> [PreloadUnitId] -> IO [String] -getPackageLibraryPath dflags pkgs = - collectLibraryPaths dflags `fmap` getPreloadPackagesAnd dflags pkgs - -collectLibraryPaths :: DynFlags -> [UnitInfo] -> [FilePath] -collectLibraryPaths dflags = ordNub . filter notNull - . concatMap (libraryDirsForWay dflags) - --- | Find all the link options in these and the preload packages, --- returning (package hs lib options, extra library options, other flags) -getPackageLinkOpts :: DynFlags -> [PreloadUnitId] -> IO ([String], [String], [String]) -getPackageLinkOpts dflags pkgs = - collectLinkOpts dflags `fmap` getPreloadPackagesAnd dflags pkgs - -collectLinkOpts :: DynFlags -> [UnitInfo] -> ([String], [String], [String]) -collectLinkOpts dflags ps = - ( - concatMap (map ("-l" ++) . packageHsLibs dflags) ps, - concatMap (map ("-l" ++) . unitExtDepLibsSys) ps, - concatMap unitLinkerOptions ps - ) -collectArchives :: DynFlags -> UnitInfo -> IO [FilePath] -collectArchives dflags pc = - filterM doesFileExist [ searchPath </> ("lib" ++ lib ++ ".a") - | searchPath <- searchPaths - , lib <- libs ] - where searchPaths = ordNub . filter notNull . libraryDirsForWay dflags $ pc - libs = packageHsLibs dflags pc ++ unitExtDepLibsSys pc - -getLibs :: DynFlags -> [PreloadUnitId] -> IO [(String,String)] -getLibs dflags pkgs = do - ps <- getPreloadPackagesAnd dflags pkgs - fmap concat . forM ps $ \p -> do - let candidates = [ (l </> f, f) | l <- collectLibraryPaths dflags [p] - , f <- (\n -> "lib" ++ n ++ ".a") <$> packageHsLibs dflags p ] - filterM (doesFileExist . fst) candidates - -packageHsLibs :: DynFlags -> UnitInfo -> [String] -packageHsLibs dflags p = map (mkDynName . addSuffix) (unitLibraries p) - where - ways0 = ways dflags - - ways1 = Set.filter (/= WayDyn) ways0 - -- the name of a shared library is libHSfoo-ghc<version>.so - -- we leave out the _dyn, because it is superfluous - - -- debug and profiled RTSs include support for -eventlog - ways2 | WayDebug `Set.member` ways1 || WayProf `Set.member` ways1 - = Set.filter (/= WayEventLog) ways1 - | otherwise - = ways1 - - tag = waysTag (Set.filter (not . wayRTSOnly) ways2) - rts_tag = waysTag ways2 - - mkDynName x - | WayDyn `Set.notMember` ways dflags = x - | "HS" `isPrefixOf` x = - x ++ '-':programName dflags ++ projectVersion dflags - -- For non-Haskell libraries, we use the name "Cfoo". The .a - -- file is libCfoo.a, and the .so is libfoo.so. That way the - -- linker knows what we mean for the vanilla (-lCfoo) and dyn - -- (-lfoo) ways. We therefore need to strip the 'C' off here. - | Just x' <- stripPrefix "C" x = x' - | otherwise - = panic ("Don't understand library name " ++ x) - - -- Add _thr and other rts suffixes to packages named - -- `rts` or `rts-1.0`. Why both? Traditionally the rts - -- package is called `rts` only. However the tooling - -- usually expects a package name to have a version. - -- As such we will gradually move towards the `rts-1.0` - -- package name, at which point the `rts` package name - -- will eventually be unused. - -- - -- This change elevates the need to add custom hooks - -- and handling specifically for the `rts` package for - -- example in ghc-cabal. - addSuffix rts@"HSrts" = rts ++ (expandTag rts_tag) - addSuffix rts@"HSrts-1.0"= rts ++ (expandTag rts_tag) - addSuffix other_lib = other_lib ++ (expandTag tag) - - expandTag t | null t = "" - | 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 - --- | Find all the C-compiler options in these and the preload packages -getPackageExtraCcOpts :: DynFlags -> [PreloadUnitId] -> IO [String] -getPackageExtraCcOpts dflags pkgs = do - ps <- getPreloadPackagesAnd dflags pkgs - return (concatMap unitCcOptions ps) - --- | Find all the package framework paths in these and the preload packages -getPackageFrameworkPath :: DynFlags -> [PreloadUnitId] -> IO [String] -getPackageFrameworkPath dflags pkgs = do - ps <- getPreloadPackagesAnd dflags pkgs - return (ordNub (filter notNull (concatMap unitExtDepFrameworkDirs ps))) - --- | Find all the package frameworks in these and the preload packages -getPackageFrameworks :: DynFlags -> [PreloadUnitId] -> IO [String] -getPackageFrameworks dflags pkgs = do - ps <- getPreloadPackagesAnd dflags pkgs - return (concatMap unitExtDepFrameworks ps) - --- ----------------------------------------------------------------------------- --- Package Utils - --- | Takes a 'ModuleName', and if the module is in any package returns --- list of modules which take that name. -lookupModuleInAllPackages :: DynFlags - -> ModuleName - -> [(Module, UnitInfo)] -lookupModuleInAllPackages dflags m - = case lookupModuleWithSuggestions dflags m Nothing of - LookupFound a b -> [(a,b)] - LookupMultiple rs -> map f rs - where f (m,_) = (m, expectJust "lookupModule" (lookupUnit dflags - (moduleUnit m))) - _ -> [] - --- | The result of performing a lookup -data LookupResult = - -- | Found the module uniquely, nothing else to do - LookupFound Module UnitInfo - -- | Multiple modules with the same name in scope - | LookupMultiple [(Module, ModuleOrigin)] - -- | No modules found, but there were some hidden ones with - -- an exact name match. First is due to package hidden, second - -- is due to module being hidden - | LookupHidden [(Module, ModuleOrigin)] [(Module, ModuleOrigin)] - -- | No modules found, but there were some unusable ones with - -- an exact name match - | LookupUnusable [(Module, ModuleOrigin)] - -- | Nothing found, here are some suggested different names - | LookupNotFound [ModuleSuggestion] -- suggestions - -data ModuleSuggestion = SuggestVisible ModuleName Module ModuleOrigin - | SuggestHidden ModuleName Module ModuleOrigin - -lookupModuleWithSuggestions :: DynFlags - -> ModuleName - -> Maybe FastString - -> LookupResult -lookupModuleWithSuggestions dflags - = lookupModuleWithSuggestions' dflags - (moduleNameProvidersMap (pkgState dflags)) - -lookupPluginModuleWithSuggestions :: DynFlags - -> ModuleName - -> Maybe FastString - -> LookupResult -lookupPluginModuleWithSuggestions dflags - = lookupModuleWithSuggestions' dflags - (pluginModuleNameProvidersMap (pkgState dflags)) - -lookupModuleWithSuggestions' :: DynFlags - -> ModuleNameProvidersMap - -> ModuleName - -> Maybe FastString - -> LookupResult -lookupModuleWithSuggestions' dflags mod_map m mb_pn - = case Map.lookup m mod_map of - Nothing -> LookupNotFound suggestions - Just xs -> - case foldl' classify ([],[],[], []) (Map.toList xs) of - ([], [], [], []) -> LookupNotFound suggestions - (_, _, _, [(m, _)]) -> LookupFound m (mod_unit m) - (_, _, _, exposed@(_:_)) -> LookupMultiple exposed - ([], [], unusable@(_:_), []) -> LookupUnusable unusable - (hidden_pkg, hidden_mod, _, []) -> - LookupHidden hidden_pkg hidden_mod - where - classify (hidden_pkg, hidden_mod, unusable, exposed) (m, origin0) = - let origin = filterOrigin mb_pn (mod_unit m) origin0 - x = (m, origin) - in case origin of - ModHidden - -> (hidden_pkg, x:hidden_mod, unusable, exposed) - ModUnusable _ - -> (hidden_pkg, hidden_mod, x:unusable, exposed) - _ | originEmpty origin - -> (hidden_pkg, hidden_mod, unusable, exposed) - | originVisible origin - -> (hidden_pkg, hidden_mod, unusable, x:exposed) - | otherwise - -> (x:hidden_pkg, hidden_mod, unusable, exposed) - - unit_lookup p = lookupUnit dflags p `orElse` pprPanic "lookupModuleWithSuggestions" (ppr p <+> ppr m) - mod_unit = unit_lookup . moduleUnit - - -- Filters out origins which are not associated with the given package - -- qualifier. No-op if there is no package qualifier. Test if this - -- excluded all origins with 'originEmpty'. - filterOrigin :: Maybe FastString - -> UnitInfo - -> ModuleOrigin - -> ModuleOrigin - filterOrigin Nothing _ o = o - filterOrigin (Just pn) pkg o = - case o of - ModHidden -> if go pkg then ModHidden else mempty - (ModUnusable _) -> if go pkg then o else mempty - ModOrigin { fromOrigPackage = e, fromExposedReexport = res, - fromHiddenReexport = rhs } - -> ModOrigin { - fromOrigPackage = if go pkg then e else Nothing - , fromExposedReexport = filter go res - , fromHiddenReexport = filter go rhs - , fromPackageFlag = False -- always excluded - } - where go pkg = pn == fsPackageName pkg - - suggestions - | gopt Opt_HelpfulErrors dflags = - fuzzyLookup (moduleNameString m) all_mods - | otherwise = [] - - all_mods :: [(String, ModuleSuggestion)] -- All modules - all_mods = sortBy (comparing fst) $ - [ (moduleNameString m, suggestion) - | (m, e) <- Map.toList (moduleNameProvidersMap (pkgState dflags)) - , suggestion <- map (getSuggestion m) (Map.toList e) - ] - getSuggestion name (mod, origin) = - (if originVisible origin then SuggestVisible else SuggestHidden) - name mod origin - -listVisibleModuleNames :: DynFlags -> [ModuleName] -listVisibleModuleNames dflags = - map fst (filter visible (Map.toList (moduleNameProvidersMap (pkgState dflags)))) - where visible (_, ms) = any originVisible (Map.elems ms) - --- | Find all the 'UnitInfo' in both the preload packages from 'DynFlags' and corresponding to the list of --- 'UnitInfo's -getPreloadPackagesAnd :: DynFlags -> [PreloadUnitId] -> IO [UnitInfo] -getPreloadPackagesAnd dflags pkgids0 = - let - pkgids = pkgids0 ++ - -- An indefinite package will have insts to HOLE, - -- which is not a real package. Don't look it up. - -- Fixes #14525 - if isIndefinite dflags - then [] - else map (toUnitId . moduleUnit . snd) - (thisUnitIdInsts dflags) - state = pkgState dflags - pkg_map = unitInfoMap state - preload = preloadPackages state - pairs = zip pkgids (repeat Nothing) - in do - all_pkgs <- throwErr dflags (foldM (add_package dflags pkg_map) preload pairs) - return (map (getInstalledPackageDetails state) all_pkgs) - --- Takes a list of packages, and returns the list with dependencies included, --- in reverse dependency order (a package appears before those it depends on). -closeDeps :: DynFlags - -> UnitInfoMap - -> [(UnitId, Maybe UnitId)] - -> IO [UnitId] -closeDeps dflags pkg_map ps - = throwErr dflags (closeDepsErr dflags pkg_map ps) - -throwErr :: DynFlags -> MaybeErr MsgDoc a -> IO a -throwErr dflags m - = case m of - Failed e -> throwGhcExceptionIO (CmdLineError (showSDoc dflags e)) - Succeeded r -> return r - -closeDepsErr :: DynFlags - -> UnitInfoMap - -> [(UnitId,Maybe UnitId)] - -> MaybeErr MsgDoc [UnitId] -closeDepsErr dflags pkg_map ps = foldM (add_package dflags pkg_map) [] ps - --- internal helper -add_package :: DynFlags - -> UnitInfoMap - -> [PreloadUnitId] - -> (PreloadUnitId,Maybe PreloadUnitId) - -> MaybeErr MsgDoc [PreloadUnitId] -add_package dflags pkg_db ps (p, mb_parent) - | p `elem` ps = return ps -- Check if we've already added this package - | otherwise = - case lookupInstalledPackage' pkg_db p of - Nothing -> Failed (missingPackageMsg p <> - missingDependencyMsg mb_parent) - Just pkg -> do - -- Add the package's dependents also - ps' <- foldM add_unit_key ps (unitDepends pkg) - return (p : ps') - where - add_unit_key ps key - = add_package dflags pkg_db ps (key, Just p) - -missingPackageMsg :: Outputable pkgid => pkgid -> SDoc -missingPackageMsg p = text "unknown package:" <+> ppr p - -missingDependencyMsg :: Maybe UnitId -> SDoc -missingDependencyMsg Nothing = Outputable.empty -missingDependencyMsg (Just parent) - = space <> parens (text "dependency of" <+> ftext (unitIdFS parent)) - --- ----------------------------------------------------------------------------- - --- Cabal packages may contain several components (programs, libraries, etc.). --- As far as GHC is concerned, installed package components ("units") are --- identified by an opaque IndefUnitId string provided by Cabal. As the string --- contains a hash, we don't want to display it to users so GHC queries the --- database to retrieve some infos about the original source package (name, --- version, component name). --- --- Instead we want to display: packagename-version[:componentname] --- --- Component name is only displayed if it isn't the default library --- --- To do this we need to query the database (cached in DynFlags). We cache --- these details in the IndefUnitId itself because we don't want to query --- DynFlags each time we pretty-print the IndefUnitId --- -mkIndefUnitId :: PackageState -> FastString -> IndefUnitId -mkIndefUnitId pkgstate raw = - let uid = UnitId raw - in case lookupInstalledPackage pkgstate uid of - Nothing -> Indefinite uid Nothing -- we didn't find the unit at all - Just c -> Indefinite uid $ Just $ UnitPprInfo - (unitPackageNameString c) - (unitPackageVersion c) - ((unpackFS . unPackageName) <$> unitComponentName c) - --- | Update component ID details from the database -updateIndefUnitId :: PackageState -> IndefUnitId -> IndefUnitId -updateIndefUnitId pkgstate uid = mkIndefUnitId pkgstate (unitIdFS (indefUnit uid)) - - -displayUnitId :: PackageState -> UnitId -> Maybe String -displayUnitId pkgstate uid = - fmap unitPackageIdString (lookupInstalledPackage pkgstate uid) - --- | Will the 'Name' come from a dynamically linked package? -isDynLinkName :: Platform -> Module -> Name -> Bool -isDynLinkName platform this_mod name - | Just mod <- nameModule_maybe name - -- Issue #8696 - when GHC is dynamically linked, it will attempt - -- to load the dynamic dependencies of object files at compile - -- time for things like QuasiQuotes or - -- TemplateHaskell. Unfortunately, this interacts badly with - -- intra-package linking, because we don't generate indirect - -- (dynamic) symbols for intra-package calls. This means that if a - -- module with an intra-package call is loaded without its - -- dependencies, then GHC fails to link. - -- - -- In the mean time, always force dynamic indirections to be - -- generated: when the module name isn't the module being - -- compiled, references are dynamic. - = case platformOS platform of - -- On Windows the hack for #8696 makes it unlinkable. - -- As the entire setup of the code from Cmm down to the RTS expects - -- the use of trampolines for the imported functions only when - -- doing intra-package linking, e.g. referring to a symbol defined in the same - -- package should not use a trampoline. - -- I much rather have dynamic TH not supported than the entire Dynamic linking - -- not due to a hack. - -- Also not sure this would break on Windows anyway. - OSMinGW32 -> moduleUnit mod /= moduleUnit this_mod - - -- For the other platforms, still perform the hack - _ -> mod /= this_mod - - | otherwise = False -- no, it is not even an external name - --- ----------------------------------------------------------------------------- --- Displaying packages - --- | Show (very verbose) package info -pprPackages :: PackageState -> SDoc -pprPackages = pprPackagesWith pprUnitInfo - -pprPackagesWith :: (UnitInfo -> SDoc) -> PackageState -> SDoc -pprPackagesWith pprIPI pkgstate = - vcat (intersperse (text "---") (map pprIPI (listUnitInfoMap pkgstate))) - --- | Show simplified package info. --- --- The idea is to only print package id, and any information that might --- be different from the package databases (exposure, trust) -pprPackagesSimple :: PackageState -> SDoc -pprPackagesSimple = pprPackagesWith pprIPI - where pprIPI ipi = let i = unitIdFS (unitId ipi) - e = if unitIsExposed ipi then text "E" else text " " - t = if unitIsTrusted ipi then text "T" else text " " - in e <> t <> text " " <> ftext i - --- | Show the mapping of modules to where they come from. -pprModuleMap :: ModuleNameProvidersMap -> SDoc -pprModuleMap mod_map = - vcat (map pprLine (Map.toList mod_map)) - where - pprLine (m,e) = ppr m $$ nest 50 (vcat (map (pprEntry m) (Map.toList e))) - pprEntry :: Outputable a => ModuleName -> (Module, a) -> SDoc - pprEntry m (m',o) - | m == moduleName m' = ppr (moduleUnit m') <+> parens (ppr o) - | otherwise = ppr m' <+> parens (ppr o) - -fsPackageName :: UnitInfo -> FastString -fsPackageName info = fs - where - PackageName fs = unitPackageName info - --- | Given a fully instantiated 'InstnatiatedUnit', improve it into a --- 'RealUnit' if we can find it in the package database. -improveUnit :: UnitInfoMap -> Unit -> Unit -improveUnit _ uid@(RealUnit _) = uid -- short circuit -improveUnit pkg_map uid = - -- Do NOT lookup indefinite ones, they won't be useful! - case lookupUnit' False pkg_map uid of - Nothing -> uid - Just pkg -> - -- Do NOT improve if the indefinite unit id is not - -- part of the closure unique set. See - -- Note [VirtUnit to RealUnit improvement] - if unitId pkg `elementOfUniqSet` preloadClosure pkg_map - then mkUnit pkg - else uid - --- | Retrieve the 'UnitInfoMap' from 'DynFlags'; used --- in the @hs-boot@ loop-breaker. -getUnitInfoMap :: DynFlags -> UnitInfoMap -getUnitInfoMap = unitInfoMap . pkgState - --- | Retrieve the 'PackageState' from 'DynFlags'; used --- in the @hs-boot@ loop-breaker. -getPackageState :: DynFlags -> PackageState -getPackageState = pkgState diff --git a/compiler/GHC/Driver/Packages.hs-boot b/compiler/GHC/Driver/Packages.hs-boot deleted file mode 100644 index 368057e2d3..0000000000 --- a/compiler/GHC/Driver/Packages.hs-boot +++ /dev/null @@ -1,16 +0,0 @@ -module GHC.Driver.Packages where -import GHC.Prelude -import GHC.Data.FastString -import {-# SOURCE #-} GHC.Driver.Session (DynFlags) -import {-# SOURCE #-} GHC.Types.Module(IndefUnitId, Unit, UnitId) -data PackageState -data UnitInfoMap -data PackageDatabase unit -emptyPackageState :: PackageState -mkIndefUnitId :: PackageState -> FastString -> IndefUnitId -displayUnitId :: PackageState -> UnitId -> Maybe String -improveUnit :: UnitInfoMap -> Unit -> Unit -getUnitInfoMap :: DynFlags -> UnitInfoMap -unitInfoMap :: PackageState -> UnitInfoMap -getPackageState :: DynFlags -> PackageState -updateIndefUnitId :: PackageState -> IndefUnitId -> IndefUnitId diff --git a/compiler/GHC/Driver/Pipeline.hs b/compiler/GHC/Driver/Pipeline.hs index 6656b2d98a..afcf1bd0bb 100644 --- a/compiler/GHC/Driver/Pipeline.hs +++ b/compiler/GHC/Driver/Pipeline.hs @@ -39,7 +39,7 @@ module GHC.Driver.Pipeline ( import GHC.Prelude import GHC.Driver.Pipeline.Monad -import GHC.Driver.Packages +import GHC.Unit.State import GHC.Driver.Ways import GHC.Parser.Header import GHC.Driver.Phases @@ -49,7 +49,7 @@ import GHC.Driver.Main import GHC.Driver.Finder import GHC.Driver.Types hiding ( Hsc ) import GHC.Utils.Outputable -import GHC.Types.Module +import GHC.Unit.Module import GHC.Utils.Error import GHC.Driver.Session import GHC.Utils.Panic diff --git a/compiler/GHC/Driver/Pipeline/Monad.hs b/compiler/GHC/Driver/Pipeline/Monad.hs index bf22ae6e9d..6ee92328bd 100644 --- a/compiler/GHC/Driver/Pipeline/Monad.hs +++ b/compiler/GHC/Driver/Pipeline/Monad.hs @@ -18,7 +18,7 @@ import GHC.Utils.Outputable import GHC.Driver.Session import GHC.Driver.Phases import GHC.Driver.Types -import GHC.Types.Module +import GHC.Unit.Module import GHC.SysTools.FileCleanup (TempFileLifetime) import Control.Monad diff --git a/compiler/GHC/Driver/Plugins.hs b/compiler/GHC/Driver/Plugins.hs index f10dafda27..61fb9d69fa 100644 --- a/compiler/GHC/Driver/Plugins.hs +++ b/compiler/GHC/Driver/Plugins.hs @@ -58,7 +58,7 @@ import GHC.Driver.Session import GHC.Driver.Types import GHC.Driver.Monad import GHC.Driver.Phases -import GHC.Types.Module +import GHC.Unit.Module import GHC.Utils.Fingerprint import Data.List (sort) import GHC.Utils.Outputable (Outputable(..), text, (<+>)) diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs index 5c39848a8d..ef6de96340 100644 --- a/compiler/GHC/Driver/Session.hs +++ b/compiler/GHC/Driver/Session.hs @@ -242,11 +242,13 @@ import GHC.Prelude import GHC.Platform import GHC.UniqueSubdir (uniqueSubdir) -import GHC.Types.Module +import GHC.Unit.Types +import GHC.Unit.Parser +import GHC.Unit.Module import {-# SOURCE #-} GHC.Driver.Plugins import {-# SOURCE #-} GHC.Driver.Hooks import {-# SOURCE #-} GHC.Builtin.Names ( mAIN ) -import {-# SOURCE #-} GHC.Driver.Packages (PackageState, emptyPackageState, PackageDatabase, mkIndefUnitId, updateIndefUnitId) +import {-# SOURCE #-} GHC.Unit.State (PackageState, emptyPackageState, PackageDatabase, mkIndefUnitId, updateIndefUnitId) import GHC.Driver.Phases ( Phase(..), phaseInputExt ) import GHC.Driver.Flags import GHC.Driver.Ways @@ -630,7 +632,7 @@ data DynFlags = DynFlags { -- ^ Stack of package databases for the target platform. -- -- A "package database" is a misleading name as it is really a Unit - -- database (cf Note [The identifier lexicon]). + -- database (cf Note [About Units]). -- -- This field is populated by `initPackages`. -- diff --git a/compiler/GHC/Driver/Session.hs-boot b/compiler/GHC/Driver/Session.hs-boot index 509535ba71..e35241aec1 100644 --- a/compiler/GHC/Driver/Session.hs-boot +++ b/compiler/GHC/Driver/Session.hs-boot @@ -3,11 +3,13 @@ module GHC.Driver.Session where import GHC.Prelude import GHC.Platform import {-# SOURCE #-} GHC.Utils.Outputable +import {-# SOURCE #-} GHC.Unit.State data DynFlags targetPlatform :: DynFlags -> Platform pprUserLength :: DynFlags -> Int +pkgState :: DynFlags -> PackageState unsafeGlobalDynFlags :: DynFlags hasPprDebug :: DynFlags -> Bool hasNoDebugOutput :: DynFlags -> Bool diff --git a/compiler/GHC/Driver/Types.hs b/compiler/GHC/Driver/Types.hs index 07e7cd7001..12424a48c5 100644 --- a/compiler/GHC/Driver/Types.hs +++ b/compiler/GHC/Driver/Types.hs @@ -170,7 +170,7 @@ import GHC.Types.Unique.FM import GHC.Hs import GHC.Types.Name.Reader import GHC.Types.Avail -import GHC.Types.Module +import GHC.Unit import GHC.Core.InstEnv ( InstEnv, ClsInst, identicalClsInstHead ) import GHC.Core.FamInstEnv import GHC.Core ( CoreProgram, RuleBase, CoreRule ) @@ -192,7 +192,6 @@ import GHC.Core.DataCon import GHC.Core.PatSyn import GHC.Builtin.Names ( gHC_PRIM, ioTyConName, printName, mkInteractiveModule ) import GHC.Builtin.Types -import GHC.Driver.Packages hiding ( Version(..) ) import GHC.Driver.CmdLine import GHC.Driver.Session import GHC.Runtime.Linker.Types ( DynLinker, Linkable(..), Unlinked(..), SptEntry(..) ) |