    -- (c) The University of Glasgow, 2006

    {-# LANGUAGE LambdaCase #-}

    -- | Unit manipulation
    module GHC.Unit.State (
            module GHC.Unit.Info,

            -- * Reading the package config, and processing cmdline args
            UnitState(..),
            PreloadUnitClosure,
            UnitDatabase (..),
            UnitErr (..),
            emptyUnitState,
            initUnits,
            readUnitDatabases,
            readUnitDatabase,
            getUnitDbRefs,
            resolveUnitDatabase,
            listUnitInfo,

            -- * Querying the package config
            UnitInfoMap,
            lookupUnit,
            lookupUnit',
            unsafeLookupUnit,
            lookupUnitId,
            lookupUnitId',
            unsafeLookupUnitId,

            lookupPackageName,
            resolvePackageImport,
            improveUnit,
            searchPackageId,
            listVisibleModuleNames,
            lookupModuleInAllUnits,
            lookupModuleWithSuggestions,
            lookupModulePackage,
            lookupPluginModuleWithSuggestions,
            requirementMerges,
            LookupResult(..),
            ModuleSuggestion(..),
            ModuleOrigin(..),
            UnusableUnit(..),
            UnusableUnitReason(..),
            pprReason,

            closeUnitDeps,
            closeUnitDeps',
            mayThrowUnitErr,

            -- * Module hole substitution
            ShHoleSubst,
            renameHoleUnit,
            renameHoleModule,
            renameHoleUnit',
            renameHoleModule',
            instUnitToUnit,
            instModuleToModule,

            -- * Pretty-printing
            pprFlag,
            pprUnits,
            pprUnitsSimple,
            pprUnitIdForUser,
            pprUnitInfoForUser,
            pprModuleMap,
            pprWithUnitState,

            -- * Utils
            unwireUnit)
    where

    import GHC.Prelude

    import GHC.Driver.DynFlags

    import GHC.Platform
    import GHC.Platform.Ways

    import GHC.Unit.Database
    import GHC.Unit.Info
    import GHC.Unit.Ppr
    import GHC.Unit.Types
    import GHC.Unit.Module
    import GHC.Unit.Home

    import GHC.Types.Unique.FM
    import GHC.Types.Unique.DFM
    import GHC.Types.Unique.Set
    import GHC.Types.Unique.DSet
    import GHC.Types.Unique.Map
    import GHC.Types.Unique
    import GHC.Types.PkgQual

    import GHC.Utils.Misc
    import GHC.Utils.Panic
    import GHC.Utils.Outputable as Outputable
    import GHC.Data.Maybe

    import System.Environment ( getEnv )
    import GHC.Data.FastString
    import qualified GHC.Data.ShortText as ST
    import GHC.Utils.Logger
    import GHC.Utils.Error
    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 ( intersperse, partition, sortBy, isSuffixOf, sortOn )
    import Data.Set (Set)
    import Data.Monoid (First(..))
    import qualified Data.Semigroup as Semigroup
    import qualified Data.Set as Set
    import Control.Applicative

    -- ---------------------------------------------------------------------------
    -- The Unit state

    -- The unit state is computed by 'initUnits', and kept in HscEnv.
    -- It is influenced by various command-line 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 unit state has the following properties.
    --
    --   * Let @exposedUnits@ be the set of packages thus exposed.
    --     Let @depExposedUnits@ be the transitive closure from @exposedUnits@ of
    --     their dependencies.
    --
    --   * When searching for a module from a preload import declaration,
    --     only the exposed modules in @exposedUnits@ are valid.
    --
    --   * When searching for a module from an implicit import, all modules
    --     from @depExposedUnits@ 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 unit is unusable.
      | ModUnusable !UnusableUnit

        -- | 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.
            ModuleOrigin -> Maybe Bool
    fromOrigUnit :: Maybe Bool
            -- | Is the module available from a reexport of an exposed package?
            -- There could be multiple.
          , ModuleOrigin -> [UnitInfo]
    fromExposedReexport :: [UnitInfo]
            -- | Is the module available from a reexport of a hidden package?
          , ModuleOrigin -> [UnitInfo]
    fromHiddenReexport :: [UnitInfo]
            -- | Did the module export come from a package flag? (ToDo: track
            -- more information.
          , ModuleOrigin -> Bool
    fromPackageFlag :: Bool
          }

    -- | A unusable unit module origin
    data UnusableUnit = UnusableUnit
      { UnusableUnit -> Unit
    uuUnit        :: !Unit               -- ^ Unusable unit
      , UnusableUnit -> UnusableUnitReason
    uuReason      :: !UnusableUnitReason -- ^ Reason
      , UnusableUnit -> Bool
    uuIsReexport  :: !Bool               -- ^ Is the "module" a reexport?
      }

    instance Outputable ModuleOrigin where
        ppr :: ModuleOrigin -> SDoc
    ppr ModuleOrigin
    ModHidden = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "hidden module"
        ppr (ModUnusable UnusableUnit
    _) = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "unusable module"
        ppr (ModOrigin Maybe Bool
    e [UnitInfo]
    res [UnitInfo]
    rhs Bool
    f) = [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    sep (SDoc -> [SDoc] -> [SDoc]
    forall doc. IsLine doc => doc -> [doc] -> [doc]
    punctuate SDoc
    forall doc. IsLine doc => doc
    comma (
            (case Maybe Bool
    e of
                Maybe Bool
    Nothing -> []
                Just Bool
    False -> [String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "hidden package"]
                Just Bool
    True -> [String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "exposed package"]) [SDoc] -> [SDoc] -> [SDoc]
    forall a. [a] -> [a] -> [a]
    ++
            (if [UnitInfo] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [UnitInfo]
    res
                then []
                else [String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "reexport by" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+>
                        [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    sep ((UnitInfo -> SDoc) -> [UnitInfo] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (Unit -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Unit -> SDoc) -> (UnitInfo -> Unit) -> UnitInfo -> SDoc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitInfo -> Unit
    mkUnit) [UnitInfo]
    res)]) [SDoc] -> [SDoc] -> [SDoc]
    forall a. [a] -> [a] -> [a]
    ++
            (if [UnitInfo] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [UnitInfo]
    rhs
                then []
                else [String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "hidden reexport by" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+>
                        [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    sep ((UnitInfo -> SDoc) -> [UnitInfo] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (Unit -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Unit -> SDoc) -> (UnitInfo -> Unit) -> UnitInfo -> SDoc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitInfo -> Unit
    mkUnit) [UnitInfo]
    res)]) [SDoc] -> [SDoc] -> [SDoc]
    forall a. [a] -> [a] -> [a]
    ++
            (if Bool
    f then [String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "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 :: Bool -> ModuleOrigin
    fromExposedModules Bool
    e = Maybe Bool -> [UnitInfo] -> [UnitInfo] -> Bool -> ModuleOrigin
    ModOrigin (Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    e) [] [] Bool
    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 :: Bool -> UnitInfo -> ModuleOrigin
    fromReexportedModules Bool
    True UnitInfo
    pkg = Maybe Bool -> [UnitInfo] -> [UnitInfo] -> Bool -> ModuleOrigin
    ModOrigin Maybe Bool
    forall a. Maybe a
    Nothing [UnitInfo
    pkg] [] Bool
    False
    fromReexportedModules Bool
    False UnitInfo
    pkg = Maybe Bool -> [UnitInfo] -> [UnitInfo] -> Bool -> ModuleOrigin
    ModOrigin Maybe Bool
    forall a. Maybe a
    Nothing [] [UnitInfo
    pkg] Bool
    False

    -- | Smart constructor for a module which was bound by a package flag.
    fromFlag :: ModuleOrigin
    fromFlag :: ModuleOrigin
    fromFlag = Maybe Bool -> [UnitInfo] -> [UnitInfo] -> Bool -> ModuleOrigin
    ModOrigin Maybe Bool
    forall a. Maybe a
    Nothing [] [] Bool
    True

    instance Semigroup ModuleOrigin where
        x :: ModuleOrigin
    x@(ModOrigin Maybe Bool
    e [UnitInfo]
    res [UnitInfo]
    rhs Bool
    f) <> :: ModuleOrigin -> ModuleOrigin -> ModuleOrigin
    <> y :: ModuleOrigin
    y@(ModOrigin Maybe Bool
    e' [UnitInfo]
    res' [UnitInfo]
    rhs' Bool
    f') =
            Maybe Bool -> [UnitInfo] -> [UnitInfo] -> Bool -> ModuleOrigin
    ModOrigin (Maybe Bool -> Maybe Bool -> Maybe Bool
    g Maybe Bool
    e Maybe Bool
    e') ([UnitInfo]
    res [UnitInfo] -> [UnitInfo] -> [UnitInfo]
    forall a. [a] -> [a] -> [a]
    ++ [UnitInfo]
    res') ([UnitInfo]
    rhs [UnitInfo] -> [UnitInfo] -> [UnitInfo]
    forall a. [a] -> [a] -> [a]
    ++ [UnitInfo]
    rhs') (Bool
    f Bool -> Bool -> Bool
    || Bool
    f')
          where g :: Maybe Bool -> Maybe Bool -> Maybe Bool
    g (Just Bool
    b) (Just Bool
    b')
                    | Bool
    b Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == Bool
    b'   = Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    b
                    | Bool
    otherwise = String -> SDoc -> Maybe Bool
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "ModOrigin: package both exposed/hidden" (SDoc -> Maybe Bool) -> SDoc -> Maybe Bool
    forall a b. (a -> b) -> a -> b
    $
                        String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "x: " SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> ModuleOrigin -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleOrigin
    x SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "y: " SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> ModuleOrigin -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleOrigin
    y
                g Maybe Bool
    Nothing Maybe Bool
    x = Maybe Bool
    x
                g Maybe Bool
    x Maybe Bool
    Nothing = Maybe Bool
    x

        ModuleOrigin
    x <> ModuleOrigin
    y = String -> SDoc -> ModuleOrigin
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "ModOrigin: module origin mismatch" (SDoc -> ModuleOrigin) -> SDoc -> ModuleOrigin
    forall a b. (a -> b) -> a -> b
    $
                     String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "x: " SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> ModuleOrigin -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleOrigin
    x SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "y: " SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> ModuleOrigin -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleOrigin
    y

    instance Monoid ModuleOrigin where
        mempty :: ModuleOrigin
    mempty = Maybe Bool -> [UnitInfo] -> [UnitInfo] -> Bool -> ModuleOrigin
    ModOrigin Maybe Bool
    forall a. Maybe a
    Nothing [] [] Bool
    False
        mappend :: ModuleOrigin -> ModuleOrigin -> ModuleOrigin
    mappend = ModuleOrigin -> ModuleOrigin -> ModuleOrigin
    forall a. Semigroup a => a -> a -> a
    (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 :: ModuleOrigin -> Bool
    originVisible ModuleOrigin
    ModHidden = Bool
    False
    originVisible (ModUnusable UnusableUnit
    _) = Bool
    False
    originVisible (ModOrigin Maybe Bool
    b [UnitInfo]
    res [UnitInfo]
    _ Bool
    f) = Maybe Bool
    b Maybe Bool -> Maybe Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    True Bool -> Bool -> Bool
    || Bool -> Bool
    not ([UnitInfo] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [UnitInfo]
    res) Bool -> Bool -> Bool
    || Bool
    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 :: ModuleOrigin -> Bool
    originEmpty (ModOrigin Maybe Bool
    Nothing [] [] Bool
    False) = Bool
    True
    originEmpty ModuleOrigin
    _ = Bool
    False

    type PreloadUnitClosure = UniqSet UnitId

    -- | 'UniqFM' map from 'Unit' to a 'UnitVisibility'.
    type VisibilityMap = UniqMap Unit UnitVisibility

    -- | 'UnitVisibility' records the various aspects of visibility of a particular
    -- 'Unit'.
    data UnitVisibility = UnitVisibility
        { UnitVisibility -> Bool
    uv_expose_all :: Bool
          --  ^ Should all modules in exposed-modules should be dumped into scope?
        , UnitVisibility -> [(ModuleName, ModuleName)]
    uv_renamings :: [(ModuleName, ModuleName)]
          -- ^ Any custom renamings that should bring extra 'ModuleName's into
          -- scope.
        , UnitVisibility -> First FastString
    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@
        , UnitVisibility -> UniqMap ModuleName (Set InstantiatedModule)
    uv_requirements :: UniqMap ModuleName (Set InstantiatedModule)
          -- ^ The signatures which are contributed to the requirements context
          -- from this unit ID.
        , UnitVisibility -> Maybe PackageArg
    uv_explicit :: Maybe PackageArg
          -- ^ 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 -> SDoc
    ppr (UnitVisibility {
            uv_expose_all :: UnitVisibility -> Bool
    uv_expose_all = Bool
    b,
            uv_renamings :: UnitVisibility -> [(ModuleName, ModuleName)]
    uv_renamings = [(ModuleName, ModuleName)]
    rns,
            uv_package_name :: UnitVisibility -> First FastString
    uv_package_name = First Maybe FastString
    mb_pn,
            uv_requirements :: UnitVisibility -> UniqMap ModuleName (Set InstantiatedModule)
    uv_requirements = UniqMap ModuleName (Set InstantiatedModule)
    reqs,
            uv_explicit :: UnitVisibility -> Maybe PackageArg
    uv_explicit = Maybe PackageArg
    explicit
        }) = (Bool, [(ModuleName, ModuleName)], Maybe FastString,
     UniqMap ModuleName (Set InstantiatedModule), Maybe PackageArg)
    -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Bool
    b, [(ModuleName, ModuleName)]
    rns, Maybe FastString
    mb_pn, UniqMap ModuleName (Set InstantiatedModule)
    reqs, Maybe PackageArg
    explicit)

    instance Semigroup UnitVisibility where
        UnitVisibility
    uv1 <> :: UnitVisibility -> UnitVisibility -> UnitVisibility
    <> UnitVisibility
    uv2
            = UnitVisibility
              { uv_expose_all :: Bool
    uv_expose_all = UnitVisibility -> Bool
    uv_expose_all UnitVisibility
    uv1 Bool -> Bool -> Bool
    || UnitVisibility -> Bool
    uv_expose_all UnitVisibility
    uv2
              , uv_renamings :: [(ModuleName, ModuleName)]
    uv_renamings = UnitVisibility -> [(ModuleName, ModuleName)]
    uv_renamings UnitVisibility
    uv1 [(ModuleName, ModuleName)]
    -> [(ModuleName, ModuleName)] -> [(ModuleName, ModuleName)]
    forall a. [a] -> [a] -> [a]
    ++ UnitVisibility -> [(ModuleName, ModuleName)]
    uv_renamings UnitVisibility
    uv2
              , uv_package_name :: First FastString
    uv_package_name = First FastString -> First FastString -> First FastString
    forall a. Monoid a => a -> a -> a
    mappend (UnitVisibility -> First FastString
    uv_package_name UnitVisibility
    uv1) (UnitVisibility -> First FastString
    uv_package_name UnitVisibility
    uv2)
              , uv_requirements :: UniqMap ModuleName (Set InstantiatedModule)
    uv_requirements = (Set InstantiatedModule
     -> Set InstantiatedModule -> Set InstantiatedModule)
    -> UniqMap ModuleName (Set InstantiatedModule)
    -> UniqMap ModuleName (Set InstantiatedModule)
    -> UniqMap ModuleName (Set InstantiatedModule)
    forall a k.
    (a -> a -> a) -> UniqMap k a -> UniqMap k a -> UniqMap k a
    plusUniqMap_C Set InstantiatedModule
    -> Set InstantiatedModule -> Set InstantiatedModule
    forall a. Ord a => Set a -> Set a -> Set a
    Set.union (UnitVisibility -> UniqMap ModuleName (Set InstantiatedModule)
    uv_requirements UnitVisibility
    uv2) (UnitVisibility -> UniqMap ModuleName (Set InstantiatedModule)
    uv_requirements UnitVisibility
    uv1)
              , uv_explicit :: Maybe PackageArg
    uv_explicit = UnitVisibility -> Maybe PackageArg
    uv_explicit UnitVisibility
    uv1 Maybe PackageArg -> Maybe PackageArg -> Maybe PackageArg
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> UnitVisibility -> Maybe PackageArg
    uv_explicit UnitVisibility
    uv2
              }

    instance Monoid UnitVisibility where
        mempty :: UnitVisibility
    mempty = UnitVisibility
                 { uv_expose_all :: Bool
    uv_expose_all = Bool
    False
                 , uv_renamings :: [(ModuleName, ModuleName)]
    uv_renamings = []
                 , uv_package_name :: First FastString
    uv_package_name = Maybe FastString -> First FastString
    forall a. Maybe a -> First a
    First Maybe FastString
    forall a. Maybe a
    Nothing
                 , uv_requirements :: UniqMap ModuleName (Set InstantiatedModule)
    uv_requirements = UniqMap ModuleName (Set InstantiatedModule)
    forall k a. UniqMap k a
    emptyUniqMap
                 , uv_explicit :: Maybe PackageArg
    uv_explicit = Maybe PackageArg
    forall a. Maybe a
    Nothing
                 }
        mappend :: UnitVisibility -> UnitVisibility -> UnitVisibility
    mappend = UnitVisibility -> UnitVisibility -> UnitVisibility
    forall a. Semigroup a => a -> a -> a
    (Semigroup.<>)

    -- | Unit configuration
    data UnitConfig = UnitConfig
       { UnitConfig -> ArchOS
    unitConfigPlatformArchOS :: !ArchOS        -- ^ Platform arch and OS
       , UnitConfig -> Ways
    unitConfigWays           :: !Ways          -- ^ Ways to use

       , UnitConfig -> Bool
    unitConfigAllowVirtual   :: !Bool          -- ^ Allow virtual units
          -- ^ Do we allow the use of virtual units instantiated on-the-fly (see
          -- Note [About units] in GHC.Unit). This should only be true when we are
          -- type-checking an indefinite unit (not producing any code).

       , UnitConfig -> String
    unitConfigProgramName    :: !String
          -- ^ Name of the compiler (e.g. "GHC", "GHCJS"). Used to fetch environment
          -- variables such as "GHC[JS]_PACKAGE_PATH".

       , UnitConfig -> String
    unitConfigGlobalDB :: !FilePath    -- ^ Path to global DB
       , UnitConfig -> String
    unitConfigGHCDir   :: !FilePath    -- ^ Main GHC dir: contains settings, etc.
       , UnitConfig -> String
    unitConfigDBName   :: !String      -- ^ User DB name (e.g. "package.conf.d")

       , UnitConfig -> [UnitId]
    unitConfigAutoLink       :: ![UnitId] -- ^ Units to link automatically (e.g. base, rts)
       , UnitConfig -> Bool
    unitConfigDistrustAll    :: !Bool     -- ^ Distrust all units by default
       , UnitConfig -> Bool
    unitConfigHideAll        :: !Bool     -- ^ Hide all units by default
       , UnitConfig -> Bool
    unitConfigHideAllPlugins :: !Bool     -- ^ Hide all plugins units by default

       , UnitConfig -> Maybe [UnitDatabase UnitId]
    unitConfigDBCache      :: Maybe [UnitDatabase UnitId]
          -- ^ Cache of databases to use, in the order they were specified on the
          -- command line (later databases shadow earlier ones).
          -- If Nothing, databases will be found using `unitConfigFlagsDB`.

       -- command-line flags
       , UnitConfig -> [PackageDBFlag]
    unitConfigFlagsDB      :: [PackageDBFlag]     -- ^ Unit databases flags
       , UnitConfig -> [PackageFlag]
    unitConfigFlagsExposed :: [PackageFlag]       -- ^ Exposed units
       , UnitConfig -> [IgnorePackageFlag]
    unitConfigFlagsIgnored :: [IgnorePackageFlag] -- ^ Ignored units
       , UnitConfig -> [TrustFlag]
    unitConfigFlagsTrusted :: [TrustFlag]         -- ^ Trusted units
       , UnitConfig -> [PackageFlag]
    unitConfigFlagsPlugins :: [PackageFlag]       -- ^ Plugins exposed units
       , UnitConfig -> Set UnitId
    unitConfigHomeUnits    :: Set.Set UnitId
       }

    initUnitConfig :: DynFlags -> Maybe [UnitDatabase UnitId] -> Set.Set UnitId -> UnitConfig
    initUnitConfig :: DynFlags -> Maybe [UnitDatabase UnitId] -> Set UnitId -> UnitConfig
    initUnitConfig DynFlags
    dflags Maybe [UnitDatabase UnitId]
    cached_dbs Set UnitId
    home_units =
       let !hu_id :: UnitId
    hu_id             = DynFlags -> UnitId
    homeUnitId_ DynFlags
    dflags
           !hu_instanceof :: Maybe UnitId
    hu_instanceof     = DynFlags -> Maybe UnitId
    homeUnitInstanceOf_ DynFlags
    dflags
           !hu_instantiations :: [(ModuleName, Module)]
    hu_instantiations = DynFlags -> [(ModuleName, Module)]
    homeUnitInstantiations_ DynFlags
    dflags

           autoLink :: [UnitId]
    autoLink
             | Bool -> Bool
    not (GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_AutoLinkPackages DynFlags
    dflags) = []
             -- By default we add ghc-internal & rts to the preload units (when they are
             -- found in the unit database) except when we are building them
             | Bool
    otherwise = (UnitId -> Bool) -> [UnitId] -> [UnitId]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (UnitId
    hu_id UnitId -> UnitId -> Bool
    forall a. Eq a => a -> a -> Bool
    /=) [UnitId
    ghcInternalUnitId, UnitId
    rtsUnitId]

           -- if the home unit is indefinite, it means we are type-checking it only
           -- (not producing any code). Hence we can use virtual units instantiated
           -- on-the-fly. See Note [About units] in GHC.Unit
           allow_virtual_units :: Bool
    allow_virtual_units = case (Maybe UnitId
    hu_instanceof, [(ModuleName, Module)]
    hu_instantiations) of
                (Just UnitId
    u, [(ModuleName, Module)]
    is) -> UnitId
    u UnitId -> UnitId -> Bool
    forall a. Eq a => a -> a -> Bool
    == UnitId
    hu_id Bool -> Bool -> Bool
    && ((ModuleName, Module) -> Bool) -> [(ModuleName, Module)] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Module -> Bool
    forall u. GenModule (GenUnit u) -> Bool
    isHoleModule (Module -> Bool)
    -> ((ModuleName, Module) -> Module) -> (ModuleName, Module) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ModuleName, Module) -> Module
    forall a b. (a, b) -> b
    snd) [(ModuleName, Module)]
    is
                (Maybe UnitId, [(ModuleName, Module)])
    _            -> Bool
    False

       in UnitConfig
          { unitConfigPlatformArchOS :: ArchOS
    unitConfigPlatformArchOS = Platform -> ArchOS
    platformArchOS (DynFlags -> Platform
    targetPlatform DynFlags
    dflags)
          , unitConfigProgramName :: String
    unitConfigProgramName    = DynFlags -> String
    programName DynFlags
    dflags
          , unitConfigWays :: Ways
    unitConfigWays           = DynFlags -> Ways
    ways DynFlags
    dflags
          , unitConfigAllowVirtual :: Bool
    unitConfigAllowVirtual   = Bool
    allow_virtual_units

          , unitConfigGlobalDB :: String
    unitConfigGlobalDB       = DynFlags -> String
    globalPackageDatabasePath DynFlags
    dflags
          , unitConfigGHCDir :: String
    unitConfigGHCDir         = DynFlags -> String
    topDir DynFlags
    dflags
          , unitConfigDBName :: String
    unitConfigDBName         = String
    "package.conf.d"

          , unitConfigAutoLink :: [UnitId]
    unitConfigAutoLink       = [UnitId]
    autoLink
          , unitConfigDistrustAll :: Bool
    unitConfigDistrustAll    = GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_DistrustAllPackages DynFlags
    dflags
          , unitConfigHideAll :: Bool
    unitConfigHideAll        = GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_HideAllPackages DynFlags
    dflags
          , unitConfigHideAllPlugins :: Bool
    unitConfigHideAllPlugins = GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_HideAllPluginPackages DynFlags
    dflags

          , unitConfigDBCache :: Maybe [UnitDatabase UnitId]
    unitConfigDBCache      = Maybe [UnitDatabase UnitId]
    cached_dbs
          , unitConfigFlagsDB :: [PackageDBFlag]
    unitConfigFlagsDB      = (PackageDBFlag -> PackageDBFlag)
    -> [PackageDBFlag] -> [PackageDBFlag]
    forall a b. (a -> b) -> [a] -> [b]
    map (Maybe String -> PackageDBFlag -> PackageDBFlag
    offsetPackageDb (DynFlags -> Maybe String
    workingDirectory DynFlags
    dflags)) ([PackageDBFlag] -> [PackageDBFlag])
    -> [PackageDBFlag] -> [PackageDBFlag]
    forall a b. (a -> b) -> a -> b
    $ DynFlags -> [PackageDBFlag]
    packageDBFlags DynFlags
    dflags
          , unitConfigFlagsExposed :: [PackageFlag]
    unitConfigFlagsExposed = DynFlags -> [PackageFlag]
    packageFlags DynFlags
    dflags
          , unitConfigFlagsIgnored :: [IgnorePackageFlag]
    unitConfigFlagsIgnored = DynFlags -> [IgnorePackageFlag]
    ignorePackageFlags DynFlags
    dflags
          , unitConfigFlagsTrusted :: [TrustFlag]
    unitConfigFlagsTrusted = DynFlags -> [TrustFlag]
    trustFlags DynFlags
    dflags
          , unitConfigFlagsPlugins :: [PackageFlag]
    unitConfigFlagsPlugins = DynFlags -> [PackageFlag]
    pluginPackageFlags DynFlags
    dflags
          , unitConfigHomeUnits :: Set UnitId
    unitConfigHomeUnits    = Set UnitId
    home_units

          }

      where
        offsetPackageDb :: Maybe FilePath -> PackageDBFlag -> PackageDBFlag
        offsetPackageDb :: Maybe String -> PackageDBFlag -> PackageDBFlag
    offsetPackageDb (Just String
    offset) (PackageDB (PkgDbPath String
    p)) | String -> Bool
    isRelative String
    p = PkgDbRef -> PackageDBFlag
    PackageDB (String -> PkgDbRef
    PkgDbPath (String
    offset String -> String -> String
    </> String
    p))
        offsetPackageDb Maybe String
    _ PackageDBFlag
    p = PackageDBFlag
    p

    -- | Map from 'ModuleName' to a set 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 =
        UniqMap ModuleName (UniqMap Module ModuleOrigin)

    data UnitState = UnitState {
      -- | A mapping of 'Unit' to 'UnitInfo'.  This list is adjusted
      -- so that only valid units are here.  'UnitInfo' reflects
      -- what was stored *on disk*, except for the 'trusted' flag, which
      -- is adjusted at runtime.  (In particular, some units in this map
      -- may have the 'exposed' flag be 'False'.)
      UnitState -> UnitInfoMap
    unitInfoMap :: UnitInfoMap,

      -- | 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]
      UnitState -> PreloadUnitClosure
    preloadClosure :: PreloadUnitClosure,

      -- | A mapping of 'PackageName' to 'UnitId'. If several units have the same
      -- package name (e.g. different instantiations), then we return one of them...
      -- This is used when users refer to packages in Backpack includes.
      -- And also to resolve package qualifiers with the PackageImports extension.
      UnitState -> UniqFM PackageName UnitId
    packageNameMap            :: UniqFM PackageName UnitId,

      -- | A mapping from database unit keys to wired in unit ids.
      UnitState -> UniqMap UnitId UnitId
    wireMap :: UniqMap UnitId UnitId,

      -- | A mapping from wired in unit ids to unit keys from the database.
      UnitState -> UniqMap UnitId UnitId
    unwireMap :: UniqMap UnitId UnitId,

      -- | The units we're going to link in eagerly.  This list
      -- should be in reverse dependency order; that is, a unit
      -- is always mentioned before the units it depends on.
      UnitState -> [UnitId]
    preloadUnits      :: [UnitId],

      -- | Units which we explicitly depend on (from a command line flag).
      -- We'll use this to generate version macros and the unused packages warning. The
      -- original flag which was used to bring the unit into scope is recorded for the
      -- -Wunused-packages warning.
      UnitState -> [(Unit, Maybe PackageArg)]
    explicitUnits :: [(Unit, Maybe PackageArg)],

      UnitState -> [UnitId]
    homeUnitDepends    :: [UnitId],

      -- | 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.
      UnitState -> ModuleNameProvidersMap
    moduleNameProvidersMap    :: !ModuleNameProvidersMap,

      -- | A map, like 'moduleNameProvidersMap', but controlling plugin visibility.
      UnitState -> ModuleNameProvidersMap
    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.
      UnitState -> UniqMap ModuleName [InstantiatedModule]
    requirementContext :: UniqMap ModuleName [InstantiatedModule],

      -- | Indicate if we can instantiate units on-the-fly.
      --
      -- This should only be true when we are type-checking an indefinite unit.
      -- See Note [About units] in GHC.Unit.
      UnitState -> Bool
    allowVirtualUnits :: !Bool
      }

    emptyUnitState :: UnitState
    emptyUnitState :: UnitState
    emptyUnitState = UnitState {
        unitInfoMap :: UnitInfoMap
    unitInfoMap    = UnitInfoMap
    forall k a. UniqMap k a
    emptyUniqMap,
        preloadClosure :: PreloadUnitClosure
    preloadClosure = PreloadUnitClosure
    forall a. UniqSet a
    emptyUniqSet,
        packageNameMap :: UniqFM PackageName UnitId
    packageNameMap = UniqFM PackageName UnitId
    forall {k} (key :: k) elt. UniqFM key elt
    emptyUFM,
        wireMap :: UniqMap UnitId UnitId
    wireMap        = UniqMap UnitId UnitId
    forall k a. UniqMap k a
    emptyUniqMap,
        unwireMap :: UniqMap UnitId UnitId
    unwireMap      = UniqMap UnitId UnitId
    forall k a. UniqMap k a
    emptyUniqMap,
        preloadUnits :: [UnitId]
    preloadUnits   = [],
        explicitUnits :: [(Unit, Maybe PackageArg)]
    explicitUnits  = [],
        homeUnitDepends :: [UnitId]
    homeUnitDepends = [],
        moduleNameProvidersMap :: ModuleNameProvidersMap
    moduleNameProvidersMap       = ModuleNameProvidersMap
    forall k a. UniqMap k a
    emptyUniqMap,
        pluginModuleNameProvidersMap :: ModuleNameProvidersMap
    pluginModuleNameProvidersMap = ModuleNameProvidersMap
    forall k a. UniqMap k a
    emptyUniqMap,
        requirementContext :: UniqMap ModuleName [InstantiatedModule]
    requirementContext           = UniqMap ModuleName [InstantiatedModule]
    forall k a. UniqMap k a
    emptyUniqMap,
        allowVirtualUnits :: Bool
    allowVirtualUnits = Bool
    False
        }

    -- | Unit database
    data UnitDatabase unit = UnitDatabase
       { forall unit. UnitDatabase unit -> String
    unitDatabasePath  :: FilePath
       , forall unit. UnitDatabase unit -> [GenUnitInfo unit]
    unitDatabaseUnits :: [GenUnitInfo unit]
       }

    instance Outputable u => Outputable (UnitDatabase u) where
      ppr :: UnitDatabase u -> SDoc
    ppr (UnitDatabase String
    fp [GenUnitInfo u]
    _u) = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "DB:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    fp

    type UnitInfoMap = UniqMap UnitId UnitInfo

    -- | Find the unit we know about with the given unit, if any
    lookupUnit :: UnitState -> Unit -> Maybe UnitInfo
    lookupUnit :: UnitState -> Unit -> Maybe UnitInfo
    lookupUnit UnitState
    pkgs = Bool -> UnitInfoMap -> PreloadUnitClosure -> Unit -> Maybe UnitInfo
    lookupUnit' (UnitState -> Bool
    allowVirtualUnits UnitState
    pkgs) (UnitState -> UnitInfoMap
    unitInfoMap UnitState
    pkgs) (UnitState -> PreloadUnitClosure
    preloadClosure UnitState
    pkgs)

    -- | A more specialized interface, which doesn't require a 'UnitState' (so it
    -- can be used while we're initializing 'DynFlags')
    --
    -- Parameters:
    --    * a boolean specifying whether or not to look for on-the-fly renamed interfaces
    --    * a 'UnitInfoMap'
    --    * a 'PreloadUnitClosure'
    lookupUnit' :: Bool -> UnitInfoMap -> PreloadUnitClosure -> Unit -> Maybe UnitInfo
    lookupUnit' :: Bool -> UnitInfoMap -> PreloadUnitClosure -> Unit -> Maybe UnitInfo
    lookupUnit' Bool
    allowOnTheFlyInst UnitInfoMap
    pkg_map PreloadUnitClosure
    closure Unit
    u = case Unit
    u of
       Unit
    HoleUnit   -> String -> Maybe UnitInfo
    forall a. HasCallStack => String -> a
    error String
    "Hole unit"
       RealUnit Definite UnitId
    i -> UnitInfoMap -> UnitId -> Maybe UnitInfo
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UnitInfoMap
    pkg_map (Definite UnitId -> UnitId
    forall unit. Definite unit -> unit
    unDefinite Definite UnitId
    i)
       VirtUnit GenInstantiatedUnit UnitId
    i
          | Bool
    allowOnTheFlyInst
          -> -- lookup UnitInfo of the indefinite unit to be instantiated and
             -- instantiate it on-the-fly
             (UnitInfo -> UnitInfo) -> Maybe UnitInfo -> Maybe UnitInfo
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (UnitInfoMap
    -> PreloadUnitClosure
    -> [(ModuleName, Module)]
    -> UnitInfo
    -> UnitInfo
    renameUnitInfo UnitInfoMap
    pkg_map PreloadUnitClosure
    closure (GenInstantiatedUnit UnitId -> [(ModuleName, Module)]
    forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts GenInstantiatedUnit UnitId
    i))
               (UnitInfoMap -> UnitId -> Maybe UnitInfo
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UnitInfoMap
    pkg_map (GenInstantiatedUnit UnitId -> UnitId
    forall unit. GenInstantiatedUnit unit -> unit
    instUnitInstanceOf GenInstantiatedUnit UnitId
    i))

          | Bool
    otherwise
          -> -- lookup UnitInfo by virtual UnitId. This is used to find indefinite
             -- units. Even if they are real, installed units, they can't use the
             -- `RealUnit` constructor (it is reserved for definite units) so we use
             -- the `VirtUnit` constructor.
             UnitInfoMap -> UnitId -> Maybe UnitInfo
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UnitInfoMap
    pkg_map (GenInstantiatedUnit UnitId -> UnitId
    virtualUnitId GenInstantiatedUnit UnitId
    i)

    -- | Find the unit we know about with the given unit id, if any
    lookupUnitId :: UnitState -> UnitId -> Maybe UnitInfo
    lookupUnitId :: UnitState -> UnitId -> Maybe UnitInfo
    lookupUnitId UnitState
    state UnitId
    uid = UnitInfoMap -> UnitId -> Maybe UnitInfo
    lookupUnitId' (UnitState -> UnitInfoMap
    unitInfoMap UnitState
    state) UnitId
    uid

    -- | Find the unit we know about with the given unit id, if any
    lookupUnitId' :: UnitInfoMap -> UnitId -> Maybe UnitInfo
    lookupUnitId' :: UnitInfoMap -> UnitId -> Maybe UnitInfo
    lookupUnitId' UnitInfoMap
    db UnitId
    uid = UnitInfoMap -> UnitId -> Maybe UnitInfo
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UnitInfoMap
    db UnitId
    uid

    -- | Looks up the given unit in the unit state, panicking if it is not found
    unsafeLookupUnit :: HasDebugCallStack => UnitState -> Unit -> UnitInfo
    unsafeLookupUnit :: HasDebugCallStack => UnitState -> Unit -> UnitInfo
    unsafeLookupUnit UnitState
    state Unit
    u = case UnitState -> Unit -> Maybe UnitInfo
    lookupUnit UnitState
    state Unit
    u of
       Just UnitInfo
    info -> UnitInfo
    info
       Maybe UnitInfo
    Nothing   -> String -> SDoc -> UnitInfo
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "unsafeLookupUnit" (Unit -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Unit
    u)

    -- | Looks up the given unit id in the unit state, panicking if it is not found
    unsafeLookupUnitId :: HasDebugCallStack => UnitState -> UnitId -> UnitInfo
    unsafeLookupUnitId :: HasDebugCallStack => UnitState -> UnitId -> UnitInfo
    unsafeLookupUnitId UnitState
    state UnitId
    uid = case UnitState -> UnitId -> Maybe UnitInfo
    lookupUnitId UnitState
    state UnitId
    uid of
       Just UnitInfo
    info -> UnitInfo
    info
       Maybe UnitInfo
    Nothing   -> String -> SDoc -> UnitInfo
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "unsafeLookupUnitId" (UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr UnitId
    uid)

    -- | Find the unit 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)
    -- This function is unsafe to use in general because it doesn't respect package
    -- visibility.
    lookupPackageName :: UnitState -> PackageName -> Maybe UnitId
    lookupPackageName :: UnitState -> PackageName -> Maybe UnitId
    lookupPackageName UnitState
    pkgstate PackageName
    n = UniqFM PackageName UnitId -> PackageName -> Maybe UnitId
    forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
    lookupUFM (UnitState -> UniqFM PackageName UnitId
    packageNameMap UnitState
    pkgstate) PackageName
    n

    -- | Search for units with a given package ID (e.g. \"foo-0.1\")
    searchPackageId :: UnitState -> PackageId -> [UnitInfo]
    searchPackageId :: UnitState -> PackageId -> [UnitInfo]
    searchPackageId UnitState
    pkgstate PackageId
    pid = (UnitInfo -> Bool) -> [UnitInfo] -> [UnitInfo]
    forall a. (a -> Bool) -> [a] -> [a]
    filter ((PackageId
    pid PackageId -> PackageId -> Bool
    forall a. Eq a => a -> a -> Bool
    ==) (PackageId -> Bool) -> (UnitInfo -> PackageId) -> UnitInfo -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitInfo -> PackageId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> srcpkgid
    unitPackageId)
                                   (UnitState -> [UnitInfo]
    listUnitInfo UnitState
    pkgstate)

    -- | Find the UnitId which an import qualified by a package import comes from.
    -- Compared to 'lookupPackageName', this function correctly accounts for visibility,
    -- renaming and thinning.
    resolvePackageImport :: UnitState -> ModuleName -> PackageName -> Maybe UnitId
    resolvePackageImport :: UnitState -> ModuleName -> PackageName -> Maybe UnitId
    resolvePackageImport UnitState
    unit_st ModuleName
    mn PackageName
    pn = do
      -- 1. Find all modules providing the ModuleName (this accounts for visibility/thinning etc)
      providers <- (ModuleOrigin -> Bool)
    -> UniqMap Module ModuleOrigin -> UniqMap Module ModuleOrigin
    forall a k. (a -> Bool) -> UniqMap k a -> UniqMap k a
    filterUniqMap ModuleOrigin -> Bool
    originVisible (UniqMap Module ModuleOrigin -> UniqMap Module ModuleOrigin)
    -> Maybe (UniqMap Module ModuleOrigin)
    -> Maybe (UniqMap Module ModuleOrigin)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ModuleNameProvidersMap
    -> ModuleName -> Maybe (UniqMap Module ModuleOrigin)
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap (UnitState -> ModuleNameProvidersMap
    moduleNameProvidersMap UnitState
    unit_st) ModuleName
    mn
      -- 2. Get the UnitIds of the candidates
      let candidates_uid = ((Module, ModuleOrigin) -> [UnitId])
    -> [(Module, ModuleOrigin)] -> [UnitId]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (Module, ModuleOrigin) -> [UnitId]
    to_uid ([(Module, ModuleOrigin)] -> [UnitId])
    -> [(Module, ModuleOrigin)] -> [UnitId]
    forall a b. (a -> b) -> a -> b
    $ ((Module, ModuleOrigin) -> Module)
    -> [(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)]
    forall b a. Ord b => (a -> b) -> [a] -> [a]
    sortOn (Module, ModuleOrigin) -> Module
    forall a b. (a, b) -> a
    fst ([(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)])
    -> [(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)]
    forall a b. (a -> b) -> a -> b
    $ UniqMap Module ModuleOrigin -> [(Module, ModuleOrigin)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList UniqMap Module ModuleOrigin
    providers
      -- 3. Get the package names of the candidates
      let candidates_units = (UnitInfo -> (PackageName, UnitId))
    -> [UnitInfo] -> [(PackageName, UnitId)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\UnitInfo
    ui -> ((UnitInfo -> PackageName
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> srcpkgname
    unitPackageName UnitInfo
    ui), UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    ui))
                                  ([UnitInfo] -> [(PackageName, UnitId)])
    -> [UnitInfo] -> [(PackageName, UnitId)]
    forall a b. (a -> b) -> a -> b
    $ (UnitId -> Maybe UnitInfo) -> [UnitId] -> [UnitInfo]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe (\UnitId
    uid -> UnitInfoMap -> UnitId -> Maybe UnitInfo
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap (UnitState -> UnitInfoMap
    unitInfoMap UnitState
    unit_st) UnitId
    uid) [UnitId]
    candidates_uid
      -- 4. Check to see if the PackageName helps us disambiguate any candidates.
      lookup pn candidates_units

      where

        -- Get the UnitId from which a visible identifier is from
        to_uid :: (Module, ModuleOrigin) -> [UnitId]
        to_uid :: (Module, ModuleOrigin) -> [UnitId]
    to_uid (Module
    mod, ModOrigin Maybe Bool
    mo [UnitInfo]
    re_exps [UnitInfo]
    _ Bool
    _) =
          case Maybe Bool
    mo of
            -- Available directly, but also potentially from re-exports
            Just Bool
    True ->  (Unit -> UnitId
    toUnitId (Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    mod)) UnitId -> [UnitId] -> [UnitId]
    forall a. a -> [a] -> [a]
    : (UnitInfo -> UnitId) -> [UnitInfo] -> [UnitId]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId [UnitInfo]
    re_exps
            -- Just available from these re-exports
            Maybe Bool
    _ -> (UnitInfo -> UnitId) -> [UnitInfo] -> [UnitId]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId [UnitInfo]
    re_exps
        to_uid (Module, ModuleOrigin)
    _ = []

    -- | Create a Map UnitId UnitInfo
    --
    -- For each instantiated unit, we add two map keys:
    --    * the real unit id
    --    * the virtual unit id made from its instantiation
    --
    -- We do the same thing for fully indefinite units (which are "instantiated"
    -- with module holes).
    --
    mkUnitInfoMap :: [UnitInfo] -> UnitInfoMap
    mkUnitInfoMap :: [UnitInfo] -> UnitInfoMap
    mkUnitInfoMap [UnitInfo]
    infos = (UnitInfoMap -> UnitInfo -> UnitInfoMap)
    -> UnitInfoMap -> [UnitInfo] -> UnitInfoMap
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' UnitInfoMap -> UnitInfo -> UnitInfoMap
    forall {srcpkgid} {srcpkgname}.
    UniqMap
      UnitId
      (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    -> GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UniqMap
         UnitId
         (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    add UnitInfoMap
    forall k a. UniqMap k a
    emptyUniqMap [UnitInfo]
    infos
      where
       mkVirt :: GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UnitId
    mkVirt      GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p = GenInstantiatedUnit UnitId -> UnitId
    virtualUnitId (UnitId -> [(ModuleName, Module)] -> GenInstantiatedUnit UnitId
    forall u.
    IsUnitId u =>
    u -> GenInstantiations u -> GenInstantiatedUnit u
    mkInstantiatedUnit (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitInstanceOf GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p) (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> [(ModuleName, Module)]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [(modulename, mod)]
    unitInstantiations GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p))
       add :: UniqMap
      UnitId
      (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    -> GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UniqMap
         UnitId
         (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    add UniqMap
      UnitId
      (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    pkg_map GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p
          | Bool -> Bool
    not ([(ModuleName, Module)] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> [(ModuleName, Module)]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [(modulename, mod)]
    unitInstantiations GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p))
          = UniqMap
      UnitId
      (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    -> UnitId
    -> GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UniqMap
         UnitId
         (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    forall k a. Uniquable k => UniqMap k a -> k -> a -> UniqMap k a
    addToUniqMap (UniqMap
      UnitId
      (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    -> UnitId
    -> GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UniqMap
         UnitId
         (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    forall k a. Uniquable k => UniqMap k a -> k -> a -> UniqMap k a
    addToUniqMap UniqMap
      UnitId
      (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    pkg_map (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UnitId
    forall {srcpkgid} {srcpkgname}.
    GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UnitId
    mkVirt GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p) GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p)
                         (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p) GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p
          | Bool
    otherwise
          = UniqMap
      UnitId
      (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    -> UnitId
    -> GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UniqMap
         UnitId
         (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    forall k a. Uniquable k => UniqMap k a -> k -> a -> UniqMap k a
    addToUniqMap UniqMap
      UnitId
      (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module)
    pkg_map (GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p) GenericUnitInfo srcpkgid srcpkgname UnitId ModuleName Module
    p

    -- | Get a list of entries from the unit database.  NB: be careful with
    -- this function, although all units in this map are "visible", this
    -- does not imply that the exposed-modules of the unit are available
    -- (they may have been thinned or renamed).
    listUnitInfo :: UnitState -> [UnitInfo]
    listUnitInfo :: UnitState -> [UnitInfo]
    listUnitInfo UnitState
    state = UnitInfoMap -> [UnitInfo]
    forall k a. UniqMap k a -> [a]
    nonDetEltsUniqMap (UnitState -> UnitInfoMap
    unitInfoMap UnitState
    state)

    -- ----------------------------------------------------------------------------
    -- Loading the unit db files and building up the unit state

    -- | Read the unit database files, and sets up various internal tables of
    -- unit information, according to the unit-related flags on the
    -- command-line (@-package@, @-hide-package@ etc.)
    --
    -- 'initUnits' can be called again subsequently after updating the
    -- 'packageFlags' field of the 'DynFlags', and it will update the
    -- 'unitState' in 'DynFlags'.
    initUnits :: Logger -> DynFlags -> Maybe [UnitDatabase UnitId] -> Set.Set UnitId -> IO ([UnitDatabase UnitId], UnitState, HomeUnit, Maybe PlatformConstants)
    initUnits :: Logger
    -> DynFlags
    -> Maybe [UnitDatabase UnitId]
    -> Set UnitId
    -> IO
         ([UnitDatabase UnitId], UnitState, HomeUnit,
          Maybe PlatformConstants)
    initUnits Logger
    logger DynFlags
    dflags Maybe [UnitDatabase UnitId]
    cached_dbs Set UnitId
    home_units = do

      let forceUnitInfoMap :: (UnitState, b) -> ()
    forceUnitInfoMap (UnitState
    state, b
    _) = UnitState -> UnitInfoMap
    unitInfoMap UnitState
    state UnitInfoMap -> () -> ()
    forall a b. a -> b -> b
    `seq` ()

      (unit_state,dbs) <- Logger
    -> SDoc
    -> ((UnitState, [UnitDatabase UnitId]) -> ())
    -> IO (UnitState, [UnitDatabase UnitId])
    -> IO (UnitState, [UnitDatabase UnitId])
    forall (m :: * -> *) a.
    MonadIO m =>
    Logger -> SDoc -> (a -> ()) -> m a -> m a
    withTiming Logger
    logger (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "initializing unit database")
                       (UnitState, [UnitDatabase UnitId]) -> ()
    forall {b}. (UnitState, b) -> ()
    forceUnitInfoMap
                     (IO (UnitState, [UnitDatabase UnitId])
     -> IO (UnitState, [UnitDatabase UnitId]))
    -> IO (UnitState, [UnitDatabase UnitId])
    -> IO (UnitState, [UnitDatabase UnitId])
    forall a b. (a -> b) -> a -> b
    $ Logger -> UnitConfig -> IO (UnitState, [UnitDatabase UnitId])
    mkUnitState Logger
    logger (DynFlags -> Maybe [UnitDatabase UnitId] -> Set UnitId -> UnitConfig
    initUnitConfig DynFlags
    dflags Maybe [UnitDatabase UnitId]
    cached_dbs Set UnitId
    home_units)

      putDumpFileMaybe logger Opt_D_dump_mod_map "Module Map"
        FormatText (updSDocContext (\SDocContext
    ctx -> SDocContext
    ctx {sdocLineLength = 200})
                    $ pprModuleMap (moduleNameProvidersMap unit_state))

      let home_unit = UnitState
    -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> HomeUnit
    mkHomeUnit UnitState
    unit_state
                                 (DynFlags -> UnitId
    homeUnitId_ DynFlags
    dflags)
                                 (DynFlags -> Maybe UnitId
    homeUnitInstanceOf_ DynFlags
    dflags)
                                 (DynFlags -> [(ModuleName, Module)]
    homeUnitInstantiations_ DynFlags
    dflags)

      -- Try to find platform constants
      --
      -- See Note [Platform constants] in GHC.Platform
      mconstants <- if homeUnitId_ dflags == rtsUnitId
        then do
          -- we're building the RTS! Lookup GhclibDerivedConstants.h in the include paths
          lookupPlatformConstants (includePathsGlobal (includePaths dflags))
        else
          -- lookup the GhclibDerivedConstants.h header bundled with the RTS unit. We
          -- don't fail if we can't find the RTS unit as it can be a valid (but
          -- uncommon) case, e.g. building a C utility program (not depending on the
          -- RTS) before building the RTS. In any case, we will fail later on if we
          -- really need to use the platform constants but they have not been loaded.
          case lookupUnitId unit_state rtsUnitId of
            Maybe UnitInfo
    Nothing   -> Maybe PlatformConstants -> IO (Maybe PlatformConstants)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe PlatformConstants
    forall a. Maybe a
    Nothing
            Just UnitInfo
    info -> [String] -> IO (Maybe PlatformConstants)
    lookupPlatformConstants ((ShortText -> String) -> [ShortText] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ShortText -> String
    ST.unpack (UnitInfo -> [ShortText]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [ShortText]
    unitIncludeDirs UnitInfo
    info))

      return (dbs,unit_state,home_unit,mconstants)

    mkHomeUnit
        :: UnitState
        -> UnitId                 -- ^ Home unit id
        -> Maybe UnitId           -- ^ Home unit instance of
        -> [(ModuleName, Module)] -- ^ Home unit instantiations
        -> HomeUnit
    mkHomeUnit :: UnitState
    -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> HomeUnit
    mkHomeUnit UnitState
    unit_state UnitId
    hu_id Maybe UnitId
    hu_instanceof [(ModuleName, Module)]
    hu_instantiations_ =
        let
            -- Some wired units can be used to instantiate the home unit. We need to
            -- replace their unit keys with their wired unit ids.
            wmap :: UniqMap UnitId UnitId
    wmap              = UnitState -> UniqMap UnitId UnitId
    wireMap UnitState
    unit_state
            hu_instantiations :: [(ModuleName, Module)]
    hu_instantiations = ((ModuleName, Module) -> (ModuleName, Module))
    -> [(ModuleName, Module)] -> [(ModuleName, Module)]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Module -> Module) -> (ModuleName, Module) -> (ModuleName, Module)
    forall a b. (a -> b) -> (ModuleName, a) -> (ModuleName, b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (UniqMap UnitId UnitId -> Module -> Module
    upd_wired_in_mod UniqMap UnitId UnitId
    wmap)) [(ModuleName, Module)]
    hu_instantiations_
        in case (Maybe UnitId
    hu_instanceof, [(ModuleName, Module)]
    hu_instantiations) of
          (Maybe UnitId
    Nothing,[]) -> UnitId -> Maybe (UnitId, [(ModuleName, Module)]) -> HomeUnit
    forall u. UnitId -> Maybe (u, GenInstantiations u) -> GenHomeUnit u
    DefiniteHomeUnit UnitId
    hu_id Maybe (UnitId, [(ModuleName, Module)])
    forall a. Maybe a
    Nothing
          (Maybe UnitId
    Nothing, [(ModuleName, Module)]
    _) -> GhcException -> HomeUnit
    forall a. GhcException -> a
    throwGhcException (GhcException -> HomeUnit) -> GhcException -> HomeUnit
    forall a b. (a -> b) -> a -> b
    $ String -> GhcException
    CmdLineError (String
    "Use of -instantiated-with requires -this-component-id")
          (Just UnitId
    _, []) -> GhcException -> HomeUnit
    forall a. GhcException -> a
    throwGhcException (GhcException -> HomeUnit) -> GhcException -> HomeUnit
    forall a b. (a -> b) -> a -> b
    $ String -> GhcException
    CmdLineError (String
    "Use of -this-component-id requires -instantiated-with")
          (Just UnitId
    u, [(ModuleName, Module)]
    is)
             -- detect fully indefinite units: all their instantiations are hole
             -- modules and the home unit id is the same as the instantiating unit
             -- id (see Note [About units] in GHC.Unit)
             | ((ModuleName, Module) -> Bool) -> [(ModuleName, Module)] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (Module -> Bool
    forall u. GenModule (GenUnit u) -> Bool
    isHoleModule (Module -> Bool)
    -> ((ModuleName, Module) -> Module) -> (ModuleName, Module) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ModuleName, Module) -> Module
    forall a b. (a, b) -> b
    snd) [(ModuleName, Module)]
    is Bool -> Bool -> Bool
    && UnitId
    u UnitId -> UnitId -> Bool
    forall a. Eq a => a -> a -> Bool
    == UnitId
    hu_id
             -> UnitId -> [(ModuleName, Module)] -> HomeUnit
    forall u. UnitId -> GenInstantiations u -> GenHomeUnit u
    IndefiniteHomeUnit UnitId
    u [(ModuleName, Module)]
    is
             -- otherwise it must be that we (fully) instantiate an indefinite unit
             -- to make it definite.
             -- TODO: error when the unit is partially instantiated??
             | Bool
    otherwise
             -> UnitId -> Maybe (UnitId, [(ModuleName, Module)]) -> HomeUnit
    forall u. UnitId -> Maybe (u, GenInstantiations u) -> GenHomeUnit u
    DefiniteHomeUnit UnitId
    hu_id ((UnitId, [(ModuleName, Module)])
    -> Maybe (UnitId, [(ModuleName, Module)])
    forall a. a -> Maybe a
    Just (UnitId
    u, [(ModuleName, Module)]
    is))

    -- -----------------------------------------------------------------------------
    -- Reading the unit database(s)

    readUnitDatabases :: Logger -> UnitConfig -> IO [UnitDatabase UnitId]
    readUnitDatabases :: Logger -> UnitConfig -> IO [UnitDatabase UnitId]
    readUnitDatabases Logger
    logger UnitConfig
    cfg = do
      conf_refs <- UnitConfig -> IO [PkgDbRef]
    getUnitDbRefs UnitConfig
    cfg
      confs     <- liftM catMaybes $ mapM (resolveUnitDatabase cfg) conf_refs
      mapM (readUnitDatabase logger cfg) confs

    getUnitDbRefs :: UnitConfig -> IO [PkgDbRef]
    getUnitDbRefs :: UnitConfig -> IO [PkgDbRef]
    getUnitDbRefs UnitConfig
    cfg = do
      let system_conf_refs :: [PkgDbRef]
    system_conf_refs = [PkgDbRef
    UserPkgDb, PkgDbRef
    GlobalPkgDb]

      e_pkg_path <- IO String -> IO (Either IOException String)
    forall a. IO a -> IO (Either IOException a)
    tryIO (String -> IO String
    getEnv (String -> IO String) -> String -> IO String
    forall a b. (a -> b) -> a -> b
    $ (Char -> Char) -> String -> String
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> Char
    toUpper (UnitConfig -> String
    unitConfigProgramName UnitConfig
    cfg) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "_PACKAGE_PATH")
      let base_conf_refs = case Either IOException String
    e_pkg_path of
            Left IOException
    _ -> [PkgDbRef]
    system_conf_refs
            Right String
    path
             | Just (String
    xs, Char
    x) <- String -> Maybe (String, Char)
    forall a. [a] -> Maybe ([a], a)
    snocView String
    path, Char -> Bool
    isSearchPathSeparator Char
    x
             -> (String -> PkgDbRef) -> [String] -> [PkgDbRef]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> PkgDbRef
    PkgDbPath (String -> [String]
    splitSearchPath String
    xs) [PkgDbRef] -> [PkgDbRef] -> [PkgDbRef]
    forall a. [a] -> [a] -> [a]
    ++ [PkgDbRef]
    system_conf_refs
             | Bool
    otherwise
             -> (String -> PkgDbRef) -> [String] -> [PkgDbRef]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> PkgDbRef
    PkgDbPath (String -> [String]
    splitSearchPath String
    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 (unitConfigFlagsDB cfg))
     where
      doFlag :: PackageDBFlag -> [PkgDbRef] -> [PkgDbRef]
    doFlag (PackageDB PkgDbRef
    p) [PkgDbRef]
    dbs = PkgDbRef
    p PkgDbRef -> [PkgDbRef] -> [PkgDbRef]
    forall a. a -> [a] -> [a]
    : [PkgDbRef]
    dbs
      doFlag PackageDBFlag
    NoUserPackageDB [PkgDbRef]
    dbs = (PkgDbRef -> Bool) -> [PkgDbRef] -> [PkgDbRef]
    forall a. (a -> Bool) -> [a] -> [a]
    filter PkgDbRef -> Bool
    isNotUser [PkgDbRef]
    dbs
      doFlag PackageDBFlag
    NoGlobalPackageDB [PkgDbRef]
    dbs = (PkgDbRef -> Bool) -> [PkgDbRef] -> [PkgDbRef]
    forall a. (a -> Bool) -> [a] -> [a]
    filter PkgDbRef -> Bool
    isNotGlobal [PkgDbRef]
    dbs
      doFlag PackageDBFlag
    ClearPackageDBs [PkgDbRef]
    _ = []

      isNotUser :: PkgDbRef -> Bool
    isNotUser PkgDbRef
    UserPkgDb = Bool
    False
      isNotUser PkgDbRef
    _ = Bool
    True

      isNotGlobal :: PkgDbRef -> Bool
    isNotGlobal PkgDbRef
    GlobalPkgDb = Bool
    False
      isNotGlobal PkgDbRef
    _ = Bool
    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.)
    resolveUnitDatabase :: UnitConfig -> PkgDbRef -> IO (Maybe FilePath)
    resolveUnitDatabase :: UnitConfig -> PkgDbRef -> IO (Maybe String)
    resolveUnitDatabase UnitConfig
    cfg PkgDbRef
    GlobalPkgDb = Maybe String -> IO (Maybe String)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe String -> IO (Maybe String))
    -> Maybe String -> IO (Maybe String)
    forall a b. (a -> b) -> a -> b
    $ String -> Maybe String
    forall a. a -> Maybe a
    Just (UnitConfig -> String
    unitConfigGlobalDB UnitConfig
    cfg)
    resolveUnitDatabase UnitConfig
    cfg PkgDbRef
    UserPkgDb = MaybeT IO String -> IO (Maybe String)
    forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
    runMaybeT (MaybeT IO String -> IO (Maybe String))
    -> MaybeT IO String -> IO (Maybe String)
    forall a b. (a -> b) -> a -> b
    $ do
      dir <- String -> ArchOS -> MaybeT IO String
    versionedAppDir (UnitConfig -> String
    unitConfigProgramName UnitConfig
    cfg) (UnitConfig -> ArchOS
    unitConfigPlatformArchOS UnitConfig
    cfg)
      let pkgconf = String
    dir String -> String -> String
    </> UnitConfig -> String
    unitConfigDBName UnitConfig
    cfg
      exist <- tryMaybeT $ doesDirectoryExist pkgconf
      if exist then return pkgconf else mzero
    resolveUnitDatabase UnitConfig
    _ (PkgDbPath String
    name) = Maybe String -> IO (Maybe String)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe String -> IO (Maybe String))
    -> Maybe String -> IO (Maybe String)
    forall a b. (a -> b) -> a -> b
    $ String -> Maybe String
    forall a. a -> Maybe a
    Just String
    name

    readUnitDatabase :: Logger -> UnitConfig -> FilePath -> IO (UnitDatabase UnitId)
    readUnitDatabase :: Logger -> UnitConfig -> String -> IO (UnitDatabase UnitId)
    readUnitDatabase Logger
    logger UnitConfig
    cfg String
    conf_file = do
      isdir <- String -> IO Bool
    doesDirectoryExist String
    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 [DbUnitInfo]
    pkgs -> [DbUnitInfo] -> IO [DbUnitInfo]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [DbUnitInfo]
    pkgs
                       Maybe [DbUnitInfo]
    Nothing   -> GhcException -> IO [DbUnitInfo]
    forall a. GhcException -> IO a
    throwGhcExceptionIO (GhcException -> IO [DbUnitInfo])
    -> GhcException -> IO [DbUnitInfo]
    forall a b. (a -> b) -> a -> b
    $ String -> GhcException
    InstallationError (String -> GhcException) -> String -> GhcException
    forall a b. (a -> b) -> a -> b
    $
                          String
    "ghc no longer supports single-file style package " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                          String
    "databases (" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    conf_file String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                          String
    ") use 'ghc-pkg init' to create the database with " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                          String
    "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' = String -> String
    dropTrailingPathSeparator String
    conf_file
          top_dir = UnitConfig -> String
    unitConfigGHCDir UnitConfig
    cfg
          pkgroot = String -> String
    takeDirectory String
    conf_file'
          pkg_configs1 = (DbUnitInfo -> UnitInfo) -> [DbUnitInfo] -> [UnitInfo]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> String -> UnitInfo -> UnitInfo
    mungeUnitInfo String
    top_dir String
    pkgroot (UnitInfo -> UnitInfo)
    -> (DbUnitInfo -> UnitInfo) -> DbUnitInfo -> UnitInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (UnitKey -> UnitId) -> GenUnitInfo UnitKey -> UnitInfo
    forall v u.
    IsUnitId v =>
    (u -> v) -> GenUnitInfo u -> GenUnitInfo v
    mapUnitInfo (\(UnitKey FastString
    x) -> FastString -> UnitId
    UnitId FastString
    x) (GenUnitInfo UnitKey -> UnitInfo)
    -> (DbUnitInfo -> GenUnitInfo UnitKey) -> DbUnitInfo -> UnitInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DbUnitInfo -> GenUnitInfo UnitKey
    mkUnitKeyInfo)
                             [DbUnitInfo]
    proto_pkg_configs
      --
      return $ UnitDatabase conf_file' pkg_configs1
      where
        readDirStyleUnitInfo :: String -> IO [DbUnitInfo]
    readDirStyleUnitInfo String
    conf_dir = do
          let filename :: String
    filename = String
    conf_dir String -> String -> String
    </> String
    "package.cache"
          cache_exists <- String -> IO Bool
    doesFileExist String
    filename
          if cache_exists
            then do
              debugTraceMsg logger 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 logger 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 logger 3 $ text "There are no .conf files in"
                              <+> text conf_dir <> text ", treating"
                              <+> text "package database as empty"
                  return []
                else
                  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 :: IO (Maybe [DbUnitInfo])
    tryReadOldFileStyleUnitInfo = do
          content <- String -> IO String
    readFile String
    conf_file IO String -> (IOException -> IO String) -> IO String
    forall a. IO a -> (IOException -> IO a) -> IO a
    `catchIO` \IOException
    _ -> String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    ""
          if take 2 content == "[]"
            then do
              let conf_dir = String
    conf_file String -> String -> String
    <.> String
    "d"
              direxists <- doesDirectoryExist conf_dir
              if direxists
                 then do debugTraceMsg logger 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 :: [UnitInfo] -> [UnitInfo]
    distrustAllUnits [UnitInfo]
    pkgs = (UnitInfo -> UnitInfo) -> [UnitInfo] -> [UnitInfo]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitInfo -> UnitInfo
    forall {srcpkgid} {srcpkgname} {uid} {modulename} {mod}.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    distrust [UnitInfo]
    pkgs
      where
        distrust :: GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    distrust GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    pkg = GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    pkg{ unitIsTrusted = False }

    mungeUnitInfo :: FilePath -> FilePath
                       -> UnitInfo -> UnitInfo
    mungeUnitInfo :: String -> String -> UnitInfo -> UnitInfo
    mungeUnitInfo String
    top_dir String
    pkgroot =
        UnitInfo -> UnitInfo
    mungeDynLibFields
      (UnitInfo -> UnitInfo)
    -> (UnitInfo -> UnitInfo) -> UnitInfo -> UnitInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ShortText -> ShortText -> UnitInfo -> UnitInfo
    forall a b c d e.
    ShortText
    -> ShortText
    -> GenericUnitInfo a b c d e
    -> GenericUnitInfo a b c d e
    mungeUnitInfoPaths (String -> ShortText
    ST.pack String
    top_dir) (String -> ShortText
    ST.pack String
    pkgroot)

    mungeDynLibFields :: UnitInfo -> UnitInfo
    mungeDynLibFields :: UnitInfo -> UnitInfo
    mungeDynLibFields UnitInfo
    pkg =
        UnitInfo
    pkg {
          unitLibraryDynDirs = case unitLibraryDynDirs pkg of
             [] -> UnitInfo -> [ShortText]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [ShortText]
    unitLibraryDirs UnitInfo
    pkg
             [ShortText]
    ds -> [ShortText]
    ds
        }

    -- -----------------------------------------------------------------------------
    -- Modify our copy of the unit database based on trust flags,
    -- -trust and -distrust.

    applyTrustFlag
       :: UnitPrecedenceMap
       -> UnusableUnits
       -> [UnitInfo]
       -> TrustFlag
       -> MaybeErr UnitErr [UnitInfo]
    applyTrustFlag :: UnitPrecedenceMap
    -> UnusableUnits
    -> [UnitInfo]
    -> TrustFlag
    -> MaybeErr UnitErr [UnitInfo]
    applyTrustFlag UnitPrecedenceMap
    prec_map UnusableUnits
    unusable [UnitInfo]
    pkgs TrustFlag
    flag =
      case TrustFlag
    flag of
        -- we trust all matching packages. Maybe should only trust first one?
        -- and leave others the same or set them untrusted
        TrustPackage String
    str ->
           case UnitPrecedenceMap
    -> PackageArg
    -> [UnitInfo]
    -> UnusableUnits
    -> Either [(UnitInfo, UnusableUnitReason)] ([UnitInfo], [UnitInfo])
    selectPackages UnitPrecedenceMap
    prec_map (String -> PackageArg
    PackageArg String
    str) [UnitInfo]
    pkgs UnusableUnits
    unusable of
             Left [(UnitInfo, UnusableUnitReason)]
    ps       -> UnitErr -> MaybeErr UnitErr [UnitInfo]
    forall err val. err -> MaybeErr err val
    Failed (TrustFlag -> [(UnitInfo, UnusableUnitReason)] -> UnitErr
    TrustFlagErr TrustFlag
    flag [(UnitInfo, UnusableUnitReason)]
    ps)
             Right ([UnitInfo]
    ps,[UnitInfo]
    qs) -> [UnitInfo] -> MaybeErr UnitErr [UnitInfo]
    forall err val. val -> MaybeErr err val
    Succeeded ((UnitInfo -> UnitInfo) -> [UnitInfo] -> [UnitInfo]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitInfo -> UnitInfo
    forall {srcpkgid} {srcpkgname} {uid} {modulename} {mod}.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    trust [UnitInfo]
    ps [UnitInfo] -> [UnitInfo] -> [UnitInfo]
    forall a. [a] -> [a] -> [a]
    ++ [UnitInfo]
    qs)
              where trust :: GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    trust GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    p = GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    p {unitIsTrusted=True}

        DistrustPackage String
    str ->
           case UnitPrecedenceMap
    -> PackageArg
    -> [UnitInfo]
    -> UnusableUnits
    -> Either [(UnitInfo, UnusableUnitReason)] ([UnitInfo], [UnitInfo])
    selectPackages UnitPrecedenceMap
    prec_map (String -> PackageArg
    PackageArg String
    str) [UnitInfo]
    pkgs UnusableUnits
    unusable of
             Left [(UnitInfo, UnusableUnitReason)]
    ps       -> UnitErr -> MaybeErr UnitErr [UnitInfo]
    forall err val. err -> MaybeErr err val
    Failed (TrustFlag -> [(UnitInfo, UnusableUnitReason)] -> UnitErr
    TrustFlagErr TrustFlag
    flag [(UnitInfo, UnusableUnitReason)]
    ps)
             Right ([UnitInfo]
    ps,[UnitInfo]
    qs) -> [UnitInfo] -> MaybeErr UnitErr [UnitInfo]
    forall err val. val -> MaybeErr err val
    Succeeded ([UnitInfo] -> [UnitInfo]
    distrustAllUnits [UnitInfo]
    ps [UnitInfo] -> [UnitInfo] -> [UnitInfo]
    forall a. [a] -> [a] -> [a]
    ++ [UnitInfo]
    qs)

    applyPackageFlag
       :: UnitPrecedenceMap
       -> UnitInfoMap
       -> PreloadUnitClosure
       -> UnusableUnits
       -> 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
       -> MaybeErr UnitErr VisibilityMap -- Now exposed

    applyPackageFlag :: UnitPrecedenceMap
    -> UnitInfoMap
    -> PreloadUnitClosure
    -> UnusableUnits
    -> Bool
    -> [UnitInfo]
    -> VisibilityMap
    -> PackageFlag
    -> MaybeErr UnitErr VisibilityMap
    applyPackageFlag UnitPrecedenceMap
    prec_map UnitInfoMap
    pkg_map PreloadUnitClosure
    closure UnusableUnits
    unusable Bool
    no_hide_others [UnitInfo]
    pkgs VisibilityMap
    vm PackageFlag
    flag =
      case PackageFlag
    flag of
        ExposePackage String
    _ PackageArg
    arg (ModRenaming Bool
    b [(ModuleName, ModuleName)]
    rns) ->
           case UnitPrecedenceMap
    -> UnitInfoMap
    -> PreloadUnitClosure
    -> PackageArg
    -> [UnitInfo]
    -> UnusableUnits
    -> Either [(UnitInfo, UnusableUnitReason)] [UnitInfo]
    findPackages UnitPrecedenceMap
    prec_map UnitInfoMap
    pkg_map PreloadUnitClosure
    closure PackageArg
    arg [UnitInfo]
    pkgs UnusableUnits
    unusable of
             Left [(UnitInfo, UnusableUnitReason)]
    ps     -> UnitErr -> MaybeErr UnitErr VisibilityMap
    forall err val. err -> MaybeErr err val
    Failed (PackageFlag -> [(UnitInfo, UnusableUnitReason)] -> UnitErr
    PackageFlagErr PackageFlag
    flag [(UnitInfo, UnusableUnitReason)]
    ps)
             Right (UnitInfo
    p:[UnitInfo]
    _) -> VisibilityMap -> MaybeErr UnitErr VisibilityMap
    forall err val. val -> MaybeErr err val
    Succeeded VisibilityMap
    vm'
              where
               n :: FastString
    n = UnitInfo -> FastString
    fsPackageName UnitInfo
    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 :: UniqMap ModuleName (Set InstantiatedModule)
    reqs | UnitIdArg Unit
    orig_uid <- PackageArg
    arg = Unit -> UniqMap ModuleName (Set InstantiatedModule)
    forall {u}.
    GenUnit u
    -> UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))
    collectHoles Unit
    orig_uid
                    | Bool
    otherwise                 = UniqMap ModuleName (Set InstantiatedModule)
    forall k a. UniqMap k a
    emptyUniqMap

               collectHoles :: GenUnit u
    -> UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))
    collectHoles GenUnit u
    uid = case GenUnit u
    uid of
                 GenUnit u
    HoleUnit       -> UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))
    forall k a. UniqMap k a
    emptyUniqMap
                 RealUnit {}    -> UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))
    forall k a. UniqMap k a
    emptyUniqMap -- definite units don't have holes
                 VirtUnit GenInstantiatedUnit u
    indef ->
                      let local :: [UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
    local = [ ModuleName
    -> Set (GenModule (GenInstantiatedUnit u))
    -> UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))
    forall k a. Uniquable k => k -> a -> UniqMap k a
    unitUniqMap
                                      (GenModule (GenUnit u) -> ModuleName
    forall unit. GenModule unit -> ModuleName
    moduleName GenModule (GenUnit u)
    mod)
                                      (GenModule (GenInstantiatedUnit u)
    -> Set (GenModule (GenInstantiatedUnit u))
    forall a. a -> Set a
    Set.singleton (GenModule (GenInstantiatedUnit u)
     -> Set (GenModule (GenInstantiatedUnit u)))
    -> GenModule (GenInstantiatedUnit u)
    -> Set (GenModule (GenInstantiatedUnit u))
    forall a b. (a -> b) -> a -> b
    $ GenInstantiatedUnit u
    -> ModuleName -> GenModule (GenInstantiatedUnit u)
    forall unit. unit -> ModuleName -> GenModule unit
    Module GenInstantiatedUnit u
    indef ModuleName
    mod_name)
                                  | (ModuleName
    mod_name, GenModule (GenUnit u)
    mod) <- GenInstantiatedUnit u -> GenInstantiations u
    forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts GenInstantiatedUnit u
    indef
                                  , GenModule (GenUnit u) -> Bool
    forall u. GenModule (GenUnit u) -> Bool
    isHoleModule GenModule (GenUnit u)
    mod ]
                          recurse :: [UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
    recurse = [ GenUnit u
    -> UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))
    collectHoles (GenModule (GenUnit u) -> GenUnit u
    forall unit. GenModule unit -> unit
    moduleUnit GenModule (GenUnit u)
    mod)
                                    | (ModuleName
    _, GenModule (GenUnit u)
    mod) <- GenInstantiatedUnit u -> GenInstantiations u
    forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts GenInstantiatedUnit u
    indef ]
                      in (Set (GenModule (GenInstantiatedUnit u))
     -> Set (GenModule (GenInstantiatedUnit u))
     -> Set (GenModule (GenInstantiatedUnit u)))
    -> [UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
    -> UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))
    forall a k. (a -> a -> a) -> [UniqMap k a] -> UniqMap k a
    plusUniqMapListWith Set (GenModule (GenInstantiatedUnit u))
    -> Set (GenModule (GenInstantiatedUnit u))
    -> Set (GenModule (GenInstantiatedUnit u))
    forall a. Ord a => Set a -> Set a -> Set a
    Set.union ([UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
     -> UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u))))
    -> [UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
    -> UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))
    forall a b. (a -> b) -> a -> b
    $ [UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
    local [UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
    -> [UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
    -> [UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
    forall a. [a] -> [a] -> [a]
    ++ [UniqMap ModuleName (Set (GenModule (GenInstantiatedUnit u)))]
    recurse

               uv :: UnitVisibility
    uv = UnitVisibility
                    { uv_expose_all :: Bool
    uv_expose_all = Bool
    b
                    , uv_renamings :: [(ModuleName, ModuleName)]
    uv_renamings = [(ModuleName, ModuleName)]
    rns
                    , uv_package_name :: First FastString
    uv_package_name = Maybe FastString -> First FastString
    forall a. Maybe a -> First a
    First (FastString -> Maybe FastString
    forall a. a -> Maybe a
    Just FastString
    n)
                    , uv_requirements :: UniqMap ModuleName (Set InstantiatedModule)
    uv_requirements = UniqMap ModuleName (Set InstantiatedModule)
    reqs
                    , uv_explicit :: Maybe PackageArg
    uv_explicit = PackageArg -> Maybe PackageArg
    forall a. a -> Maybe a
    Just PackageArg
    arg
                    }
               vm' :: VisibilityMap
    vm' = (UnitVisibility -> UnitVisibility -> UnitVisibility)
    -> VisibilityMap -> Unit -> UnitVisibility -> VisibilityMap
    forall k a.
    Uniquable k =>
    (a -> a -> a) -> UniqMap k a -> k -> a -> UniqMap k a
    addToUniqMap_C UnitVisibility -> UnitVisibility -> UnitVisibility
    forall a. Monoid a => a -> a -> a
    mappend VisibilityMap
    vm_cleared (UnitInfo -> Unit
    mkUnit UnitInfo
    p) UnitVisibility
    uv
               -- 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 :: VisibilityMap
    vm_cleared | Bool
    no_hide_others = VisibilityMap
    vm
                          -- NB: renamings never clear
                          | ((ModuleName, ModuleName)
    _:[(ModuleName, ModuleName)]
    _) <- [(ModuleName, ModuleName)]
    rns = VisibilityMap
    vm
                          | Bool
    otherwise = (Unit -> UnitVisibility -> Bool) -> VisibilityMap -> VisibilityMap
    forall k a. (k -> a -> Bool) -> UniqMap k a -> UniqMap k a
    filterWithKeyUniqMap
                                (\Unit
    k UnitVisibility
    uv -> Unit
    k Unit -> Unit -> Bool
    forall a. Eq a => a -> a -> Bool
    == UnitInfo -> Unit
    mkUnit UnitInfo
    p
                                       Bool -> Bool -> Bool
    || Maybe FastString -> First FastString
    forall a. Maybe a -> First a
    First (FastString -> Maybe FastString
    forall a. a -> Maybe a
    Just FastString
    n) First FastString -> First FastString -> Bool
    forall a. Eq a => a -> a -> Bool
    /= UnitVisibility -> First FastString
    uv_package_name UnitVisibility
    uv) VisibilityMap
    vm
             Either [(UnitInfo, UnusableUnitReason)] [UnitInfo]
    _ -> String -> MaybeErr UnitErr VisibilityMap
    forall a. HasCallStack => String -> a
    panic String
    "applyPackageFlag"

        HidePackage String
    str ->
           case UnitPrecedenceMap
    -> UnitInfoMap
    -> PreloadUnitClosure
    -> PackageArg
    -> [UnitInfo]
    -> UnusableUnits
    -> Either [(UnitInfo, UnusableUnitReason)] [UnitInfo]
    findPackages UnitPrecedenceMap
    prec_map UnitInfoMap
    pkg_map PreloadUnitClosure
    closure (String -> PackageArg
    PackageArg String
    str) [UnitInfo]
    pkgs UnusableUnits
    unusable of
             Left [(UnitInfo, UnusableUnitReason)]
    ps  -> UnitErr -> MaybeErr UnitErr VisibilityMap
    forall err val. err -> MaybeErr err val
    Failed (PackageFlag -> [(UnitInfo, UnusableUnitReason)] -> UnitErr
    PackageFlagErr PackageFlag
    flag [(UnitInfo, UnusableUnitReason)]
    ps)
             Right [UnitInfo]
    ps -> VisibilityMap -> MaybeErr UnitErr VisibilityMap
    forall err val. val -> MaybeErr err val
    Succeeded (VisibilityMap -> MaybeErr UnitErr VisibilityMap)
    -> VisibilityMap -> MaybeErr UnitErr VisibilityMap
    forall a b. (a -> b) -> a -> b
    $ (VisibilityMap -> Unit -> VisibilityMap)
    -> VisibilityMap -> [Unit] -> VisibilityMap
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' VisibilityMap -> Unit -> VisibilityMap
    forall k a. Uniquable k => UniqMap k a -> k -> UniqMap k a
    delFromUniqMap VisibilityMap
    vm ((UnitInfo -> Unit) -> [UnitInfo] -> [Unit]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitInfo -> Unit
    mkUnit [UnitInfo]
    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 :: UnitPrecedenceMap
                 -> UnitInfoMap
                 -> PreloadUnitClosure
                 -> PackageArg -> [UnitInfo]
                 -> UnusableUnits
                 -> Either [(UnitInfo, UnusableUnitReason)]
                    [UnitInfo]
    findPackages :: UnitPrecedenceMap
    -> UnitInfoMap
    -> PreloadUnitClosure
    -> PackageArg
    -> [UnitInfo]
    -> UnusableUnits
    -> Either [(UnitInfo, UnusableUnitReason)] [UnitInfo]
    findPackages UnitPrecedenceMap
    prec_map UnitInfoMap
    pkg_map PreloadUnitClosure
    closure PackageArg
    arg [UnitInfo]
    pkgs UnusableUnits
    unusable
      = let ps :: [UnitInfo]
    ps = (UnitInfo -> Maybe UnitInfo) -> [UnitInfo] -> [UnitInfo]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe (PackageArg -> UnitInfo -> Maybe UnitInfo
    finder PackageArg
    arg) [UnitInfo]
    pkgs
        in if [UnitInfo] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [UnitInfo]
    ps
            then [(UnitInfo, UnusableUnitReason)]
    -> Either [(UnitInfo, UnusableUnitReason)] [UnitInfo]
    forall a b. a -> Either a b
    Left (((UnitInfo, UnusableUnitReason)
     -> Maybe (UnitInfo, UnusableUnitReason))
    -> [(UnitInfo, UnusableUnitReason)]
    -> [(UnitInfo, UnusableUnitReason)]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe (\(UnitInfo
    x,UnusableUnitReason
    y) -> PackageArg -> UnitInfo -> Maybe UnitInfo
    finder PackageArg
    arg UnitInfo
    x Maybe UnitInfo
    -> (UnitInfo -> Maybe (UnitInfo, UnusableUnitReason))
    -> Maybe (UnitInfo, UnusableUnitReason)
    forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \UnitInfo
    x' -> (UnitInfo, UnusableUnitReason)
    -> Maybe (UnitInfo, UnusableUnitReason)
    forall a. a -> Maybe a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (UnitInfo
    x',UnusableUnitReason
    y))
                                (UnusableUnits -> [(UnitInfo, UnusableUnitReason)]
    forall k a. UniqMap k a -> [a]
    nonDetEltsUniqMap UnusableUnits
    unusable))
            else [UnitInfo] -> Either [(UnitInfo, UnusableUnitReason)] [UnitInfo]
    forall a b. b -> Either a b
    Right (UnitPrecedenceMap -> [UnitInfo] -> [UnitInfo]
    sortByPreference UnitPrecedenceMap
    prec_map [UnitInfo]
    ps)
      where
        finder :: PackageArg -> UnitInfo -> Maybe UnitInfo
    finder (PackageArg String
    str) UnitInfo
    p
          = if String -> UnitInfo -> Bool
    matchingStr String
    str UnitInfo
    p
              then UnitInfo -> Maybe UnitInfo
    forall a. a -> Maybe a
    Just UnitInfo
    p
              else Maybe UnitInfo
    forall a. Maybe a
    Nothing
        finder (UnitIdArg Unit
    uid) UnitInfo
    p
          = case Unit
    uid of
              RealUnit (Definite UnitId
    iuid)
                | UnitId
    iuid UnitId -> UnitId -> Bool
    forall a. Eq a => a -> a -> Bool
    == UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    p
                -> UnitInfo -> Maybe UnitInfo
    forall a. a -> Maybe a
    Just UnitInfo
    p
              VirtUnit GenInstantiatedUnit UnitId
    inst
                | GenInstantiatedUnit UnitId -> UnitId
    forall unit. GenInstantiatedUnit unit -> unit
    instUnitInstanceOf GenInstantiatedUnit UnitId
    inst UnitId -> UnitId -> Bool
    forall a. Eq a => a -> a -> Bool
    == UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    p
                -> UnitInfo -> Maybe UnitInfo
    forall a. a -> Maybe a
    Just (UnitInfoMap
    -> PreloadUnitClosure
    -> [(ModuleName, Module)]
    -> UnitInfo
    -> UnitInfo
    renameUnitInfo UnitInfoMap
    pkg_map PreloadUnitClosure
    closure (GenInstantiatedUnit UnitId -> [(ModuleName, Module)]
    forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts GenInstantiatedUnit UnitId
    inst) UnitInfo
    p)
              Unit
    _ -> Maybe UnitInfo
    forall a. Maybe a
    Nothing

    selectPackages :: UnitPrecedenceMap -> PackageArg -> [UnitInfo]
                   -> UnusableUnits
                   -> Either [(UnitInfo, UnusableUnitReason)]
                      ([UnitInfo], [UnitInfo])
    selectPackages :: UnitPrecedenceMap
    -> PackageArg
    -> [UnitInfo]
    -> UnusableUnits
    -> Either [(UnitInfo, UnusableUnitReason)] ([UnitInfo], [UnitInfo])
    selectPackages UnitPrecedenceMap
    prec_map PackageArg
    arg [UnitInfo]
    pkgs UnusableUnits
    unusable
      = let matches :: UnitInfo -> Bool
    matches = PackageArg -> UnitInfo -> Bool
    matching PackageArg
    arg
            ([UnitInfo]
    ps,[UnitInfo]
    rest) = (UnitInfo -> Bool) -> [UnitInfo] -> ([UnitInfo], [UnitInfo])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition UnitInfo -> Bool
    matches [UnitInfo]
    pkgs
        in if [UnitInfo] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [UnitInfo]
    ps
            then [(UnitInfo, UnusableUnitReason)]
    -> Either [(UnitInfo, UnusableUnitReason)] ([UnitInfo], [UnitInfo])
    forall a b. a -> Either a b
    Left (((UnitInfo, UnusableUnitReason) -> Bool)
    -> [(UnitInfo, UnusableUnitReason)]
    -> [(UnitInfo, UnusableUnitReason)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (UnitInfo -> Bool
    matches(UnitInfo -> Bool)
    -> ((UnitInfo, UnusableUnitReason) -> UnitInfo)
    -> (UnitInfo, UnusableUnitReason)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .(UnitInfo, UnusableUnitReason) -> UnitInfo
    forall a b. (a, b) -> a
    fst) (UnusableUnits -> [(UnitInfo, UnusableUnitReason)]
    forall k a. UniqMap k a -> [a]
    nonDetEltsUniqMap UnusableUnits
    unusable))
            else ([UnitInfo], [UnitInfo])
    -> Either [(UnitInfo, UnusableUnitReason)] ([UnitInfo], [UnitInfo])
    forall a b. b -> Either a b
    Right (UnitPrecedenceMap -> [UnitInfo] -> [UnitInfo]
    sortByPreference UnitPrecedenceMap
    prec_map [UnitInfo]
    ps, [UnitInfo]
    rest)

    -- | Rename a 'UnitInfo' according to some module instantiation.
    renameUnitInfo :: UnitInfoMap -> PreloadUnitClosure -> [(ModuleName, Module)] -> UnitInfo -> UnitInfo
    renameUnitInfo :: UnitInfoMap
    -> PreloadUnitClosure
    -> [(ModuleName, Module)]
    -> UnitInfo
    -> UnitInfo
    renameUnitInfo UnitInfoMap
    pkg_map PreloadUnitClosure
    closure [(ModuleName, Module)]
    insts UnitInfo
    conf =
        let hsubst :: UniqFM ModuleName Module
    hsubst = [(ModuleName, Module)] -> UniqFM ModuleName Module
    forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
    listToUFM [(ModuleName, Module)]
    insts
            smod :: Module -> Module
    smod  = UnitInfoMap
    -> PreloadUnitClosure
    -> UniqFM ModuleName Module
    -> Module
    -> Module
    renameHoleModule' UnitInfoMap
    pkg_map PreloadUnitClosure
    closure UniqFM ModuleName Module
    hsubst
            new_insts :: [(ModuleName, Module)]
    new_insts = ((ModuleName, Module) -> (ModuleName, Module))
    -> [(ModuleName, Module)] -> [(ModuleName, Module)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(ModuleName
    k,Module
    v) -> (ModuleName
    k,Module -> Module
    smod Module
    v)) (UnitInfo -> [(ModuleName, Module)]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [(modulename, mod)]
    unitInstantiations UnitInfo
    conf)
        in UnitInfo
    conf {
            unitInstantiations = new_insts,
            unitExposedModules = map (\(ModuleName
    mod_name, Maybe Module
    mb_mod) -> (ModuleName
    mod_name, (Module -> Module) -> Maybe Module -> Maybe Module
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Module -> Module
    smod Maybe Module
    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 :: String -> UnitInfo -> Bool
    matchingStr String
    str UnitInfo
    p
            =  String
    str String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == UnitInfo -> String
    forall u. GenUnitInfo u -> String
    unitPackageIdString UnitInfo
    p
            Bool -> Bool -> Bool
    || String
    str String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == UnitInfo -> String
    forall u. GenUnitInfo u -> String
    unitPackageNameString UnitInfo
    p

    matchingId :: UnitId -> UnitInfo -> Bool
    matchingId :: UnitId -> UnitInfo -> Bool
    matchingId UnitId
    uid UnitInfo
    p = UnitId
    uid UnitId -> UnitId -> Bool
    forall a. Eq a => a -> a -> Bool
    == UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    p

    matching :: PackageArg -> UnitInfo -> Bool
    matching :: PackageArg -> UnitInfo -> Bool
    matching (PackageArg String
    str) = String -> UnitInfo -> Bool
    matchingStr String
    str
    matching (UnitIdArg (RealUnit (Definite UnitId
    uid))) = UnitId -> UnitInfo -> Bool
    matchingId UnitId
    uid
    matching (UnitIdArg Unit
    _)  = \UnitInfo
    _ -> Bool
    False -- TODO: warn in this case

    -- | This sorts a list of packages, putting "preferred" packages first.
    -- See 'compareByPreference' for the semantics of "preference".
    sortByPreference :: UnitPrecedenceMap -> [UnitInfo] -> [UnitInfo]
    sortByPreference :: UnitPrecedenceMap -> [UnitInfo] -> [UnitInfo]
    sortByPreference UnitPrecedenceMap
    prec_map = (UnitInfo -> UnitInfo -> Ordering) -> [UnitInfo] -> [UnitInfo]
    forall a. (a -> a -> Ordering) -> [a] -> [a]
    sortBy ((UnitInfo -> UnitInfo -> Ordering)
    -> UnitInfo -> UnitInfo -> Ordering
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (UnitPrecedenceMap -> UnitInfo -> UnitInfo -> Ordering
    compareByPreference UnitPrecedenceMap
    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 units
    -- in later unit database.
    compareByPreference
        :: UnitPrecedenceMap
        -> UnitInfo
        -> UnitInfo
        -> Ordering
    compareByPreference :: UnitPrecedenceMap -> UnitInfo -> UnitInfo -> Ordering
    compareByPreference UnitPrecedenceMap
    prec_map UnitInfo
    pkg UnitInfo
    pkg'
      = case (UnitInfo -> Version) -> UnitInfo -> UnitInfo -> Ordering
    forall a t. Ord a => (t -> a) -> t -> t -> Ordering
    comparing UnitInfo -> Version
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> Version
    unitPackageVersion UnitInfo
    pkg UnitInfo
    pkg' of
            Ordering
    GT -> Ordering
    GT
            Ordering
    EQ | Just Int
    prec  <- UnitPrecedenceMap -> UnitId -> Maybe Int
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UnitPrecedenceMap
    prec_map (UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    pkg)
               , Just Int
    prec' <- UnitPrecedenceMap -> UnitId -> Maybe Int
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UnitPrecedenceMap
    prec_map (UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    pkg')
               -- Prefer the unit from the later DB flag (i.e., higher
               -- precedence)
               -> Int -> Int -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Int
    prec Int
    prec'
               | Bool
    otherwise
               -> Ordering
    EQ
            Ordering
    LT -> Ordering
    LT

    comparing :: Ord a => (t -> a) -> t -> t -> Ordering
    comparing :: forall a t. Ord a => (t -> a) -> t -> t -> Ordering
    comparing t -> a
    f t
    a t
    b = t -> a
    f t
    a a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` t -> a
    f t
    b

    pprFlag :: PackageFlag -> SDoc
    pprFlag :: PackageFlag -> SDoc
    pprFlag PackageFlag
    flag = case PackageFlag
    flag of
        HidePackage String
    p   -> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "-hide-package " SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    p
        ExposePackage String
    doc PackageArg
    _ ModRenaming
    _ -> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    doc

    pprTrustFlag :: TrustFlag -> SDoc
    pprTrustFlag :: TrustFlag -> SDoc
    pprTrustFlag TrustFlag
    flag = case TrustFlag
    flag of
        TrustPackage String
    p    -> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "-trust " SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    p
        DistrustPackage String
    p -> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "-distrust " SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    p

    -- -----------------------------------------------------------------------------
    -- Wired-in units
    --
    -- See Note [Wired-in units] in GHC.Unit.Types

    type WiringMap = UniqMap UnitId UnitId

    findWiredInUnits
       :: Logger
       -> UnitPrecedenceMap
       -> [UnitInfo]           -- database
       -> VisibilityMap             -- info on what units are visible
                                    -- for wired in selection
       -> IO ([UnitInfo],  -- unit database updated for wired in
              WiringMap)   -- map from unit id to wired identity

    findWiredInUnits :: Logger
    -> UnitPrecedenceMap
    -> [UnitInfo]
    -> VisibilityMap
    -> IO ([UnitInfo], UniqMap UnitId UnitId)
    findWiredInUnits Logger
    logger UnitPrecedenceMap
    prec_map [UnitInfo]
    pkgs VisibilityMap
    vis_map = do
      -- Now we must find our wired-in units, and rename them to
      -- their canonical names (eg. base-1.0 ==> base), as described
      -- in Note [Wired-in units] in GHC.Unit.Types
      let
            matches :: UnitInfo -> UnitId -> Bool
            UnitInfo
    pc matches :: UnitInfo -> UnitId -> Bool
    `matches` UnitId
    pid = UnitInfo -> PackageName
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> srcpkgname
    unitPackageName UnitInfo
    pc PackageName -> PackageName -> Bool
    forall a. Eq a => a -> a -> Bool
    == FastString -> PackageName
    PackageName (UnitId -> FastString
    unitIdFS UnitId
    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.
            --
            findWiredInUnit :: [UnitInfo] -> UnitId -> IO (Maybe (UnitId, UnitInfo))
            findWiredInUnit :: [UnitInfo] -> UnitId -> IO (Maybe (UnitId, UnitInfo))
    findWiredInUnit [UnitInfo]
    pkgs UnitId
    wired_pkg = [IO (Maybe (UnitId, UnitInfo))] -> IO (Maybe (UnitId, UnitInfo))
    forall (m :: * -> *) (f :: * -> *) a.
    (Monad m, Foldable f) =>
    f (m (Maybe a)) -> m (Maybe a)
    firstJustsM [[UnitInfo] -> IO (Maybe (UnitId, UnitInfo))
    try [UnitInfo]
    all_exposed_ps, [UnitInfo] -> IO (Maybe (UnitId, UnitInfo))
    try [UnitInfo]
    all_ps, IO (Maybe (UnitId, UnitInfo))
    notfound]
              where
                    all_ps :: [UnitInfo]
    all_ps = [ UnitInfo
    p | UnitInfo
    p <- [UnitInfo]
    pkgs, UnitInfo
    p UnitInfo -> UnitId -> Bool
    `matches` UnitId
    wired_pkg ]
                    all_exposed_ps :: [UnitInfo]
    all_exposed_ps = [ UnitInfo
    p | UnitInfo
    p <- [UnitInfo]
    all_ps, (UnitInfo -> Unit
    mkUnit UnitInfo
    p) Unit -> VisibilityMap -> Bool
    forall k a. Uniquable k => k -> UniqMap k a -> Bool
    `elemUniqMap` VisibilityMap
    vis_map ]

                    try :: [UnitInfo] -> IO (Maybe (UnitId, UnitInfo))
    try [UnitInfo]
    ps = case UnitPrecedenceMap -> [UnitInfo] -> [UnitInfo]
    sortByPreference UnitPrecedenceMap
    prec_map [UnitInfo]
    ps of
                        UnitInfo
    p:[UnitInfo]
    _ -> (UnitId, UnitInfo) -> Maybe (UnitId, UnitInfo)
    forall a. a -> Maybe a
    Just ((UnitId, UnitInfo) -> Maybe (UnitId, UnitInfo))
    -> IO (UnitId, UnitInfo) -> IO (Maybe (UnitId, UnitInfo))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> UnitInfo -> IO (UnitId, UnitInfo)
    pick UnitInfo
    p
                        [UnitInfo]
    _ -> Maybe (UnitId, UnitInfo) -> IO (Maybe (UnitId, UnitInfo))
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe (UnitId, UnitInfo)
    forall a. Maybe a
    Nothing

                    notfound :: IO (Maybe (UnitId, UnitInfo))
    notfound = do
                              Logger -> Int -> SDoc -> IO ()
    debugTraceMsg Logger
    logger Int
    2 (SDoc -> IO ()) -> SDoc -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                                String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "wired-in package "
                                     SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext (UnitId -> FastString
    unitIdFS UnitId
    wired_pkg)
                                     SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    " not found."
                              Maybe (UnitId, UnitInfo) -> IO (Maybe (UnitId, UnitInfo))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (UnitId, UnitInfo)
    forall a. Maybe a
    Nothing
                    pick :: UnitInfo -> IO (UnitId, UnitInfo)
                    pick :: UnitInfo -> IO (UnitId, UnitInfo)
    pick UnitInfo
    pkg = do
                            Logger -> Int -> SDoc -> IO ()
    debugTraceMsg Logger
    logger Int
    2 (SDoc -> IO ()) -> SDoc -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                                String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "wired-in package "
                                     SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext (UnitId -> FastString
    unitIdFS UnitId
    wired_pkg)
                                     SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    " mapped to "
                                     SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    pkg)
                            (UnitId, UnitInfo) -> IO (UnitId, UnitInfo)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (UnitId
    wired_pkg, UnitInfo
    pkg)

      mb_wired_in_pkgs <- (UnitId -> IO (Maybe (UnitId, UnitInfo)))
    -> [UnitId] -> IO [Maybe (UnitId, UnitInfo)]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM ([UnitInfo] -> UnitId -> IO (Maybe (UnitId, UnitInfo))
    findWiredInUnit [UnitInfo]
    pkgs) [UnitId]
    wiredInUnitIds
      let
            wired_in_pkgs = [Maybe (UnitId, UnitInfo)] -> [(UnitId, UnitInfo)]
    forall a. [Maybe a] -> [a]
    catMaybes [Maybe (UnitId, UnitInfo)]
    mb_wired_in_pkgs

            wiredInMap :: UniqMap UnitId UnitId
            wiredInMap = [(UnitId, UnitId)] -> UniqMap UnitId UnitId
    forall k a. Uniquable k => [(k, a)] -> UniqMap k a
    listToUniqMap
              [ (UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    realUnitInfo, UnitId
    wiredInUnitId)
              | (UnitId
    wiredInUnitId, UnitInfo
    realUnitInfo) <- [(UnitId, UnitInfo)]
    wired_in_pkgs
              , Bool -> Bool
    not (UnitInfo -> Bool
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> Bool
    unitIsIndefinite UnitInfo
    realUnitInfo)
              ]

            updateWiredInDependencies [GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module]
    pkgs = (GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
     -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module)
    -> [GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module]
    -> [GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module]
    forall a b. (a -> b) -> [a] -> [b]
    map (GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    forall {srcpkgid} {srcpkgname} {modulename}.
    GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    upd_deps (GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
     -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module)
    -> (GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
        -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module)
    -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    forall {srcpkgid} {srcpkgname} {modulename} {mod}.
    GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    upd_pkg) [GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module]
    pkgs
              where upd_pkg :: GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    upd_pkg GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    pkg
                      | Just UnitId
    wiredInUnitId <- UniqMap UnitId UnitId -> UnitId -> Maybe UnitId
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UniqMap UnitId UnitId
    wiredInMap (GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    pkg)
                      = GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    pkg { unitId         = wiredInUnitId
                            , unitInstanceOf = wiredInUnitId
                               -- every non instantiated unit is an instance of
                               -- itself (required by Backpack...)
                               --
                               -- See Note [About units] in GHC.Unit
                            }
                      | Bool
    otherwise
                      = GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    pkg
                    upd_deps :: GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    -> GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    upd_deps GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    pkg = GenericUnitInfo srcpkgid srcpkgname UnitId modulename Module
    pkg {
                          unitDepends = map (upd_wired_in wiredInMap) (unitDepends pkg),
                          unitExposedModules
                            = map (\(modulename
    k,Maybe Module
    v) -> (modulename
    k, (Module -> Module) -> Maybe Module -> Maybe Module
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (UniqMap UnitId UnitId -> Module -> Module
    upd_wired_in_mod UniqMap UnitId UnitId
    wiredInMap) Maybe Module
    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 units] in GHC.Unit.Types.
    --
    -- 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 :: WiringMap -> Module -> Module
    upd_wired_in_mod :: UniqMap UnitId UnitId -> Module -> Module
    upd_wired_in_mod UniqMap UnitId UnitId
    wiredInMap (Module Unit
    uid ModuleName
    m) = Unit -> ModuleName -> Module
    forall unit. unit -> ModuleName -> GenModule unit
    Module (UniqMap UnitId UnitId -> Unit -> Unit
    upd_wired_in_uid UniqMap UnitId UnitId
    wiredInMap Unit
    uid) ModuleName
    m

    upd_wired_in_uid :: WiringMap -> Unit -> Unit
    upd_wired_in_uid :: UniqMap UnitId UnitId -> Unit -> Unit
    upd_wired_in_uid UniqMap UnitId UnitId
    wiredInMap Unit
    u = case Unit
    u of
       Unit
    HoleUnit -> Unit
    forall uid. GenUnit uid
    HoleUnit
       RealUnit (Definite UnitId
    uid) -> Definite UnitId -> Unit
    forall uid. Definite uid -> GenUnit uid
    RealUnit (UnitId -> Definite UnitId
    forall unit. unit -> Definite unit
    Definite (UniqMap UnitId UnitId -> UnitId -> UnitId
    upd_wired_in UniqMap UnitId UnitId
    wiredInMap UnitId
    uid))
       VirtUnit GenInstantiatedUnit UnitId
    indef_uid ->
          GenInstantiatedUnit UnitId -> Unit
    forall uid. GenInstantiatedUnit uid -> GenUnit uid
    VirtUnit (GenInstantiatedUnit UnitId -> Unit)
    -> GenInstantiatedUnit UnitId -> Unit
    forall a b. (a -> b) -> a -> b
    $ UnitId -> [(ModuleName, Module)] -> GenInstantiatedUnit UnitId
    forall u.
    IsUnitId u =>
    u -> GenInstantiations u -> GenInstantiatedUnit u
    mkInstantiatedUnit
            (GenInstantiatedUnit UnitId -> UnitId
    forall unit. GenInstantiatedUnit unit -> unit
    instUnitInstanceOf GenInstantiatedUnit UnitId
    indef_uid)
            (((ModuleName, Module) -> (ModuleName, Module))
    -> [(ModuleName, Module)] -> [(ModuleName, Module)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(ModuleName
    x,Module
    y) -> (ModuleName
    x,UniqMap UnitId UnitId -> Module -> Module
    upd_wired_in_mod UniqMap UnitId UnitId
    wiredInMap Module
    y)) (GenInstantiatedUnit UnitId -> [(ModuleName, Module)]
    forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts GenInstantiatedUnit UnitId
    indef_uid))

    upd_wired_in :: WiringMap -> UnitId -> UnitId
    upd_wired_in :: UniqMap UnitId UnitId -> UnitId -> UnitId
    upd_wired_in UniqMap UnitId UnitId
    wiredInMap UnitId
    key
        | Just UnitId
    key' <- UniqMap UnitId UnitId -> UnitId -> Maybe UnitId
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UniqMap UnitId UnitId
    wiredInMap UnitId
    key = UnitId
    key'
        | Bool
    otherwise = UnitId
    key

    updateVisibilityMap :: WiringMap -> VisibilityMap -> VisibilityMap
    updateVisibilityMap :: UniqMap UnitId UnitId -> VisibilityMap -> VisibilityMap
    updateVisibilityMap UniqMap UnitId UnitId
    wiredInMap VisibilityMap
    vis_map = (VisibilityMap -> (UnitId, UnitId) -> VisibilityMap)
    -> VisibilityMap -> [(UnitId, UnitId)] -> VisibilityMap
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' VisibilityMap -> (UnitId, UnitId) -> VisibilityMap
    f VisibilityMap
    vis_map (UniqMap UnitId UnitId -> [(UnitId, UnitId)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList UniqMap UnitId UnitId
    wiredInMap)
      where f :: VisibilityMap -> (UnitId, UnitId) -> VisibilityMap
    f VisibilityMap
    vm (UnitId
    from, UnitId
    to) = case VisibilityMap -> Unit -> Maybe UnitVisibility
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap VisibilityMap
    vis_map (Definite UnitId -> Unit
    forall uid. Definite uid -> GenUnit uid
    RealUnit (UnitId -> Definite UnitId
    forall unit. unit -> Definite unit
    Definite UnitId
    from)) of
                        Maybe UnitVisibility
    Nothing -> VisibilityMap
    vm
                        Just UnitVisibility
    r -> VisibilityMap -> Unit -> UnitVisibility -> VisibilityMap
    forall k a. Uniquable k => UniqMap k a -> k -> a -> UniqMap k a
    addToUniqMap (VisibilityMap -> Unit -> VisibilityMap
    forall k a. Uniquable k => UniqMap k a -> k -> UniqMap k a
    delFromUniqMap VisibilityMap
    vm (Definite UnitId -> Unit
    forall uid. Definite uid -> GenUnit uid
    RealUnit (UnitId -> Definite UnitId
    forall unit. unit -> Definite unit
    Definite UnitId
    from)))
                                  (Definite UnitId -> Unit
    forall uid. Definite uid -> GenUnit uid
    RealUnit (UnitId -> Definite UnitId
    forall unit. unit -> Definite unit
    Definite UnitId
    to)) UnitVisibility
    r

      -- ----------------------------------------------------------------------------

    -- | The reason why a unit is unusable.
    data UnusableUnitReason
      = -- | We ignored it explicitly using @-ignore-package@.
        IgnoredWithFlag
        -- | This unit transitively depends on a unit that was never present
        -- in any of the provided databases.
      | BrokenDependencies   [UnitId]
        -- | This unit transitively depends on a unit involved in a cycle.
        -- Note that the list of 'UnitId' reports the direct dependencies
        -- of this unit that (transitively) depended on the cycle, and not
        -- the actual cycle itself (which we report separately at high verbosity.)
      | CyclicDependencies   [UnitId]
        -- | This unit transitively depends on a unit which was ignored.
      | IgnoredDependencies  [UnitId]
        -- | This unit transitively depends on a unit which was
        -- shadowed by an ABI-incompatible unit.
      | ShadowedDependencies [UnitId]

    instance Outputable UnusableUnitReason where
        ppr :: UnusableUnitReason -> SDoc
    ppr UnusableUnitReason
    IgnoredWithFlag = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "[ignored with flag]"
        ppr (BrokenDependencies [UnitId]
    uids)   = SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    brackets (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "broken" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [UnitId] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [UnitId]
    uids)
        ppr (CyclicDependencies [UnitId]
    uids)   = SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    brackets (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "cyclic" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [UnitId] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [UnitId]
    uids)
        ppr (IgnoredDependencies [UnitId]
    uids)  = SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    brackets (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "ignored" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [UnitId] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [UnitId]
    uids)
        ppr (ShadowedDependencies [UnitId]
    uids) = SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    brackets (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "shadowed" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [UnitId] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [UnitId]
    uids)

    type UnusableUnits = UniqMap UnitId (UnitInfo, UnusableUnitReason)

    pprReason :: SDoc -> UnusableUnitReason -> SDoc
    pprReason :: SDoc -> UnusableUnitReason -> SDoc
    pprReason SDoc
    pref UnusableUnitReason
    reason = case UnusableUnitReason
    reason of
      UnusableUnitReason
    IgnoredWithFlag ->
          SDoc
    pref SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "ignored due to an -ignore-package flag"
      BrokenDependencies [UnitId]
    deps ->
          SDoc
    pref SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "unusable due to missing dependencies:" SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$
            Int -> SDoc -> SDoc
    nest Int
    2 ([SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep ((UnitId -> SDoc) -> [UnitId] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [UnitId]
    deps))
      CyclicDependencies [UnitId]
    deps ->
          SDoc
    pref SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "unusable due to cyclic dependencies:" SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$
            Int -> SDoc -> SDoc
    nest Int
    2 ([SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep ((UnitId -> SDoc) -> [UnitId] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [UnitId]
    deps))
      IgnoredDependencies [UnitId]
    deps ->
          SDoc
    pref SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text (String
    "unusable because the -ignore-package flag was used to " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                         String
    "ignore at least one of its dependencies:") SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$
            Int -> SDoc -> SDoc
    nest Int
    2 ([SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep ((UnitId -> SDoc) -> [UnitId] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [UnitId]
    deps))
      ShadowedDependencies [UnitId]
    deps ->
          SDoc
    pref SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "unusable due to shadowed dependencies:" SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$
            Int -> SDoc -> SDoc
    nest Int
    2 ([SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep ((UnitId -> SDoc) -> [UnitId] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr [UnitId]
    deps))

    reportCycles :: Logger -> [SCC UnitInfo] -> IO ()
    reportCycles :: Logger -> [SCC UnitInfo] -> IO ()
    reportCycles Logger
    logger [SCC UnitInfo]
    sccs = (SCC UnitInfo -> IO ()) -> [SCC UnitInfo] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ SCC UnitInfo -> IO ()
    report [SCC UnitInfo]
    sccs
      where
        report :: SCC UnitInfo -> IO ()
    report (AcyclicSCC UnitInfo
    _) = () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
        report (CyclicSCC [UnitInfo]
    vs) =
            Logger -> Int -> SDoc -> IO ()
    debugTraceMsg Logger
    logger Int
    2 (SDoc -> IO ()) -> SDoc -> IO ()
    forall a b. (a -> b) -> a -> b
    $
              String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "these packages are involved in a cycle:" SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$
                Int -> SDoc -> SDoc
    nest Int
    2 ([SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep ((UnitInfo -> SDoc) -> [UnitInfo] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (UnitId -> SDoc) -> (UnitInfo -> UnitId) -> UnitInfo -> SDoc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId) [UnitInfo]
    vs))

    reportUnusable :: Logger -> UnusableUnits -> IO ()
    reportUnusable :: Logger -> UnusableUnits -> IO ()
    reportUnusable Logger
    logger UnusableUnits
    pkgs = ((UnitId, (UnitInfo, UnusableUnitReason)) -> IO ())
    -> [(UnitId, (UnitInfo, UnusableUnitReason))] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ (UnitId, (UnitInfo, UnusableUnitReason)) -> IO ()
    report (UnusableUnits -> [(UnitId, (UnitInfo, UnusableUnitReason))]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList UnusableUnits
    pkgs)
      where
        report :: (UnitId, (UnitInfo, UnusableUnitReason)) -> IO ()
    report (UnitId
    ipid, (UnitInfo
    _, UnusableUnitReason
    reason)) =
           Logger -> Int -> SDoc -> IO ()
    debugTraceMsg Logger
    logger Int
    2 (SDoc -> IO ()) -> SDoc -> IO ()
    forall a b. (a -> b) -> a -> b
    $
             SDoc -> UnusableUnitReason -> SDoc
    pprReason
               (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "package" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr UnitId
    ipid SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "is") UnusableUnitReason
    reason

    -- ----------------------------------------------------------------------------
    --
    -- Utilities on the database
    --

    -- | A reverse dependency index, mapping an 'UnitId' to
    -- the 'UnitId's which have a dependency on it.
    type RevIndex = UniqMap UnitId [UnitId]

    -- | Compute the reverse dependency index of a unit database.
    reverseDeps :: UnitInfoMap -> RevIndex
    reverseDeps :: UnitInfoMap -> RevIndex
    reverseDeps UnitInfoMap
    db = ((UnitId, UnitInfo) -> RevIndex -> RevIndex)
    -> RevIndex -> UnitInfoMap -> RevIndex
    forall k a b. ((k, a) -> b -> b) -> b -> UniqMap k a -> b
    nonDetFoldUniqMap (UnitId, UnitInfo) -> RevIndex -> RevIndex
    go RevIndex
    forall k a. UniqMap k a
    emptyUniqMap UnitInfoMap
    db
      where
        go :: (UnitId, UnitInfo) -> RevIndex -> RevIndex
        go :: (UnitId, UnitInfo) -> RevIndex -> RevIndex
    go (UnitId
    _uid, UnitInfo
    pkg) RevIndex
    r = (RevIndex -> UnitId -> RevIndex)
    -> RevIndex -> [UnitId] -> RevIndex
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' (UnitId -> RevIndex -> UnitId -> RevIndex
    forall {k} {a}.
    Uniquable k =>
    a -> UniqMap k [a] -> k -> UniqMap k [a]
    go' (UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    pkg)) RevIndex
    r (UnitInfo -> [UnitId]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> [uid]
    unitDepends UnitInfo
    pkg)
        go' :: a -> UniqMap k [a] -> k -> UniqMap k [a]
    go' a
    from UniqMap k [a]
    r k
    to = ([a] -> [a] -> [a]) -> UniqMap k [a] -> k -> [a] -> UniqMap k [a]
    forall k a.
    Uniquable k =>
    (a -> a -> a) -> UniqMap k a -> k -> a -> UniqMap k a
    addToUniqMap_C [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    (++) UniqMap k [a]
    r k
    to [a
    from]

    -- | Given a list of 'UnitId's to remove, a database,
    -- and a reverse dependency index (as computed by 'reverseDeps'),
    -- remove those units, plus any units which depend on them.
    -- Returns the pruned database, as well as a list of 'UnitInfo's
    -- that was removed.
    removeUnits :: [UnitId] -> RevIndex
                   -> UnitInfoMap
                   -> (UnitInfoMap, [UnitInfo])
    removeUnits :: [UnitId] -> RevIndex -> UnitInfoMap -> (UnitInfoMap, [UnitInfo])
    removeUnits [UnitId]
    uids RevIndex
    index UnitInfoMap
    m = [UnitId] -> (UnitInfoMap, [UnitInfo]) -> (UnitInfoMap, [UnitInfo])
    go [UnitId]
    uids (UnitInfoMap
    m,[])
      where
        go :: [UnitId] -> (UnitInfoMap, [UnitInfo]) -> (UnitInfoMap, [UnitInfo])
    go [] (UnitInfoMap
    m,[UnitInfo]
    pkgs) = (UnitInfoMap
    m,[UnitInfo]
    pkgs)
        go (UnitId
    uid:[UnitId]
    uids) (UnitInfoMap
    m,[UnitInfo]
    pkgs)
            | Just UnitInfo
    pkg <- UnitInfoMap -> UnitId -> Maybe UnitInfo
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UnitInfoMap
    m UnitId
    uid
            = case RevIndex -> UnitId -> Maybe [UnitId]
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap RevIndex
    index UnitId
    uid of
                Maybe [UnitId]
    Nothing    -> [UnitId] -> (UnitInfoMap, [UnitInfo]) -> (UnitInfoMap, [UnitInfo])
    go [UnitId]
    uids (UnitInfoMap -> UnitId -> UnitInfoMap
    forall k a. Uniquable k => UniqMap k a -> k -> UniqMap k a
    delFromUniqMap UnitInfoMap
    m UnitId
    uid, UnitInfo
    pkgUnitInfo -> [UnitInfo] -> [UnitInfo]
    forall a. a -> [a] -> [a]
    :[UnitInfo]
    pkgs)
                Just [UnitId]
    rdeps -> [UnitId] -> (UnitInfoMap, [UnitInfo]) -> (UnitInfoMap, [UnitInfo])
    go ([UnitId]
    rdeps [UnitId] -> [UnitId] -> [UnitId]
    forall a. [a] -> [a] -> [a]
    ++ [UnitId]
    uids) (UnitInfoMap -> UnitId -> UnitInfoMap
    forall k a. Uniquable k => UniqMap k a -> k -> UniqMap k a
    delFromUniqMap UnitInfoMap
    m UnitId
    uid, UnitInfo
    pkgUnitInfo -> [UnitInfo] -> [UnitInfo]
    forall a. a -> [a] -> [a]
    :[UnitInfo]
    pkgs)
            | Bool
    otherwise
            = [UnitId] -> (UnitInfoMap, [UnitInfo]) -> (UnitInfoMap, [UnitInfo])
    go [UnitId]
    uids (UnitInfoMap
    m,[UnitInfo]
    pkgs)

    -- | Given a 'UnitInfo' from some 'UnitInfoMap', return all entries in 'depends'
    -- which correspond to units that do not exist in the index.
    depsNotAvailable :: UnitInfoMap
                     -> UnitInfo
                     -> [UnitId]
    depsNotAvailable :: UnitInfoMap -> UnitInfo -> [UnitId]
    depsNotAvailable UnitInfoMap
    pkg_map UnitInfo
    pkg = (UnitId -> Bool) -> [UnitId] -> [UnitId]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (UnitId -> Bool) -> UnitId -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (UnitId -> UnitInfoMap -> Bool
    forall k a. Uniquable k => k -> UniqMap k a -> Bool
    `elemUniqMap` UnitInfoMap
    pkg_map)) (UnitInfo -> [UnitId]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> [uid]
    unitDepends UnitInfo
    pkg)

    -- | Given a 'UnitInfo' from some 'UnitInfoMap' return all entries in
    -- 'unitAbiDepends' which correspond to units that do not exist, OR have
    -- mismatching ABIs.
    depsAbiMismatch :: UnitInfoMap
                    -> UnitInfo
                    -> [UnitId]
    depsAbiMismatch :: UnitInfoMap -> UnitInfo -> [UnitId]
    depsAbiMismatch UnitInfoMap
    pkg_map UnitInfo
    pkg = ((UnitId, ShortText) -> UnitId)
    -> [(UnitId, ShortText)] -> [UnitId]
    forall a b. (a -> b) -> [a] -> [b]
    map (UnitId, ShortText) -> UnitId
    forall a b. (a, b) -> a
    fst ([(UnitId, ShortText)] -> [UnitId])
    -> ([(UnitId, ShortText)] -> [(UnitId, ShortText)])
    -> [(UnitId, ShortText)]
    -> [UnitId]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((UnitId, ShortText) -> Bool)
    -> [(UnitId, ShortText)] -> [(UnitId, ShortText)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool)
    -> ((UnitId, ShortText) -> Bool) -> (UnitId, ShortText) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (UnitId, ShortText) -> Bool
    abiMatch) ([(UnitId, ShortText)] -> [UnitId])
    -> [(UnitId, ShortText)] -> [UnitId]
    forall a b. (a -> b) -> a -> b
    $ UnitInfo -> [(UnitId, ShortText)]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [(uid, ShortText)]
    unitAbiDepends UnitInfo
    pkg
      where
        abiMatch :: (UnitId, ShortText) -> Bool
    abiMatch (UnitId
    dep_uid, ShortText
    abi)
            | Just UnitInfo
    dep_pkg <- UnitInfoMap -> UnitId -> Maybe UnitInfo
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap UnitInfoMap
    pkg_map UnitId
    dep_uid
            = UnitInfo -> ShortText
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> ShortText
    unitAbiHash UnitInfo
    dep_pkg ShortText -> ShortText -> Bool
    forall a. Eq a => a -> a -> Bool
    == ShortText
    abi
            | Bool
    otherwise
            = Bool
    False

    -- -----------------------------------------------------------------------------
    -- Ignore units

    ignoreUnits :: [IgnorePackageFlag] -> [UnitInfo] -> UnusableUnits
    ignoreUnits :: [IgnorePackageFlag] -> [UnitInfo] -> UnusableUnits
    ignoreUnits [IgnorePackageFlag]
    flags [UnitInfo]
    pkgs = [(UnitId, (UnitInfo, UnusableUnitReason))] -> UnusableUnits
    forall k a. Uniquable k => [(k, a)] -> UniqMap k a
    listToUniqMap ((IgnorePackageFlag -> [(UnitId, (UnitInfo, UnusableUnitReason))])
    -> [IgnorePackageFlag]
    -> [(UnitId, (UnitInfo, UnusableUnitReason))]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap IgnorePackageFlag -> [(UnitId, (UnitInfo, UnusableUnitReason))]
    doit [IgnorePackageFlag]
    flags)
      where
      doit :: IgnorePackageFlag -> [(UnitId, (UnitInfo, UnusableUnitReason))]
    doit (IgnorePackage String
    str) =
         case (UnitInfo -> Bool) -> [UnitInfo] -> ([UnitInfo], [UnitInfo])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition (String -> UnitInfo -> Bool
    matchingStr String
    str) [UnitInfo]
    pkgs of
             ([UnitInfo]
    ps, [UnitInfo]
    _) -> [ (UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    p, (UnitInfo
    p, UnusableUnitReason
    IgnoredWithFlag))
                        | UnitInfo
    p <- [UnitInfo]
    ps ]
            -- missing unit 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 unit, a mapping from uid -> i indicates that this
    -- unit was brought into GHC by the ith @-package-db@ flag on
    -- the command line.  We use this mapping to make sure we prefer
    -- units that were defined later on the command line, if there
    -- is an ambiguity.
    type UnitPrecedenceMap = UniqMap UnitId Int

    -- | Given a list of databases, merge them together, where
    -- units 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 :: Logger -> [UnitDatabase UnitId]
                   -> IO (UnitInfoMap, UnitPrecedenceMap)
    mergeDatabases :: Logger
    -> [UnitDatabase UnitId] -> IO (UnitInfoMap, UnitPrecedenceMap)
    mergeDatabases Logger
    logger = ((UnitInfoMap, UnitPrecedenceMap)
     -> (Int, UnitDatabase UnitId)
     -> IO (UnitInfoMap, UnitPrecedenceMap))
    -> (UnitInfoMap, UnitPrecedenceMap)
    -> [(Int, UnitDatabase UnitId)]
    -> IO (UnitInfoMap, UnitPrecedenceMap)
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldM (UnitInfoMap, UnitPrecedenceMap)
    -> (Int, UnitDatabase UnitId)
    -> IO (UnitInfoMap, UnitPrecedenceMap)
    merge (UnitInfoMap
    forall k a. UniqMap k a
    emptyUniqMap, UnitPrecedenceMap
    forall k a. UniqMap k a
    emptyUniqMap) ([(Int, UnitDatabase UnitId)]
     -> IO (UnitInfoMap, UnitPrecedenceMap))
    -> ([UnitDatabase UnitId] -> [(Int, UnitDatabase UnitId)])
    -> [UnitDatabase UnitId]
    -> IO (UnitInfoMap, UnitPrecedenceMap)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Int] -> [UnitDatabase UnitId] -> [(Int, UnitDatabase UnitId)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Int
    1..]
      where
        merge :: (UnitInfoMap, UnitPrecedenceMap)
    -> (Int, UnitDatabase UnitId)
    -> IO (UnitInfoMap, UnitPrecedenceMap)
    merge (UnitInfoMap
    pkg_map, UnitPrecedenceMap
    prec_map) (Int
    i, UnitDatabase String
    db_path [UnitInfo]
    db) = do
          Logger -> Int -> SDoc -> IO ()
    debugTraceMsg Logger
    logger Int
    2 (SDoc -> IO ()) -> SDoc -> IO ()
    forall a b. (a -> b) -> a -> b
    $
              String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "loading package database" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    db_path
          [UnitId] -> (UnitId -> IO ()) -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ (Set UnitId -> [UnitId]
    forall a. Set a -> [a]
    Set.toList Set UnitId
    override_set) ((UnitId -> IO ()) -> IO ()) -> (UnitId -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \UnitId
    pkg ->
              Logger -> Int -> SDoc -> IO ()
    debugTraceMsg Logger
    logger Int
    2 (SDoc -> IO ()) -> SDoc -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                  String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "package" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr UnitId
    pkg SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+>
                  String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "overrides a previously defined package"
          (UnitInfoMap, UnitPrecedenceMap)
    -> IO (UnitInfoMap, UnitPrecedenceMap)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (UnitInfoMap
    pkg_map', UnitPrecedenceMap
    prec_map')
         where
          db_map :: UnitInfoMap
    db_map = [UnitInfo] -> UnitInfoMap
    forall {srcpkgid} {srcpkgname} {modulename} {mod}.
    [GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod]
    -> UniqMap
         UnitId (GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod)
    mk_pkg_map [UnitInfo]
    db
          mk_pkg_map :: [GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod]
    -> UniqMap
         UnitId (GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod)
    mk_pkg_map = [(UnitId,
      GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod)]
    -> UniqMap
         UnitId (GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod)
    forall k a. Uniquable k => [(k, a)] -> UniqMap k a
    listToUniqMap ([(UnitId,
       GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod)]
     -> UniqMap
          UnitId (GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod))
    -> ([GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod]
        -> [(UnitId,
             GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod)])
    -> [GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod]
    -> UniqMap
         UnitId (GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
     -> (UnitId,
         GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod))
    -> [GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod]
    -> [(UnitId,
         GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    p -> (GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    p, GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    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 UnitId
    override_set = Set UnitId -> Set UnitId -> Set UnitId
    forall a. Ord a => Set a -> Set a -> Set a
    Set.intersection (UnitInfoMap -> Set UnitId
    forall k a. Ord k => UniqMap k a -> Set k
    nonDetUniqMapToKeySet UnitInfoMap
    db_map)
                                          (UnitInfoMap -> Set UnitId
    forall k a. Ord k => UniqMap k a -> Set k
    nonDetUniqMapToKeySet UnitInfoMap
    pkg_map)

          -- Now merge the sets together (NB: in case of duplicate,
          -- first argument preferred)
          pkg_map' :: UnitInfoMap
          pkg_map' :: UnitInfoMap
    pkg_map' = UnitInfoMap
    pkg_map UnitInfoMap -> UnitInfoMap -> UnitInfoMap
    forall k a. UniqMap k a -> UniqMap k a -> UniqMap k a
    `plusUniqMap` UnitInfoMap
    db_map

          prec_map' :: UnitPrecedenceMap
          prec_map' :: UnitPrecedenceMap
    prec_map' = UnitPrecedenceMap
    prec_map UnitPrecedenceMap -> UnitPrecedenceMap -> UnitPrecedenceMap
    forall k a. UniqMap k a -> UniqMap k a -> UniqMap k a
    `plusUniqMap` ((UnitInfo -> Int) -> UnitInfoMap -> UnitPrecedenceMap
    forall a b k. (a -> b) -> UniqMap k a -> UniqMap k b
    mapUniqMap (Int -> UnitInfo -> Int
    forall a b. a -> b -> a
    const Int
    i) UnitInfoMap
    db_map)

    -- | Validates a database, removing unusable units from it
    -- (this includes removing units that the user has explicitly
    -- ignored.)  Our general strategy:
    --
    -- 1. Remove all broken units (dangling dependencies)
    -- 2. Remove all units that are cyclic
    -- 3. Apply ignore flags
    -- 4. Remove all units which have deps with mismatching ABIs
    --
    validateDatabase :: UnitConfig -> UnitInfoMap
                     -> (UnitInfoMap, UnusableUnits, [SCC UnitInfo])
    validateDatabase :: UnitConfig
    -> UnitInfoMap -> (UnitInfoMap, UnusableUnits, [SCC UnitInfo])
    validateDatabase UnitConfig
    cfg UnitInfoMap
    pkg_map1 =
        (UnitInfoMap
    pkg_map5, UnusableUnits
    unusable, [SCC UnitInfo]
    sccs)
      where
        ignore_flags :: [IgnorePackageFlag]
    ignore_flags = [IgnorePackageFlag] -> [IgnorePackageFlag]
    forall a. [a] -> [a]
    reverse (UnitConfig -> [IgnorePackageFlag]
    unitConfigFlagsIgnored UnitConfig
    cfg)

        -- Compute the reverse dependency index
        index :: RevIndex
    index = UnitInfoMap -> RevIndex
    reverseDeps UnitInfoMap
    pkg_map1

        -- Helper function
        mk_unusable :: (t -> b)
    -> (t -> GenericUnitInfo srcpkgid srcpkgname k modulename mod -> t)
    -> t
    -> [GenericUnitInfo srcpkgid srcpkgname k modulename mod]
    -> UniqMap
         k (GenericUnitInfo srcpkgid srcpkgname k modulename mod, b)
    mk_unusable t -> b
    mk_err t -> GenericUnitInfo srcpkgid srcpkgname k modulename mod -> t
    dep_matcher t
    m [GenericUnitInfo srcpkgid srcpkgname k modulename mod]
    uids =
          [(k, (GenericUnitInfo srcpkgid srcpkgname k modulename mod, b))]
    -> UniqMap
         k (GenericUnitInfo srcpkgid srcpkgname k modulename mod, b)
    forall k a. Uniquable k => [(k, a)] -> UniqMap k a
    listToUniqMap [ (GenericUnitInfo srcpkgid srcpkgname k modulename mod -> k
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId GenericUnitInfo srcpkgid srcpkgname k modulename mod
    pkg, (GenericUnitInfo srcpkgid srcpkgname k modulename mod
    pkg, t -> b
    mk_err (t -> GenericUnitInfo srcpkgid srcpkgname k modulename mod -> t
    dep_matcher t
    m GenericUnitInfo srcpkgid srcpkgname k modulename mod
    pkg)))
                        | GenericUnitInfo srcpkgid srcpkgname k modulename mod
    pkg <- [GenericUnitInfo srcpkgid srcpkgname k modulename mod]
    uids
                        ]

        -- Find broken units
        directly_broken :: [UnitInfo]
    directly_broken = (UnitInfo -> Bool) -> [UnitInfo] -> [UnitInfo]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (UnitInfo -> Bool) -> UnitInfo -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [UnitId] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([UnitId] -> Bool) -> (UnitInfo -> [UnitId]) -> UnitInfo -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitInfoMap -> UnitInfo -> [UnitId]
    depsNotAvailable UnitInfoMap
    pkg_map1)
                                 (UnitInfoMap -> [UnitInfo]
    forall k a. UniqMap k a -> [a]
    nonDetEltsUniqMap UnitInfoMap
    pkg_map1)
        (UnitInfoMap
    pkg_map2, [UnitInfo]
    broken) = [UnitId] -> RevIndex -> UnitInfoMap -> (UnitInfoMap, [UnitInfo])
    removeUnits ((UnitInfo -> UnitId) -> [UnitInfo] -> [UnitId]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId [UnitInfo]
    directly_broken) RevIndex
    index UnitInfoMap
    pkg_map1
        unusable_broken :: UnusableUnits
    unusable_broken = ([UnitId] -> UnusableUnitReason)
    -> (UnitInfoMap -> UnitInfo -> [UnitId])
    -> UnitInfoMap
    -> [UnitInfo]
    -> UnusableUnits
    forall {k} {t} {b} {t} {srcpkgid} {srcpkgname} {modulename} {mod}.
    Uniquable k =>
    (t -> b)
    -> (t -> GenericUnitInfo srcpkgid srcpkgname k modulename mod -> t)
    -> t
    -> [GenericUnitInfo srcpkgid srcpkgname k modulename mod]
    -> UniqMap
         k (GenericUnitInfo srcpkgid srcpkgname k modulename mod, b)
    mk_unusable [UnitId] -> UnusableUnitReason
    BrokenDependencies UnitInfoMap -> UnitInfo -> [UnitId]
    depsNotAvailable UnitInfoMap
    pkg_map2 [UnitInfo]
    broken

        -- Find recursive units
        sccs :: [SCC UnitInfo]
    sccs = [(UnitInfo, UnitId, [UnitId])] -> [SCC UnitInfo]
    forall key node. Ord key => [(node, key, [key])] -> [SCC node]
    stronglyConnComp [ (UnitInfo
    pkg, UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    pkg, UnitInfo -> [UnitId]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> [uid]
    unitDepends UnitInfo
    pkg)
                                | UnitInfo
    pkg <- UnitInfoMap -> [UnitInfo]
    forall k a. UniqMap k a -> [a]
    nonDetEltsUniqMap UnitInfoMap
    pkg_map2 ]
        getCyclicSCC :: SCC (GenericUnitInfo srcpkgid srcpkgname b modulename mod) -> [b]
    getCyclicSCC (CyclicSCC [GenericUnitInfo srcpkgid srcpkgname b modulename mod]
    vs) = (GenericUnitInfo srcpkgid srcpkgname b modulename mod -> b)
    -> [GenericUnitInfo srcpkgid srcpkgname b modulename mod] -> [b]
    forall a b. (a -> b) -> [a] -> [b]
    map GenericUnitInfo srcpkgid srcpkgname b modulename mod -> b
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId [GenericUnitInfo srcpkgid srcpkgname b modulename mod]
    vs
        getCyclicSCC (AcyclicSCC GenericUnitInfo srcpkgid srcpkgname b modulename mod
    _) = []
        (UnitInfoMap
    pkg_map3, [UnitInfo]
    cyclic) = [UnitId] -> RevIndex -> UnitInfoMap -> (UnitInfoMap, [UnitInfo])
    removeUnits ((SCC UnitInfo -> [UnitId]) -> [SCC UnitInfo] -> [UnitId]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap SCC UnitInfo -> [UnitId]
    forall {srcpkgid} {srcpkgname} {b} {modulename} {mod}.
    SCC (GenericUnitInfo srcpkgid srcpkgname b modulename mod) -> [b]
    getCyclicSCC [SCC UnitInfo]
    sccs) RevIndex
    index UnitInfoMap
    pkg_map2
        unusable_cyclic :: UnusableUnits
    unusable_cyclic = ([UnitId] -> UnusableUnitReason)
    -> (UnitInfoMap -> UnitInfo -> [UnitId])
    -> UnitInfoMap
    -> [UnitInfo]
    -> UnusableUnits
    forall {k} {t} {b} {t} {srcpkgid} {srcpkgname} {modulename} {mod}.
    Uniquable k =>
    (t -> b)
    -> (t -> GenericUnitInfo srcpkgid srcpkgname k modulename mod -> t)
    -> t
    -> [GenericUnitInfo srcpkgid srcpkgname k modulename mod]
    -> UniqMap
         k (GenericUnitInfo srcpkgid srcpkgname k modulename mod, b)
    mk_unusable [UnitId] -> UnusableUnitReason
    CyclicDependencies UnitInfoMap -> UnitInfo -> [UnitId]
    depsNotAvailable UnitInfoMap
    pkg_map3 [UnitInfo]
    cyclic

        -- Apply ignore flags
        directly_ignored :: UnusableUnits
    directly_ignored = [IgnorePackageFlag] -> [UnitInfo] -> UnusableUnits
    ignoreUnits [IgnorePackageFlag]
    ignore_flags (UnitInfoMap -> [UnitInfo]
    forall k a. UniqMap k a -> [a]
    nonDetEltsUniqMap UnitInfoMap
    pkg_map3)
        (UnitInfoMap
    pkg_map4, [UnitInfo]
    ignored) = [UnitId] -> RevIndex -> UnitInfoMap -> (UnitInfoMap, [UnitInfo])
    removeUnits (UnusableUnits -> [UnitId]
    forall k a. UniqMap k a -> [k]
    nonDetKeysUniqMap UnusableUnits
    directly_ignored) RevIndex
    index UnitInfoMap
    pkg_map3
        unusable_ignored :: UnusableUnits
    unusable_ignored = ([UnitId] -> UnusableUnitReason)
    -> (UnitInfoMap -> UnitInfo -> [UnitId])
    -> UnitInfoMap
    -> [UnitInfo]
    -> UnusableUnits
    forall {k} {t} {b} {t} {srcpkgid} {srcpkgname} {modulename} {mod}.
    Uniquable k =>
    (t -> b)
    -> (t -> GenericUnitInfo srcpkgid srcpkgname k modulename mod -> t)
    -> t
    -> [GenericUnitInfo srcpkgid srcpkgname k modulename mod]
    -> UniqMap
         k (GenericUnitInfo srcpkgid srcpkgname k modulename mod, b)
    mk_unusable [UnitId] -> UnusableUnitReason
    IgnoredDependencies UnitInfoMap -> UnitInfo -> [UnitId]
    depsNotAvailable UnitInfoMap
    pkg_map4 [UnitInfo]
    ignored

        -- Knock out units whose dependencies don't agree with ABI
        -- (i.e., got invalidated due to shadowing)
        directly_shadowed :: [UnitInfo]
    directly_shadowed = (UnitInfo -> Bool) -> [UnitInfo] -> [UnitInfo]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (UnitInfo -> Bool) -> UnitInfo -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [UnitId] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([UnitId] -> Bool) -> (UnitInfo -> [UnitId]) -> UnitInfo -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitInfoMap -> UnitInfo -> [UnitId]
    depsAbiMismatch UnitInfoMap
    pkg_map4)
                                   (UnitInfoMap -> [UnitInfo]
    forall k a. UniqMap k a -> [a]
    nonDetEltsUniqMap UnitInfoMap
    pkg_map4)
        (UnitInfoMap
    pkg_map5, [UnitInfo]
    shadowed) = [UnitId] -> RevIndex -> UnitInfoMap -> (UnitInfoMap, [UnitInfo])
    removeUnits ((UnitInfo -> UnitId) -> [UnitInfo] -> [UnitId]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId [UnitInfo]
    directly_shadowed) RevIndex
    index UnitInfoMap
    pkg_map4
        unusable_shadowed :: UnusableUnits
    unusable_shadowed = ([UnitId] -> UnusableUnitReason)
    -> (UnitInfoMap -> UnitInfo -> [UnitId])
    -> UnitInfoMap
    -> [UnitInfo]
    -> UnusableUnits
    forall {k} {t} {b} {t} {srcpkgid} {srcpkgname} {modulename} {mod}.
    Uniquable k =>
    (t -> b)
    -> (t -> GenericUnitInfo srcpkgid srcpkgname k modulename mod -> t)
    -> t
    -> [GenericUnitInfo srcpkgid srcpkgname k modulename mod]
    -> UniqMap
         k (GenericUnitInfo srcpkgid srcpkgname k modulename mod, b)
    mk_unusable [UnitId] -> UnusableUnitReason
    ShadowedDependencies UnitInfoMap -> UnitInfo -> [UnitId]
    depsAbiMismatch UnitInfoMap
    pkg_map5 [UnitInfo]
    shadowed

        -- combine all unusables. The order is important for shadowing.
        -- plusUniqMapList folds using plusUFM which is right biased (opposite of
        -- Data.Map.union) so the head of the list should be the least preferred
        unusable :: UnusableUnits
    unusable = [UnusableUnits] -> UnusableUnits
    forall k a. [UniqMap k a] -> UniqMap k a
    plusUniqMapList [ UnusableUnits
    unusable_shadowed
                                   , UnusableUnits
    unusable_cyclic
                                   , UnusableUnits
    unusable_broken
                                   , UnusableUnits
    unusable_ignored
                                   , UnusableUnits
    directly_ignored
                                   ]

    -- -----------------------------------------------------------------------------
    -- When all the command-line options are in, we can process our unit
    -- settings and populate the unit state.

    mkUnitState
        :: Logger
        -> UnitConfig
        -> IO (UnitState,[UnitDatabase UnitId])
    mkUnitState :: Logger -> UnitConfig -> IO (UnitState, [UnitDatabase UnitId])
    mkUnitState Logger
    logger UnitConfig
    cfg = 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.
    -}

      -- if databases have not been provided, read the database flags
      raw_dbs <- case UnitConfig -> Maybe [UnitDatabase UnitId]
    unitConfigDBCache UnitConfig
    cfg of
                   Maybe [UnitDatabase UnitId]
    Nothing  -> Logger -> UnitConfig -> IO [UnitDatabase UnitId]
    readUnitDatabases Logger
    logger UnitConfig
    cfg
                   Just [UnitDatabase UnitId]
    dbs -> [UnitDatabase UnitId] -> IO [UnitDatabase UnitId]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [UnitDatabase UnitId]
    dbs

      -- distrust all units if the flag is set
      let distrust_all UnitDatabase UnitId
    db = UnitDatabase UnitId
    db { unitDatabaseUnits = distrustAllUnits (unitDatabaseUnits db) }
          dbs | UnitConfig -> Bool
    unitConfigDistrustAll UnitConfig
    cfg = (UnitDatabase UnitId -> UnitDatabase UnitId)
    -> [UnitDatabase UnitId] -> [UnitDatabase UnitId]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitDatabase UnitId -> UnitDatabase UnitId
    distrust_all [UnitDatabase UnitId]
    raw_dbs
              | Bool
    otherwise                 = [UnitDatabase UnitId]
    raw_dbs

      -- 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 raw_other_flags = [PackageFlag] -> [PackageFlag]
    forall a. [a] -> [a]
    reverse (UnitConfig -> [PackageFlag]
    unitConfigFlagsExposed UnitConfig
    cfg)
          (hpt_flags, other_flags) = partition (selectHptFlag (unitConfigHomeUnits cfg)) raw_other_flags
      debugTraceMsg logger 2 $
          text "package flags" <+> ppr other_flags

      let home_unit_deps = Set UnitId -> [PackageFlag] -> Set UnitId
    selectHomeUnits (UnitConfig -> Set UnitId
    unitConfigHomeUnits UnitConfig
    cfg) [PackageFlag]
    hpt_flags

      -- Merge databases together, without checking validity
      (pkg_map1, prec_map) <- mergeDatabases logger dbs

      -- Now that we've merged everything together, prune out unusable
      -- packages.
      let (pkg_map2, unusable, sccs) = validateDatabase cfg pkg_map1

      reportCycles   logger sccs
      reportUnusable logger unusable

      -- Apply trust flags (these flags apply regardless of whether
      -- or not packages are visible or not)
      pkgs1 <- mayThrowUnitErr
                $ foldM (applyTrustFlag prec_map unusable)
                     (nonDetEltsUniqMap pkg_map2) (reverse (unitConfigFlagsTrusted cfg))
      let prelim_pkg_db = [UnitInfo] -> UnitInfoMap
    mkUnitInfoMap [UnitInfo]
    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 UnitInfo
    unit UnitInfo
    unit' =
            case UnitPrecedenceMap -> UnitInfo -> UnitInfo -> Ordering
    compareByPreference UnitPrecedenceMap
    prec_map UnitInfo
    unit UnitInfo
    unit' of
                Ordering
    GT -> UnitInfo
    unit
                Ordering
    _  -> UnitInfo
    unit'
          addIfMorePreferable UniqDFM FastString UnitInfo
    m UnitInfo
    unit = (UnitInfo -> UnitInfo -> UnitInfo)
    -> UniqDFM FastString UnitInfo
    -> FastString
    -> UnitInfo
    -> UniqDFM FastString UnitInfo
    forall key elt.
    Uniquable key =>
    (elt -> elt -> elt)
    -> UniqDFM key elt -> key -> elt -> UniqDFM key elt
    addToUDFM_C UnitInfo -> UnitInfo -> UnitInfo
    preferLater UniqDFM FastString UnitInfo
    m (UnitInfo -> FastString
    fsPackageName UnitInfo
    unit) UnitInfo
    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 UnitConfig -> Bool
    unitConfigHideAll UnitConfig
    cfg
                        then UniqDFM FastString UnitInfo
    forall {k} (key :: k) elt. UniqDFM key elt
    emptyUDFM
                        else (UniqDFM FastString UnitInfo
     -> UnitInfo -> UniqDFM FastString UnitInfo)
    -> UniqDFM FastString UnitInfo
    -> [UnitInfo]
    -> UniqDFM FastString UnitInfo
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' UniqDFM FastString UnitInfo
    -> UnitInfo -> UniqDFM FastString UnitInfo
    addIfMorePreferable UniqDFM FastString UnitInfo
    forall {k} (key :: k) elt. UniqDFM key elt
    emptyUDFM [UnitInfo]
    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 UnitInfo
    u =
            case UniqDFM FastString UnitInfo -> FastString -> Maybe UnitInfo
    forall key elt.
    Uniquable key =>
    UniqDFM key elt -> key -> Maybe elt
    lookupUDFM UniqDFM FastString UnitInfo
    mostPreferablePackageReps (UnitInfo -> FastString
    fsPackageName UnitInfo
    u) of
              Maybe UnitInfo
    Nothing -> Bool
    False
              Just UnitInfo
    u' -> UnitPrecedenceMap -> UnitInfo -> UnitInfo -> Ordering
    compareByPreference UnitPrecedenceMap
    prec_map UnitInfo
    u UnitInfo
    u' Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    == Ordering
    EQ
          vis_map1 = (VisibilityMap -> UnitInfo -> VisibilityMap)
    -> VisibilityMap -> [UnitInfo] -> VisibilityMap
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' (\VisibilityMap
    vm UnitInfo
    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 UnitInfo -> Bool
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> Bool
    unitIsExposed UnitInfo
    p Bool -> Bool -> Bool
    && Unit -> Bool
    unitIsDefinite (UnitInfo -> Unit
    mkUnit UnitInfo
    p) Bool -> Bool -> Bool
    && UnitInfo -> Bool
    mostPreferable UnitInfo
    p
                                   then VisibilityMap -> Unit -> UnitVisibility -> VisibilityMap
    forall k a. Uniquable k => UniqMap k a -> k -> a -> UniqMap k a
    addToUniqMap VisibilityMap
    vm (UnitInfo -> Unit
    mkUnit UnitInfo
    p)
                                                   UnitVisibility {
                                                     uv_expose_all :: Bool
    uv_expose_all = Bool
    True,
                                                     uv_renamings :: [(ModuleName, ModuleName)]
    uv_renamings = [],
                                                     uv_package_name :: First FastString
    uv_package_name = Maybe FastString -> First FastString
    forall a. Maybe a -> First a
    First (FastString -> Maybe FastString
    forall a. a -> Maybe a
    Just (UnitInfo -> FastString
    fsPackageName UnitInfo
    p)),
                                                     uv_requirements :: UniqMap ModuleName (Set InstantiatedModule)
    uv_requirements = UniqMap ModuleName (Set InstantiatedModule)
    forall k a. UniqMap k a
    emptyUniqMap,
                                                     uv_explicit :: Maybe PackageArg
    uv_explicit = Maybe PackageArg
    forall a. Maybe a
    Nothing
                                                   }
                                   else VisibilityMap
    vm)
                             VisibilityMap
    forall k a. UniqMap k a
    emptyUniqMap [UnitInfo]
    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 <- mayThrowUnitErr
                    $ foldM (applyPackageFlag prec_map prelim_pkg_db emptyUniqSet unusable
                            (unitConfigHideAll cfg) 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) <- findWiredInUnits logger prec_map pkgs1 vis_map2
      let pkg_db = [UnitInfo] -> UnitInfoMap
    mkUnitInfoMap [UnitInfo]
    pkgs2

      -- Update the visibility map, so we treat wired packages as visible.
      let vis_map = UniqMap UnitId UnitId -> VisibilityMap -> VisibilityMap
    updateVisibilityMap UniqMap UnitId UnitId
    wired_map VisibilityMap
    vis_map2

      let hide_plugin_pkgs = UnitConfig -> Bool
    unitConfigHideAllPlugins UnitConfig
    cfg
      plugin_vis_map <-
        case unitConfigFlagsPlugins cfg of
            -- common case; try to share the old vis_map
            [] | Bool -> Bool
    not Bool
    hide_plugin_pkgs -> VisibilityMap -> IO VisibilityMap
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return VisibilityMap
    vis_map
               | Bool
    otherwise -> VisibilityMap -> IO VisibilityMap
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return VisibilityMap
    forall k a. UniqMap k a
    emptyUniqMap
            [PackageFlag]
    _ -> do let plugin_vis_map1 :: VisibilityMap
    plugin_vis_map1
                            | Bool
    hide_plugin_pkgs = VisibilityMap
    forall k a. UniqMap k a
    emptyUniqMap
                            -- Use the vis_map PRIOR to wired in,
                            -- because otherwise applyPackageFlag
                            -- won't work.
                            | Bool
    otherwise = VisibilityMap
    vis_map2
                    plugin_vis_map2
                        <- MaybeErr UnitErr VisibilityMap -> IO VisibilityMap
    forall a. MaybeErr UnitErr a -> IO a
    mayThrowUnitErr
                            (MaybeErr UnitErr VisibilityMap -> IO VisibilityMap)
    -> MaybeErr UnitErr VisibilityMap -> IO VisibilityMap
    forall a b. (a -> b) -> a -> b
    $ (VisibilityMap -> PackageFlag -> MaybeErr UnitErr VisibilityMap)
    -> VisibilityMap -> [PackageFlag] -> MaybeErr UnitErr VisibilityMap
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldM (UnitPrecedenceMap
    -> UnitInfoMap
    -> PreloadUnitClosure
    -> UnusableUnits
    -> Bool
    -> [UnitInfo]
    -> VisibilityMap
    -> PackageFlag
    -> MaybeErr UnitErr VisibilityMap
    applyPackageFlag UnitPrecedenceMap
    prec_map UnitInfoMap
    prelim_pkg_db PreloadUnitClosure
    forall a. UniqSet a
    emptyUniqSet UnusableUnits
    unusable
                                    Bool
    hide_plugin_pkgs [UnitInfo]
    pkgs1)
                                 VisibilityMap
    plugin_vis_map1
                                 ([PackageFlag] -> [PackageFlag]
    forall a. [a] -> [a]
    reverse (UnitConfig -> [PackageFlag]
    unitConfigFlagsPlugins UnitConfig
    cfg))
                    -- 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)

      let pkgname_map = [(PackageName, UnitId)] -> UniqFM PackageName UnitId
    forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
    listToUFM [ (UnitInfo -> PackageName
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> srcpkgname
    unitPackageName UnitInfo
    p, UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitInstanceOf UnitInfo
    p)
                                  | UnitInfo
    p <- [UnitInfo]
    pkgs2
                                  ]
      -- The explicitUnits accurately reflects the set of units 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 = [(Unit
    k, UnitVisibility -> Maybe PackageArg
    uv_explicit UnitVisibility
    v) | (Unit
    k, UnitVisibility
    v) <- VisibilityMap -> [(Unit, UnitVisibility)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList VisibilityMap
    vis_map]
          req_ctx = (Set InstantiatedModule -> [InstantiatedModule])
    -> UniqMap ModuleName (Set InstantiatedModule)
    -> UniqMap ModuleName [InstantiatedModule]
    forall a b k. (a -> b) -> UniqMap k a -> UniqMap k b
    mapUniqMap (Set InstantiatedModule -> [InstantiatedModule]
    forall a. Set a -> [a]
    Set.toList)
                  (UniqMap ModuleName (Set InstantiatedModule)
     -> UniqMap ModuleName [InstantiatedModule])
    -> UniqMap ModuleName (Set InstantiatedModule)
    -> UniqMap ModuleName [InstantiatedModule]
    forall a b. (a -> b) -> a -> b
    $ (Set InstantiatedModule
     -> Set InstantiatedModule -> Set InstantiatedModule)
    -> [UniqMap ModuleName (Set InstantiatedModule)]
    -> UniqMap ModuleName (Set InstantiatedModule)
    forall a k. (a -> a -> a) -> [UniqMap k a] -> UniqMap k a
    plusUniqMapListWith Set InstantiatedModule
    -> Set InstantiatedModule -> Set InstantiatedModule
    forall a. Ord a => Set a -> Set a -> Set a
    Set.union ((UnitVisibility -> UniqMap ModuleName (Set InstantiatedModule))
    -> [UnitVisibility]
    -> [UniqMap ModuleName (Set InstantiatedModule)]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitVisibility -> UniqMap ModuleName (Set InstantiatedModule)
    uv_requirements (VisibilityMap -> [UnitVisibility]
    forall k a. UniqMap k a -> [a]
    nonDetEltsUniqMap VisibilityMap
    vis_map))

      --
      -- 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 = VisibilityMap -> [Unit]
    forall k a. UniqMap k a -> [k]
    nonDetKeysUniqMap ((UnitVisibility -> Bool) -> VisibilityMap -> VisibilityMap
    forall a k. (a -> Bool) -> UniqMap k a -> UniqMap k a
    filterUniqMap (Maybe PackageArg -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe PackageArg -> Bool)
    -> (UnitVisibility -> Maybe PackageArg) -> UnitVisibility -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitVisibility -> Maybe PackageArg
    uv_explicit) VisibilityMap
    vis_map)

          -- add default preload units if they can be found in the db
          basicLinkedUnits = (UnitId -> Unit) -> [UnitId] -> [Unit]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Definite UnitId -> Unit
    forall uid. Definite uid -> GenUnit uid
    RealUnit (Definite UnitId -> Unit)
    -> (UnitId -> Definite UnitId) -> UnitId -> Unit
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitId -> Definite UnitId
    forall unit. unit -> Definite unit
    Definite)
                             ([UnitId] -> [Unit]) -> [UnitId] -> [Unit]
    forall a b. (a -> b) -> a -> b
    $ (UnitId -> Bool) -> [UnitId] -> [UnitId]
    forall a. (a -> Bool) -> [a] -> [a]
    filter ((UnitId -> UnitInfoMap -> Bool) -> UnitInfoMap -> UnitId -> Bool
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip UnitId -> UnitInfoMap -> Bool
    forall k a. Uniquable k => k -> UniqMap k a -> Bool
    elemUniqMap UnitInfoMap
    pkg_db)
                             ([UnitId] -> [UnitId]) -> [UnitId] -> [UnitId]
    forall a b. (a -> b) -> a -> b
    $ UnitConfig -> [UnitId]
    unitConfigAutoLink UnitConfig
    cfg
          preload3 = [Unit] -> [Unit]
    forall a. Ord a => [a] -> [a]
    ordNub ([Unit] -> [Unit]) -> [Unit] -> [Unit]
    forall a b. (a -> b) -> a -> b
    $ ([Unit]
    basicLinkedUnits [Unit] -> [Unit] -> [Unit]
    forall a. [a] -> [a] -> [a]
    ++ [Unit]
    preload1)

      -- Close the preload packages with their dependencies
      dep_preload <- mayThrowUnitErr
                        $ closeUnitDeps pkg_db
                        $ zip (map toUnitId preload3) (repeat Nothing)

      let mod_map1 = Logger
    -> UnitConfig
    -> UnitInfoMap
    -> PreloadUnitClosure
    -> VisibilityMap
    -> ModuleNameProvidersMap
    mkModuleNameProvidersMap Logger
    logger UnitConfig
    cfg UnitInfoMap
    pkg_db PreloadUnitClosure
    forall a. UniqSet a
    emptyUniqSet VisibilityMap
    vis_map
          mod_map2 = UnusableUnits -> ModuleNameProvidersMap
    mkUnusableModuleNameProvidersMap UnusableUnits
    unusable
          mod_map = ModuleNameProvidersMap
    mod_map2 ModuleNameProvidersMap
    -> ModuleNameProvidersMap -> ModuleNameProvidersMap
    forall k a. UniqMap k a -> UniqMap k a -> UniqMap k a
    `plusUniqMap` ModuleNameProvidersMap
    mod_map1

      -- Force the result to avoid leaking input parameters
      let !state = UnitState
             { preloadUnits :: [UnitId]
    preloadUnits                 = [UnitId]
    dep_preload
             , explicitUnits :: [(Unit, Maybe PackageArg)]
    explicitUnits                = [(Unit, Maybe PackageArg)]
    explicit_pkgs
             , homeUnitDepends :: [UnitId]
    homeUnitDepends              = Set UnitId -> [UnitId]
    forall a. Set a -> [a]
    Set.toList Set UnitId
    home_unit_deps
             , unitInfoMap :: UnitInfoMap
    unitInfoMap                  = UnitInfoMap
    pkg_db
             , preloadClosure :: PreloadUnitClosure
    preloadClosure               = PreloadUnitClosure
    forall a. UniqSet a
    emptyUniqSet
             , moduleNameProvidersMap :: ModuleNameProvidersMap
    moduleNameProvidersMap       = ModuleNameProvidersMap
    mod_map
             , pluginModuleNameProvidersMap :: ModuleNameProvidersMap
    pluginModuleNameProvidersMap = Logger
    -> UnitConfig
    -> UnitInfoMap
    -> PreloadUnitClosure
    -> VisibilityMap
    -> ModuleNameProvidersMap
    mkModuleNameProvidersMap Logger
    logger UnitConfig
    cfg UnitInfoMap
    pkg_db PreloadUnitClosure
    forall a. UniqSet a
    emptyUniqSet VisibilityMap
    plugin_vis_map
             , packageNameMap :: UniqFM PackageName UnitId
    packageNameMap               = UniqFM PackageName UnitId
    pkgname_map
             , wireMap :: UniqMap UnitId UnitId
    wireMap                      = UniqMap UnitId UnitId
    wired_map
             , unwireMap :: UniqMap UnitId UnitId
    unwireMap                    = [(UnitId, UnitId)] -> UniqMap UnitId UnitId
    forall k a. Uniquable k => [(k, a)] -> UniqMap k a
    listToUniqMap [ (UnitId
    v,UnitId
    k) | (UnitId
    k,UnitId
    v) <- UniqMap UnitId UnitId -> [(UnitId, UnitId)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList UniqMap UnitId UnitId
    wired_map ]
             , requirementContext :: UniqMap ModuleName [InstantiatedModule]
    requirementContext           = UniqMap ModuleName [InstantiatedModule]
    req_ctx
             , allowVirtualUnits :: Bool
    allowVirtualUnits            = UnitConfig -> Bool
    unitConfigAllowVirtual UnitConfig
    cfg
             }
      return (state, raw_dbs)

    selectHptFlag :: Set.Set UnitId -> PackageFlag -> Bool
    selectHptFlag :: Set UnitId -> PackageFlag -> Bool
    selectHptFlag Set UnitId
    home_units (ExposePackage String
    _ (UnitIdArg Unit
    uid) ModRenaming
    _) | Unit -> UnitId
    toUnitId Unit
    uid UnitId -> Set UnitId -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set UnitId
    home_units = Bool
    True
    selectHptFlag Set UnitId
    _ PackageFlag
    _ = Bool
    False

    selectHomeUnits :: Set.Set UnitId -> [PackageFlag] -> Set.Set UnitId
    selectHomeUnits :: Set UnitId -> [PackageFlag] -> Set UnitId
    selectHomeUnits Set UnitId
    home_units [PackageFlag]
    flags = (Set UnitId -> PackageFlag -> Set UnitId)
    -> Set UnitId -> [PackageFlag] -> Set UnitId
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' Set UnitId -> PackageFlag -> Set UnitId
    go Set UnitId
    forall a. Set a
    Set.empty [PackageFlag]
    flags
      where
        go :: Set.Set UnitId -> PackageFlag -> Set.Set UnitId
        go :: Set UnitId -> PackageFlag -> Set UnitId
    go Set UnitId
    cur (ExposePackage String
    _ (UnitIdArg Unit
    uid) ModRenaming
    _) | Unit -> UnitId
    toUnitId Unit
    uid UnitId -> Set UnitId -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set UnitId
    home_units = UnitId -> Set UnitId -> Set UnitId
    forall a. Ord a => a -> Set a -> Set a
    Set.insert (Unit -> UnitId
    toUnitId Unit
    uid) Set UnitId
    cur
        -- MP: This does not yet support thinning/renaming
        go Set UnitId
    cur PackageFlag
    _ = Set UnitId
    cur

    -- | Given a wired-in 'Unit', "unwire" it into the 'Unit'
    -- that it was recorded as in the package database.
    unwireUnit :: UnitState -> Unit -> Unit
    unwireUnit :: UnitState -> Unit -> Unit
    unwireUnit UnitState
    state uid :: Unit
    uid@(RealUnit (Definite UnitId
    def_uid)) =
        Unit -> (UnitId -> Unit) -> Maybe UnitId -> Unit
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Unit
    uid (Definite UnitId -> Unit
    forall uid. Definite uid -> GenUnit uid
    RealUnit (Definite UnitId -> Unit)
    -> (UnitId -> Definite UnitId) -> UnitId -> Unit
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitId -> Definite UnitId
    forall unit. unit -> Definite unit
    Definite) (UniqMap UnitId UnitId -> UnitId -> Maybe UnitId
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap (UnitState -> UniqMap UnitId UnitId
    unwireMap UnitState
    state) UnitId
    def_uid)
    unwireUnit UnitState
    _ Unit
    uid = Unit
    uid

    -- -----------------------------------------------------------------------------
    -- | Makes the mapping from ModuleName 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
      :: Logger
      -> UnitConfig
      -> UnitInfoMap
      -> PreloadUnitClosure
      -> VisibilityMap
      -> ModuleNameProvidersMap
    mkModuleNameProvidersMap :: Logger
    -> UnitConfig
    -> UnitInfoMap
    -> PreloadUnitClosure
    -> VisibilityMap
    -> ModuleNameProvidersMap
    mkModuleNameProvidersMap Logger
    logger UnitConfig
    cfg UnitInfoMap
    pkg_map PreloadUnitClosure
    closure VisibilityMap
    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_map is awkward because if we have an
        --      Backpack instantiation, we need to possibly add a
        --      package from pkg_map 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.
        ((Unit, UnitVisibility)
     -> ModuleNameProvidersMap -> ModuleNameProvidersMap)
    -> ModuleNameProvidersMap
    -> VisibilityMap
    -> ModuleNameProvidersMap
    forall k a b. ((k, a) -> b -> b) -> b -> UniqMap k a -> b
    nonDetFoldUniqMap (Unit, UnitVisibility)
    -> ModuleNameProvidersMap -> ModuleNameProvidersMap
    extend_modmap ModuleNameProvidersMap
    forall k a. UniqMap k a
    emptyMap VisibilityMap
    vis_map_extended
     where
      vis_map_extended :: VisibilityMap
    vis_map_extended = {- preferred -} VisibilityMap
    default_vis VisibilityMap -> VisibilityMap -> VisibilityMap
    forall k a. UniqMap k a -> UniqMap k a -> UniqMap k a
    `plusUniqMap` VisibilityMap
    vis_map

      default_vis :: VisibilityMap
    default_vis = [(Unit, UnitVisibility)] -> VisibilityMap
    forall k a. Uniquable k => [(k, a)] -> UniqMap k a
    listToUniqMap
                      [ (UnitInfo -> Unit
    mkUnit UnitInfo
    pkg, UnitVisibility
    forall a. Monoid a => a
    mempty)
                      | (UnitId
    _, UnitInfo
    pkg) <- UnitInfoMap -> [(UnitId, UnitInfo)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList UnitInfoMap
    pkg_map
                      -- Exclude specific instantiations of an indefinite
                      -- package
                      , UnitInfo -> Bool
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> Bool
    unitIsIndefinite UnitInfo
    pkg Bool -> Bool -> Bool
    || [(ModuleName, Module)] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (UnitInfo -> [(ModuleName, Module)]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [(modulename, mod)]
    unitInstantiations UnitInfo
    pkg)
                      ]

      emptyMap :: UniqMap k a
    emptyMap = UniqMap k a
    forall k a. UniqMap k a
    emptyUniqMap
      setOrigins :: f a -> b -> f b
    setOrigins f a
    m b
    os = (a -> b) -> f a -> f b
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (b -> a -> b
    forall a b. a -> b -> a
    const b
    os) f a
    m
      extend_modmap :: (Unit, UnitVisibility)
    -> ModuleNameProvidersMap -> ModuleNameProvidersMap
    extend_modmap (Unit
    uid, UnitVisibility { uv_expose_all :: UnitVisibility -> Bool
    uv_expose_all = Bool
    b, uv_renamings :: UnitVisibility -> [(ModuleName, ModuleName)]
    uv_renamings = [(ModuleName, ModuleName)]
    rns }) ModuleNameProvidersMap
    modmap
        = ModuleNameProvidersMap
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    -> ModuleNameProvidersMap
    forall a k1 k2.
    (Monoid a, Ord k1, Ord k2, Uniquable k1, Uniquable k2) =>
    UniqMap k1 (UniqMap k2 a)
    -> [(k1, UniqMap k2 a)] -> UniqMap k1 (UniqMap k2 a)
    addListTo ModuleNameProvidersMap
    modmap [(ModuleName, UniqMap Module ModuleOrigin)]
    theBindings
       where
        pkg :: UnitInfo
    pkg = Unit -> UnitInfo
    unit_lookup Unit
    uid

        theBindings :: [(ModuleName, UniqMap Module ModuleOrigin)]
        theBindings :: [(ModuleName, UniqMap Module ModuleOrigin)]
    theBindings = Bool
    -> [(ModuleName, ModuleName)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    newBindings Bool
    b [(ModuleName, ModuleName)]
    rns

        newBindings :: Bool
                    -> [(ModuleName, ModuleName)]
                    -> [(ModuleName, UniqMap Module ModuleOrigin)]
        newBindings :: Bool
    -> [(ModuleName, ModuleName)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    newBindings Bool
    e [(ModuleName, ModuleName)]
    rns  = Bool -> [(ModuleName, UniqMap Module ModuleOrigin)]
    es Bool
    e [(ModuleName, UniqMap Module ModuleOrigin)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    forall a. [a] -> [a] -> [a]
    ++ [(ModuleName, UniqMap Module ModuleOrigin)]
    hiddens [(ModuleName, UniqMap Module ModuleOrigin)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    forall a. [a] -> [a] -> [a]
    ++ ((ModuleName, ModuleName)
     -> (ModuleName, UniqMap Module ModuleOrigin))
    -> [(ModuleName, ModuleName)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    forall a b. (a -> b) -> [a] -> [b]
    map (ModuleName, ModuleName)
    -> (ModuleName, UniqMap Module ModuleOrigin)
    rnBinding [(ModuleName, ModuleName)]
    rns

        rnBinding :: (ModuleName, ModuleName)
                  -> (ModuleName, UniqMap Module ModuleOrigin)
        rnBinding :: (ModuleName, ModuleName)
    -> (ModuleName, UniqMap Module ModuleOrigin)
    rnBinding (ModuleName
    orig, ModuleName
    new) = (ModuleName
    new, UniqMap Module ModuleOrigin
    -> ModuleOrigin -> UniqMap Module ModuleOrigin
    forall {f :: * -> *} {a} {b}. Functor f => f a -> b -> f b
    setOrigins UniqMap Module ModuleOrigin
    origEntry ModuleOrigin
    fromFlag)
         where origEntry :: UniqMap Module ModuleOrigin
    origEntry = case UniqFM ModuleName (UniqMap Module ModuleOrigin)
    -> ModuleName -> Maybe (UniqMap Module ModuleOrigin)
    forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
    lookupUFM UniqFM ModuleName (UniqMap Module ModuleOrigin)
    esmap ModuleName
    orig of
                Just UniqMap Module ModuleOrigin
    r -> UniqMap Module ModuleOrigin
    r
                Maybe (UniqMap Module ModuleOrigin)
    Nothing -> GhcException -> UniqMap Module ModuleOrigin
    forall a. GhcException -> a
    throwGhcException (String -> GhcException
    CmdLineError (SDocContext -> SDoc -> String
    renderWithContext
                            (LogFlags -> SDocContext
    log_default_user_context (Logger -> LogFlags
    logFlags Logger
    logger))
                            (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "package flag: could not find module name" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+>
                                ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    orig SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "in package" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Unit -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Unit
    pk)))

        es :: Bool -> [(ModuleName, UniqMap Module ModuleOrigin)]
        es :: Bool -> [(ModuleName, UniqMap Module ModuleOrigin)]
    es Bool
    e = do
         (m, exposedReexport) <- [(ModuleName, Maybe Module)]
    exposed_mods
         let (pk', m', origin') =
              case exposedReexport of
               Maybe Module
    Nothing -> (Unit
    pk, ModuleName
    m, Bool -> ModuleOrigin
    fromExposedModules Bool
    e)
               Just (Module Unit
    pk' ModuleName
    m') ->
                  (Unit
    pk', ModuleName
    m', Bool -> UnitInfo -> ModuleOrigin
    fromReexportedModules Bool
    e UnitInfo
    pkg)
         return (m, mkModMap pk' m' origin')

        esmap :: UniqFM ModuleName (UniqMap Module ModuleOrigin)
        esmap :: UniqFM ModuleName (UniqMap Module ModuleOrigin)
    esmap = [(ModuleName, UniqMap Module ModuleOrigin)]
    -> UniqFM ModuleName (UniqMap Module ModuleOrigin)
    forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
    listToUFM (Bool -> [(ModuleName, UniqMap Module ModuleOrigin)]
    es Bool
    False) -- parameter here doesn't matter, orig will
                                     -- be overwritten

        hiddens :: [(ModuleName, UniqMap Module ModuleOrigin)]
    hiddens = [(ModuleName
    m, Unit -> ModuleName -> ModuleOrigin -> UniqMap Module ModuleOrigin
    mkModMap Unit
    pk ModuleName
    m ModuleOrigin
    ModHidden) | ModuleName
    m <- [ModuleName]
    hidden_mods]

        pk :: Unit
    pk = UnitInfo -> Unit
    mkUnit UnitInfo
    pkg
        unit_lookup :: Unit -> UnitInfo
    unit_lookup Unit
    uid = Bool -> UnitInfoMap -> PreloadUnitClosure -> Unit -> Maybe UnitInfo
    lookupUnit' (UnitConfig -> Bool
    unitConfigAllowVirtual UnitConfig
    cfg) UnitInfoMap
    pkg_map PreloadUnitClosure
    closure Unit
    uid
                            Maybe UnitInfo -> UnitInfo -> UnitInfo
    forall a. Maybe a -> a -> a
    `orElse` String -> SDoc -> UnitInfo
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "unit_lookup" (Unit -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Unit
    uid)

        exposed_mods :: [(ModuleName, Maybe Module)]
    exposed_mods = UnitInfo -> [(ModuleName, Maybe Module)]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [(modulename, Maybe mod)]
    unitExposedModules UnitInfo
    pkg
        hidden_mods :: [ModuleName]
    hidden_mods  = UnitInfo -> [ModuleName]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [modulename]
    unitHiddenModules UnitInfo
    pkg

    -- | Make a 'ModuleNameProvidersMap' covering a set of unusable packages.
    mkUnusableModuleNameProvidersMap :: UnusableUnits -> ModuleNameProvidersMap
    mkUnusableModuleNameProvidersMap :: UnusableUnits -> ModuleNameProvidersMap
    mkUnusableModuleNameProvidersMap UnusableUnits
    unusables =
        ((UnitId, (UnitInfo, UnusableUnitReason))
     -> ModuleNameProvidersMap -> ModuleNameProvidersMap)
    -> ModuleNameProvidersMap
    -> UnusableUnits
    -> ModuleNameProvidersMap
    forall k a b. ((k, a) -> b -> b) -> b -> UniqMap k a -> b
    nonDetFoldUniqMap (UnitId, (UnitInfo, UnusableUnitReason))
    -> ModuleNameProvidersMap -> ModuleNameProvidersMap
    forall {a}.
    (a, (UnitInfo, UnusableUnitReason))
    -> ModuleNameProvidersMap -> ModuleNameProvidersMap
    extend_modmap ModuleNameProvidersMap
    forall k a. UniqMap k a
    emptyUniqMap UnusableUnits
    unusables
     where
        extend_modmap :: (a, (UnitInfo, UnusableUnitReason))
    -> ModuleNameProvidersMap -> ModuleNameProvidersMap
    extend_modmap (a
    _uid, (UnitInfo
    unit_info, UnusableUnitReason
    reason)) ModuleNameProvidersMap
    modmap = ModuleNameProvidersMap
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    -> ModuleNameProvidersMap
    forall a k1 k2.
    (Monoid a, Ord k1, Ord k2, Uniquable k1, Uniquable k2) =>
    UniqMap k1 (UniqMap k2 a)
    -> [(k1, UniqMap k2 a)] -> UniqMap k1 (UniqMap k2 a)
    addListTo ModuleNameProvidersMap
    modmap [(ModuleName, UniqMap Module ModuleOrigin)]
    bindings
          where bindings :: [(ModuleName, UniqMap Module ModuleOrigin)]
                bindings :: [(ModuleName, UniqMap Module ModuleOrigin)]
    bindings = [(ModuleName, UniqMap Module ModuleOrigin)]
    exposed [(ModuleName, UniqMap Module ModuleOrigin)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    forall a. [a] -> [a] -> [a]
    ++ [(ModuleName, UniqMap Module ModuleOrigin)]
    hidden

                origin_reexport :: ModuleOrigin
    origin_reexport =  UnusableUnit -> ModuleOrigin
    ModUnusable (Unit -> UnusableUnitReason -> Bool -> UnusableUnit
    UnusableUnit Unit
    unit UnusableUnitReason
    reason Bool
    True)
                origin_normal :: ModuleOrigin
    origin_normal   =  UnusableUnit -> ModuleOrigin
    ModUnusable (Unit -> UnusableUnitReason -> Bool -> UnusableUnit
    UnusableUnit Unit
    unit UnusableUnitReason
    reason Bool
    False)
                unit :: Unit
    unit = UnitInfo -> Unit
    mkUnit UnitInfo
    unit_info

                exposed :: [(ModuleName, UniqMap Module ModuleOrigin)]
    exposed = ((ModuleName, Maybe Module)
     -> (ModuleName, UniqMap Module ModuleOrigin))
    -> [(ModuleName, Maybe Module)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    forall a b. (a -> b) -> [a] -> [b]
    map (ModuleName, Maybe Module)
    -> (ModuleName, UniqMap Module ModuleOrigin)
    get_exposed [(ModuleName, Maybe Module)]
    exposed_mods
                hidden :: [(ModuleName, UniqMap Module ModuleOrigin)]
    hidden = [(ModuleName
    m, Unit -> ModuleName -> ModuleOrigin -> UniqMap Module ModuleOrigin
    mkModMap Unit
    unit ModuleName
    m ModuleOrigin
    origin_normal) | ModuleName
    m <- [ModuleName]
    hidden_mods]

                -- with re-exports, c:Foo can be reexported from two (or more)
                -- unusable packages:
                --  Foo -> a:Foo (unusable reason A) -> c:Foo
                --      -> b:Foo (unusable reason B) -> c:Foo
                --
                -- We must be careful to not record the following (#21097):
                --  Foo -> c:Foo (unusable reason A)
                --      -> c:Foo (unusable reason B)
                -- But:
                --  Foo -> a:Foo (unusable reason A)
                --      -> b:Foo (unusable reason B)
                --
                get_exposed :: (ModuleName, Maybe Module)
    -> (ModuleName, UniqMap Module ModuleOrigin)
    get_exposed (ModuleName
    mod, Just Module
    _) = (ModuleName
    mod, Unit -> ModuleName -> ModuleOrigin -> UniqMap Module ModuleOrigin
    mkModMap Unit
    unit ModuleName
    mod ModuleOrigin
    origin_reexport)
                get_exposed (ModuleName
    mod, Maybe Module
    _) = (ModuleName
    mod, Unit -> ModuleName -> ModuleOrigin -> UniqMap Module ModuleOrigin
    mkModMap Unit
    unit ModuleName
    mod ModuleOrigin
    origin_normal)
                  -- in the reexport case, we create a virtual module that doesn't
                  -- exist but we don't care as it's only used as a key in the map.

                exposed_mods :: [(ModuleName, Maybe Module)]
    exposed_mods = UnitInfo -> [(ModuleName, Maybe Module)]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [(modulename, Maybe mod)]
    unitExposedModules UnitInfo
    unit_info
                hidden_mods :: [ModuleName]
    hidden_mods  = UnitInfo -> [ModuleName]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> [modulename]
    unitHiddenModules  UnitInfo
    unit_info

    -- | 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, Uniquable k1, Uniquable k2)
              => UniqMap k1 (UniqMap k2 a)
              -> [(k1, UniqMap k2 a)]
              -> UniqMap k1 (UniqMap k2 a)
    addListTo :: forall a k1 k2.
    (Monoid a, Ord k1, Ord k2, Uniquable k1, Uniquable k2) =>
    UniqMap k1 (UniqMap k2 a)
    -> [(k1, UniqMap k2 a)] -> UniqMap k1 (UniqMap k2 a)
    addListTo = (UniqMap k1 (UniqMap k2 a)
     -> (k1, UniqMap k2 a) -> UniqMap k1 (UniqMap k2 a))
    -> UniqMap k1 (UniqMap k2 a)
    -> [(k1, UniqMap k2 a)]
    -> UniqMap k1 (UniqMap k2 a)
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' UniqMap k1 (UniqMap k2 a)
    -> (k1, UniqMap k2 a) -> UniqMap k1 (UniqMap k2 a)
    forall {k} {a} {k}.
    (Uniquable k, Monoid a) =>
    UniqMap k (UniqMap k a)
    -> (k, UniqMap k a) -> UniqMap k (UniqMap k a)
    merge
      where merge :: UniqMap k (UniqMap k a)
    -> (k, UniqMap k a) -> UniqMap k (UniqMap k a)
    merge UniqMap k (UniqMap k a)
    m (k
    k, UniqMap k a
    v) = (UniqMap k a -> UniqMap k a -> UniqMap k a)
    -> UniqMap k (UniqMap k a)
    -> k
    -> UniqMap k a
    -> UniqMap k (UniqMap k a)
    forall k a.
    Uniquable k =>
    (a -> a -> a) -> UniqMap k a -> k -> a -> UniqMap k a
    addToUniqMap_C ((a -> a -> a) -> UniqMap k a -> UniqMap k a -> UniqMap k a
    forall a k.
    (a -> a -> a) -> UniqMap k a -> UniqMap k a -> UniqMap k a
    plusUniqMap_C a -> a -> a
    forall a. Monoid a => a -> a -> a
    mappend) UniqMap k (UniqMap k a)
    m k
    k UniqMap k a
    v

    -- | Create a singleton module mapping
    mkModMap :: Unit -> ModuleName -> ModuleOrigin -> UniqMap Module ModuleOrigin
    mkModMap :: Unit -> ModuleName -> ModuleOrigin -> UniqMap Module ModuleOrigin
    mkModMap Unit
    pkg ModuleName
    mod = Module -> ModuleOrigin -> UniqMap Module ModuleOrigin
    forall k a. Uniquable k => k -> a -> UniqMap k a
    unitUniqMap (Unit -> ModuleName -> Module
    forall unit. unit -> ModuleName -> GenModule unit
    mkModule Unit
    pkg ModuleName
    mod)

    -- -----------------------------------------------------------------------------
    -- Package Utils

    -- | Takes a 'ModuleName', and if the module is in any package returns
    -- list of modules which take that name.
    lookupModuleInAllUnits :: UnitState
                              -> ModuleName
                              -> [(Module, UnitInfo)]
    lookupModuleInAllUnits :: UnitState -> ModuleName -> [(Module, UnitInfo)]
    lookupModuleInAllUnits UnitState
    pkgs ModuleName
    m
      = case UnitState -> ModuleName -> PkgQual -> LookupResult
    lookupModuleWithSuggestions UnitState
    pkgs ModuleName
    m PkgQual
    NoPkgQual of
          LookupFound Module
    a (UnitInfo, ModuleOrigin)
    b -> [(Module
    a,(UnitInfo, ModuleOrigin) -> UnitInfo
    forall a b. (a, b) -> a
    fst (UnitInfo, ModuleOrigin)
    b)]
          LookupMultiple [(Module, ModuleOrigin)]
    rs -> ((Module, ModuleOrigin) -> (Module, UnitInfo))
    -> [(Module, ModuleOrigin)] -> [(Module, UnitInfo)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Module, ModuleOrigin) -> (Module, UnitInfo)
    f [(Module, ModuleOrigin)]
    rs
            where f :: (Module, ModuleOrigin) -> (Module, UnitInfo)
    f (Module
    m,ModuleOrigin
    _) = (Module
    m, String -> Maybe UnitInfo -> UnitInfo
    forall a. HasDebugCallStack => String -> Maybe a -> a
    expectJust String
    "lookupModule" (UnitState -> Unit -> Maybe UnitInfo
    lookupUnit UnitState
    pkgs
                                                             (Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    m)))
          LookupResult
    _ -> []

    -- | The result of performing a lookup
    data LookupResult =
        -- | Found the module uniquely, nothing else to do
        LookupFound Module (UnitInfo, ModuleOrigin)
        -- | 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 :: UnitState
                                -> ModuleName
                                -> PkgQual
                                -> LookupResult
    lookupModuleWithSuggestions :: UnitState -> ModuleName -> PkgQual -> LookupResult
    lookupModuleWithSuggestions UnitState
    pkgs
      = UnitState
    -> ModuleNameProvidersMap -> ModuleName -> PkgQual -> LookupResult
    lookupModuleWithSuggestions' UnitState
    pkgs (UnitState -> ModuleNameProvidersMap
    moduleNameProvidersMap UnitState
    pkgs)

    -- | The package which the module **appears** to come from, this could be
    -- the one which reexports the module from it's original package. This function
    -- is currently only used for -Wunused-packages
    lookupModulePackage :: UnitState -> ModuleName -> PkgQual -> Maybe [UnitInfo]
    lookupModulePackage :: UnitState -> ModuleName -> PkgQual -> Maybe [UnitInfo]
    lookupModulePackage UnitState
    pkgs ModuleName
    mn PkgQual
    mfs =
        case UnitState
    -> ModuleNameProvidersMap -> ModuleName -> PkgQual -> LookupResult
    lookupModuleWithSuggestions' UnitState
    pkgs (UnitState -> ModuleNameProvidersMap
    moduleNameProvidersMap UnitState
    pkgs) ModuleName
    mn PkgQual
    mfs of
          LookupFound Module
    _ (UnitInfo
    orig_unit, ModuleOrigin
    origin) ->
            case ModuleOrigin
    origin of
              ModOrigin {Maybe Bool
    fromOrigUnit :: ModuleOrigin -> Maybe Bool
    fromOrigUnit :: Maybe Bool
    fromOrigUnit, [UnitInfo]
    fromExposedReexport :: ModuleOrigin -> [UnitInfo]
    fromExposedReexport :: [UnitInfo]
    fromExposedReexport} ->
                case Maybe Bool
    fromOrigUnit of
                  -- Just True means, the import is available from its original location
                  Just Bool
    True ->
                    [UnitInfo] -> Maybe [UnitInfo]
    forall a. a -> Maybe a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure [UnitInfo
    orig_unit]
                  -- Otherwise, it must be available from a reexport
                  Maybe Bool
    _ -> [UnitInfo] -> Maybe [UnitInfo]
    forall a. a -> Maybe a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure [UnitInfo]
    fromExposedReexport

              ModuleOrigin
    _ -> Maybe [UnitInfo]
    forall a. Maybe a
    Nothing

          LookupResult
    _ -> Maybe [UnitInfo]
    forall a. Maybe a
    Nothing

    lookupPluginModuleWithSuggestions :: UnitState
                                      -> ModuleName
                                      -> PkgQual
                                      -> LookupResult
    lookupPluginModuleWithSuggestions :: UnitState -> ModuleName -> PkgQual -> LookupResult
    lookupPluginModuleWithSuggestions UnitState
    pkgs
      = UnitState
    -> ModuleNameProvidersMap -> ModuleName -> PkgQual -> LookupResult
    lookupModuleWithSuggestions' UnitState
    pkgs (UnitState -> ModuleNameProvidersMap
    pluginModuleNameProvidersMap UnitState
    pkgs)

    lookupModuleWithSuggestions' :: UnitState
                                -> ModuleNameProvidersMap
                                -> ModuleName
                                -> PkgQual
                                -> LookupResult
    lookupModuleWithSuggestions' :: UnitState
    -> ModuleNameProvidersMap -> ModuleName -> PkgQual -> LookupResult
    lookupModuleWithSuggestions' UnitState
    pkgs ModuleNameProvidersMap
    mod_map ModuleName
    m PkgQual
    mb_pn
      = case ModuleNameProvidersMap
    -> ModuleName -> Maybe (UniqMap Module ModuleOrigin)
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap ModuleNameProvidersMap
    mod_map ModuleName
    m of
            Maybe (UniqMap Module ModuleOrigin)
    Nothing -> [ModuleSuggestion] -> LookupResult
    LookupNotFound [ModuleSuggestion]
    suggestions
            Just UniqMap Module ModuleOrigin
    xs ->
              case (([(Module, ModuleOrigin)], [(Module, ModuleOrigin)],
      [(Module, ModuleOrigin)], [(Module, ModuleOrigin)])
     -> (Module, ModuleOrigin)
     -> ([(Module, ModuleOrigin)], [(Module, ModuleOrigin)],
         [(Module, ModuleOrigin)], [(Module, ModuleOrigin)]))
    -> ([(Module, ModuleOrigin)], [(Module, ModuleOrigin)],
        [(Module, ModuleOrigin)], [(Module, ModuleOrigin)])
    -> [(Module, ModuleOrigin)]
    -> ([(Module, ModuleOrigin)], [(Module, ModuleOrigin)],
        [(Module, ModuleOrigin)], [(Module, ModuleOrigin)])
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' ([(Module, ModuleOrigin)], [(Module, ModuleOrigin)],
     [(Module, ModuleOrigin)], [(Module, ModuleOrigin)])
    -> (Module, ModuleOrigin)
    -> ([(Module, ModuleOrigin)], [(Module, ModuleOrigin)],
        [(Module, ModuleOrigin)], [(Module, ModuleOrigin)])
    classify ([],[],[], []) (((Module, ModuleOrigin) -> Module)
    -> [(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)]
    forall b a. Ord b => (a -> b) -> [a] -> [a]
    sortOn (Module, ModuleOrigin) -> Module
    forall a b. (a, b) -> a
    fst ([(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)])
    -> [(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)]
    forall a b. (a -> b) -> a -> b
    $ UniqMap Module ModuleOrigin -> [(Module, ModuleOrigin)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList UniqMap Module ModuleOrigin
    xs) of
                ([], [], [], []) -> [ModuleSuggestion] -> LookupResult
    LookupNotFound [ModuleSuggestion]
    suggestions
                ([(Module, ModuleOrigin)]
    _, [(Module, ModuleOrigin)]
    _, [(Module, ModuleOrigin)]
    _, [(Module
    m, ModuleOrigin
    o)])             -> Module -> (UnitInfo, ModuleOrigin) -> LookupResult
    LookupFound Module
    m (Module -> UnitInfo
    mod_unit Module
    m, ModuleOrigin
    o)
                ([(Module, ModuleOrigin)]
    _, [(Module, ModuleOrigin)]
    _, [(Module, ModuleOrigin)]
    _, exposed :: [(Module, ModuleOrigin)]
    exposed@((Module, ModuleOrigin)
    _:[(Module, ModuleOrigin)]
    _))        -> [(Module, ModuleOrigin)] -> LookupResult
    LookupMultiple [(Module, ModuleOrigin)]
    exposed
                ([], [], unusable :: [(Module, ModuleOrigin)]
    unusable@((Module, ModuleOrigin)
    _:[(Module, ModuleOrigin)]
    _), [])    -> [(Module, ModuleOrigin)] -> LookupResult
    LookupUnusable [(Module, ModuleOrigin)]
    unusable
                ([(Module, ModuleOrigin)]
    hidden_pkg, [(Module, ModuleOrigin)]
    hidden_mod, [(Module, ModuleOrigin)]
    _, []) ->
                  [(Module, ModuleOrigin)]
    -> [(Module, ModuleOrigin)] -> LookupResult
    LookupHidden [(Module, ModuleOrigin)]
    hidden_pkg [(Module, ModuleOrigin)]
    hidden_mod
      where
        classify :: ([(Module, ModuleOrigin)], [(Module, ModuleOrigin)],
     [(Module, ModuleOrigin)], [(Module, ModuleOrigin)])
    -> (Module, ModuleOrigin)
    -> ([(Module, ModuleOrigin)], [(Module, ModuleOrigin)],
        [(Module, ModuleOrigin)], [(Module, ModuleOrigin)])
    classify ([(Module, ModuleOrigin)]
    hidden_pkg, [(Module, ModuleOrigin)]
    hidden_mod, [(Module, ModuleOrigin)]
    unusable, [(Module, ModuleOrigin)]
    exposed) (Module
    m, ModuleOrigin
    origin0) =
          let origin :: ModuleOrigin
    origin = PkgQual -> UnitInfo -> ModuleOrigin -> ModuleOrigin
    filterOrigin PkgQual
    mb_pn (Module -> UnitInfo
    mod_unit Module
    m) ModuleOrigin
    origin0
              x :: (Module, ModuleOrigin)
    x = (Module
    m, ModuleOrigin
    origin)
          in case ModuleOrigin
    origin of
              ModuleOrigin
    ModHidden
                -> ([(Module, ModuleOrigin)]
    hidden_pkg, (Module, ModuleOrigin)
    x(Module, ModuleOrigin)
    -> [(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)]
    forall a. a -> [a] -> [a]
    :[(Module, ModuleOrigin)]
    hidden_mod, [(Module, ModuleOrigin)]
    unusable, [(Module, ModuleOrigin)]
    exposed)
              ModUnusable UnusableUnit
    _
                -> ([(Module, ModuleOrigin)]
    hidden_pkg, [(Module, ModuleOrigin)]
    hidden_mod, (Module, ModuleOrigin)
    x(Module, ModuleOrigin)
    -> [(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)]
    forall a. a -> [a] -> [a]
    :[(Module, ModuleOrigin)]
    unusable, [(Module, ModuleOrigin)]
    exposed)
              ModuleOrigin
    _ | ModuleOrigin -> Bool
    originEmpty ModuleOrigin
    origin
                -> ([(Module, ModuleOrigin)]
    hidden_pkg,   [(Module, ModuleOrigin)]
    hidden_mod, [(Module, ModuleOrigin)]
    unusable, [(Module, ModuleOrigin)]
    exposed)
                | ModuleOrigin -> Bool
    originVisible ModuleOrigin
    origin
                -> ([(Module, ModuleOrigin)]
    hidden_pkg, [(Module, ModuleOrigin)]
    hidden_mod, [(Module, ModuleOrigin)]
    unusable, (Module, ModuleOrigin)
    x(Module, ModuleOrigin)
    -> [(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)]
    forall a. a -> [a] -> [a]
    :[(Module, ModuleOrigin)]
    exposed)
                | Bool
    otherwise
                -> ((Module, ModuleOrigin)
    x(Module, ModuleOrigin)
    -> [(Module, ModuleOrigin)] -> [(Module, ModuleOrigin)]
    forall a. a -> [a] -> [a]
    :[(Module, ModuleOrigin)]
    hidden_pkg, [(Module, ModuleOrigin)]
    hidden_mod, [(Module, ModuleOrigin)]
    unusable, [(Module, ModuleOrigin)]
    exposed)

        unit_lookup :: Unit -> UnitInfo
    unit_lookup Unit
    p = UnitState -> Unit -> Maybe UnitInfo
    lookupUnit UnitState
    pkgs Unit
    p Maybe UnitInfo -> UnitInfo -> UnitInfo
    forall a. Maybe a -> a -> a
    `orElse` String -> SDoc -> UnitInfo
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "lookupModuleWithSuggestions" (Unit -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Unit
    p SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    m)
        mod_unit :: Module -> UnitInfo
    mod_unit = Unit -> UnitInfo
    unit_lookup (Unit -> UnitInfo) -> (Module -> Unit) -> Module -> UnitInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Module -> Unit
    forall unit. GenModule unit -> unit
    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 :: PkgQual
                     -> UnitInfo
                     -> ModuleOrigin
                     -> ModuleOrigin
        filterOrigin :: PkgQual -> UnitInfo -> ModuleOrigin -> ModuleOrigin
    filterOrigin PkgQual
    NoPkgQual UnitInfo
    _ ModuleOrigin
    o = ModuleOrigin
    o
        filterOrigin (ThisPkg UnitId
    _) UnitInfo
    _ ModuleOrigin
    o = ModuleOrigin
    o
        filterOrigin (OtherPkg UnitId
    u) UnitInfo
    pkg ModuleOrigin
    o =
          let match_pkg :: UnitInfo -> Bool
    match_pkg UnitInfo
    p = UnitId
    u UnitId -> UnitId -> Bool
    forall a. Eq a => a -> a -> Bool
    == UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    p
          in case ModuleOrigin
    o of
              ModuleOrigin
    ModHidden
                | UnitInfo -> Bool
    match_pkg UnitInfo
    pkg -> ModuleOrigin
    ModHidden
                | Bool
    otherwise     -> ModuleOrigin
    forall a. Monoid a => a
    mempty
              ModUnusable UnusableUnit
    _
                | UnitInfo -> Bool
    match_pkg UnitInfo
    pkg -> ModuleOrigin
    o
                | Bool
    otherwise     -> ModuleOrigin
    forall a. Monoid a => a
    mempty
              ModOrigin { fromOrigUnit :: ModuleOrigin -> Maybe Bool
    fromOrigUnit = Maybe Bool
    e, fromExposedReexport :: ModuleOrigin -> [UnitInfo]
    fromExposedReexport = [UnitInfo]
    res,
                          fromHiddenReexport :: ModuleOrigin -> [UnitInfo]
    fromHiddenReexport = [UnitInfo]
    rhs }
                -> ModOrigin
                    { fromOrigUnit :: Maybe Bool
    fromOrigUnit        = if UnitInfo -> Bool
    match_pkg UnitInfo
    pkg then Maybe Bool
    e else Maybe Bool
    forall a. Maybe a
    Nothing
                    , fromExposedReexport :: [UnitInfo]
    fromExposedReexport = (UnitInfo -> Bool) -> [UnitInfo] -> [UnitInfo]
    forall a. (a -> Bool) -> [a] -> [a]
    filter UnitInfo -> Bool
    match_pkg [UnitInfo]
    res
                    , fromHiddenReexport :: [UnitInfo]
    fromHiddenReexport  = (UnitInfo -> Bool) -> [UnitInfo] -> [UnitInfo]
    forall a. (a -> Bool) -> [a] -> [a]
    filter UnitInfo -> Bool
    match_pkg [UnitInfo]
    rhs
                    , fromPackageFlag :: Bool
    fromPackageFlag     = Bool
    False -- always excluded
                    }

        suggestions :: [ModuleSuggestion]
    suggestions = String -> [(String, ModuleSuggestion)] -> [ModuleSuggestion]
    forall a. String -> [(String, a)] -> [a]
    fuzzyLookup (ModuleName -> String
    moduleNameString ModuleName
    m) [(String, ModuleSuggestion)]
    all_mods

        all_mods :: [(String, ModuleSuggestion)]     -- All modules
        all_mods :: [(String, ModuleSuggestion)]
    all_mods = ((String, ModuleSuggestion)
     -> (String, ModuleSuggestion) -> Ordering)
    -> [(String, ModuleSuggestion)] -> [(String, ModuleSuggestion)]
    forall a. (a -> a -> Ordering) -> [a] -> [a]
    sortBy (((String, ModuleSuggestion) -> String)
    -> (String, ModuleSuggestion)
    -> (String, ModuleSuggestion)
    -> Ordering
    forall a t. Ord a => (t -> a) -> t -> t -> Ordering
    comparing (String, ModuleSuggestion) -> String
    forall a b. (a, b) -> a
    fst) ([(String, ModuleSuggestion)] -> [(String, ModuleSuggestion)])
    -> [(String, ModuleSuggestion)] -> [(String, ModuleSuggestion)]
    forall a b. (a -> b) -> a -> b
    $
            [ (ModuleName -> String
    moduleNameString ModuleName
    m, ModuleSuggestion
    suggestion)
            | (ModuleName
    m, UniqMap Module ModuleOrigin
    e) <- ModuleNameProvidersMap
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList (UnitState -> ModuleNameProvidersMap
    moduleNameProvidersMap UnitState
    pkgs)
            , ModuleSuggestion
    suggestion <- ((Module, ModuleOrigin) -> ModuleSuggestion)
    -> [(Module, ModuleOrigin)] -> [ModuleSuggestion]
    forall a b. (a -> b) -> [a] -> [b]
    map (ModuleName -> (Module, ModuleOrigin) -> ModuleSuggestion
    getSuggestion ModuleName
    m) (UniqMap Module ModuleOrigin -> [(Module, ModuleOrigin)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList UniqMap Module ModuleOrigin
    e)
            ]
        getSuggestion :: ModuleName -> (Module, ModuleOrigin) -> ModuleSuggestion
    getSuggestion ModuleName
    name (Module
    mod, ModuleOrigin
    origin) =
            (if ModuleOrigin -> Bool
    originVisible ModuleOrigin
    origin then ModuleName -> Module -> ModuleOrigin -> ModuleSuggestion
    SuggestVisible else ModuleName -> Module -> ModuleOrigin -> ModuleSuggestion
    SuggestHidden)
                ModuleName
    name Module
    mod ModuleOrigin
    origin

    listVisibleModuleNames :: UnitState -> [ModuleName]
    listVisibleModuleNames :: UnitState -> [ModuleName]
    listVisibleModuleNames UnitState
    state =
        ((ModuleName, UniqMap Module ModuleOrigin) -> ModuleName)
    -> [(ModuleName, UniqMap Module ModuleOrigin)] -> [ModuleName]
    forall a b. (a -> b) -> [a] -> [b]
    map (ModuleName, UniqMap Module ModuleOrigin) -> ModuleName
    forall a b. (a, b) -> a
    fst (((ModuleName, UniqMap Module ModuleOrigin) -> Bool)
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (ModuleName, UniqMap Module ModuleOrigin) -> Bool
    forall {a} {k}. (a, UniqMap k ModuleOrigin) -> Bool
    visible (ModuleNameProvidersMap
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList (UnitState -> ModuleNameProvidersMap
    moduleNameProvidersMap UnitState
    state)))
      where visible :: (a, UniqMap k ModuleOrigin) -> Bool
    visible (a
    _, UniqMap k ModuleOrigin
    ms) = (ModuleOrigin -> Bool) -> UniqMap k ModuleOrigin -> Bool
    forall a k. (a -> Bool) -> UniqMap k a -> Bool
    anyUniqMap ModuleOrigin -> Bool
    originVisible UniqMap k ModuleOrigin
    ms

    -- | Takes a list of UnitIds (and their "parent" dependency, used for error
    -- messages), and returns the list with dependencies included, in reverse
    -- dependency order (a units appears before those it depends on).
    closeUnitDeps :: UnitInfoMap -> [(UnitId,Maybe UnitId)] -> MaybeErr UnitErr [UnitId]
    closeUnitDeps :: UnitInfoMap
    -> [(UnitId, Maybe UnitId)] -> MaybeErr UnitErr [UnitId]
    closeUnitDeps UnitInfoMap
    pkg_map [(UnitId, Maybe UnitId)]
    ps = UnitInfoMap
    -> [UnitId]
    -> [(UnitId, Maybe UnitId)]
    -> MaybeErr UnitErr [UnitId]
    closeUnitDeps' UnitInfoMap
    pkg_map [] [(UnitId, Maybe UnitId)]
    ps

    -- | Similar to closeUnitDeps but takes a list of already loaded units as an
    -- additional argument.
    closeUnitDeps' :: UnitInfoMap -> [UnitId] -> [(UnitId,Maybe UnitId)] -> MaybeErr UnitErr [UnitId]
    closeUnitDeps' :: UnitInfoMap
    -> [UnitId]
    -> [(UnitId, Maybe UnitId)]
    -> MaybeErr UnitErr [UnitId]
    closeUnitDeps' UnitInfoMap
    pkg_map [UnitId]
    current_ids [(UnitId, Maybe UnitId)]
    ps = ([UnitId] -> (UnitId, Maybe UnitId) -> MaybeErr UnitErr [UnitId])
    -> [UnitId]
    -> [(UnitId, Maybe UnitId)]
    -> MaybeErr UnitErr [UnitId]
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldM ((UnitId -> Maybe UnitId -> MaybeErr UnitErr [UnitId])
    -> (UnitId, Maybe UnitId) -> MaybeErr UnitErr [UnitId]
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry ((UnitId -> Maybe UnitId -> MaybeErr UnitErr [UnitId])
     -> (UnitId, Maybe UnitId) -> MaybeErr UnitErr [UnitId])
    -> ([UnitId]
        -> UnitId -> Maybe UnitId -> MaybeErr UnitErr [UnitId])
    -> [UnitId]
    -> (UnitId, Maybe UnitId)
    -> MaybeErr UnitErr [UnitId]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnitInfoMap
    -> [UnitId] -> UnitId -> Maybe UnitId -> MaybeErr UnitErr [UnitId]
    add_unit UnitInfoMap
    pkg_map) [UnitId]
    current_ids [(UnitId, Maybe UnitId)]
    ps

    -- | Add a UnitId and those it depends on (recursively) to the given list of
    -- UnitIds if they are not already in it. Return a list in reverse dependency
    -- order (a unit appears before those it depends on).
    --
    -- The UnitId is looked up in the given UnitInfoMap (to find its dependencies).
    -- It it's not found, the optional parent unit is used to return a more precise
    -- error message ("dependency of <PARENT>").
    add_unit :: UnitInfoMap
                -> [UnitId]
                -> UnitId
                -> Maybe UnitId
                -> MaybeErr UnitErr [UnitId]
    add_unit :: UnitInfoMap
    -> [UnitId] -> UnitId -> Maybe UnitId -> MaybeErr UnitErr [UnitId]
    add_unit UnitInfoMap
    pkg_map [UnitId]
    ps UnitId
    p Maybe UnitId
    mb_parent
      | UnitId
    p UnitId -> [UnitId] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [UnitId]
    ps = [UnitId] -> MaybeErr UnitErr [UnitId]
    forall a. a -> MaybeErr UnitErr a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [UnitId]
    ps     -- Check if we've already added this unit
      | Bool
    otherwise   = case UnitInfoMap -> UnitId -> Maybe UnitInfo
    lookupUnitId' UnitInfoMap
    pkg_map UnitId
    p of
          Maybe UnitInfo
    Nothing   -> UnitErr -> MaybeErr UnitErr [UnitId]
    forall err val. err -> MaybeErr err val
    Failed (UnitId -> Maybe UnitId -> UnitErr
    CloseUnitErr UnitId
    p Maybe UnitId
    mb_parent)
          Just UnitInfo
    info -> do
             -- Add the unit's dependents also
             ps' <- ([UnitId] -> UnitId -> MaybeErr UnitErr [UnitId])
    -> [UnitId] -> [UnitId] -> MaybeErr UnitErr [UnitId]
    forall (t :: * -> *) (m :: * -> *) b a.
    (Foldable t, Monad m) =>
    (b -> a -> m b) -> b -> t a -> m b
    foldM [UnitId] -> UnitId -> MaybeErr UnitErr [UnitId]
    add_unit_key [UnitId]
    ps (UnitInfo -> [UnitId]
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> [uid]
    unitDepends UnitInfo
    info)
             return (p : ps')
            where
              add_unit_key :: [UnitId] -> UnitId -> MaybeErr UnitErr [UnitId]
    add_unit_key [UnitId]
    xs UnitId
    key
                = UnitInfoMap
    -> [UnitId] -> UnitId -> Maybe UnitId -> MaybeErr UnitErr [UnitId]
    add_unit UnitInfoMap
    pkg_map [UnitId]
    xs UnitId
    key (UnitId -> Maybe UnitId
    forall a. a -> Maybe a
    Just UnitId
    p)

    data UnitErr
      = CloseUnitErr !UnitId !(Maybe UnitId)
      | PackageFlagErr !PackageFlag ![(UnitInfo,UnusableUnitReason)]
      | TrustFlagErr   !TrustFlag   ![(UnitInfo,UnusableUnitReason)]

    mayThrowUnitErr :: MaybeErr UnitErr a -> IO a
    mayThrowUnitErr :: forall a. MaybeErr UnitErr a -> IO a
    mayThrowUnitErr = \case
        Failed UnitErr
    e    -> GhcException -> IO a
    forall a. GhcException -> IO a
    throwGhcExceptionIO
                        (GhcException -> IO a) -> GhcException -> IO a
    forall a b. (a -> b) -> a -> b
    $ String -> GhcException
    CmdLineError
                        (String -> GhcException) -> String -> GhcException
    forall a b. (a -> b) -> a -> b
    $ SDocContext -> SDoc -> String
    renderWithContext SDocContext
    defaultSDocContext
                        (SDoc -> String) -> SDoc -> String
    forall a b. (a -> b) -> a -> b
    $ PprStyle -> SDoc -> SDoc
    withPprStyle PprStyle
    defaultUserStyle
                        (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $ UnitErr -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr UnitErr
    e
        Succeeded a
    a -> a -> IO a
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    a

    instance Outputable UnitErr where
        ppr :: UnitErr -> SDoc
    ppr = \case
            CloseUnitErr UnitId
    p Maybe UnitId
    mb_parent
                -> (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "unknown unit:" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> UnitId -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr UnitId
    p)
                   SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> case Maybe UnitId
    mb_parent of
                         Maybe UnitId
    Nothing     -> SDoc
    forall doc. IsOutput doc => doc
    Outputable.empty
                         Just UnitId
    parent -> SDoc
    forall doc. IsLine doc => doc
    space SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    parens (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "dependency of"
                                                  SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext (UnitId -> FastString
    unitIdFS UnitId
    parent))
            PackageFlagErr PackageFlag
    flag [(UnitInfo, UnusableUnitReason)]
    reasons
                -> SDoc -> [(UnitInfo, UnusableUnitReason)] -> SDoc
    forall {a} {srcpkgid} {srcpkgname} {modulename} {mod}.
    Outputable a =>
    SDoc
    -> [(GenericUnitInfo srcpkgid srcpkgname a modulename mod,
         UnusableUnitReason)]
    -> SDoc
    flag_err (PackageFlag -> SDoc
    pprFlag PackageFlag
    flag) [(UnitInfo, UnusableUnitReason)]
    reasons

            TrustFlagErr TrustFlag
    flag [(UnitInfo, UnusableUnitReason)]
    reasons
                -> SDoc -> [(UnitInfo, UnusableUnitReason)] -> SDoc
    forall {a} {srcpkgid} {srcpkgname} {modulename} {mod}.
    Outputable a =>
    SDoc
    -> [(GenericUnitInfo srcpkgid srcpkgname a modulename mod,
         UnusableUnitReason)]
    -> SDoc
    flag_err (TrustFlag -> SDoc
    pprTrustFlag TrustFlag
    flag) [(UnitInfo, UnusableUnitReason)]
    reasons
          where
            flag_err :: SDoc
    -> [(GenericUnitInfo srcpkgid srcpkgname a modulename mod,
         UnusableUnitReason)]
    -> SDoc
    flag_err SDoc
    flag_doc [(GenericUnitInfo srcpkgid srcpkgname a modulename mod,
      UnusableUnitReason)]
    reasons =
                String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "cannot satisfy "
                SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    flag_doc
                SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> (if [(GenericUnitInfo srcpkgid srcpkgname a modulename mod,
      UnusableUnitReason)]
    -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(GenericUnitInfo srcpkgid srcpkgname a modulename mod,
      UnusableUnitReason)]
    reasons then SDoc
    forall doc. IsOutput doc => doc
    Outputable.empty else String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    ": ")
                SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Int -> SDoc -> SDoc
    nest Int
    4 ([SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat (((GenericUnitInfo srcpkgid srcpkgname a modulename mod,
      UnusableUnitReason)
     -> SDoc)
    -> [(GenericUnitInfo srcpkgid srcpkgname a modulename mod,
         UnusableUnitReason)]
    -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (GenericUnitInfo srcpkgid srcpkgname a modulename mod,
     UnusableUnitReason)
    -> SDoc
    forall {a} {srcpkgid} {srcpkgname} {modulename} {mod}.
    Outputable a =>
    (GenericUnitInfo srcpkgid srcpkgname a modulename mod,
     UnusableUnitReason)
    -> SDoc
    ppr_reason [(GenericUnitInfo srcpkgid srcpkgname a modulename mod,
      UnusableUnitReason)]
    reasons) SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$
                          String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "(use -v for more information)")

            ppr_reason :: (GenericUnitInfo srcpkgid srcpkgname a modulename mod,
     UnusableUnitReason)
    -> SDoc
    ppr_reason (GenericUnitInfo srcpkgid srcpkgname a modulename mod
    p, UnusableUnitReason
    reason) =
                SDoc -> UnusableUnitReason -> SDoc
    pprReason (a -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (GenericUnitInfo srcpkgid srcpkgname a modulename mod -> a
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId GenericUnitInfo srcpkgid srcpkgname a modulename mod
    p) SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "is") UnusableUnitReason
    reason

    -- | Return this list of requirement interfaces that need to be merged
    -- to form @mod_name@, or @[]@ if this is not a requirement.
    requirementMerges :: UnitState -> ModuleName -> [InstantiatedModule]
    requirementMerges :: UnitState -> ModuleName -> [InstantiatedModule]
    requirementMerges UnitState
    pkgstate ModuleName
    mod_name =
      [InstantiatedModule]
    -> Maybe [InstantiatedModule] -> [InstantiatedModule]
    forall a. a -> Maybe a -> a
    fromMaybe [] (UniqMap ModuleName [InstantiatedModule]
    -> ModuleName -> Maybe [InstantiatedModule]
    forall k a. Uniquable k => UniqMap k a -> k -> Maybe a
    lookupUniqMap (UnitState -> UniqMap ModuleName [InstantiatedModule]
    requirementContext UnitState
    pkgstate) ModuleName
    mod_name)

    -- -----------------------------------------------------------------------------

    -- | Pretty-print a UnitId for the user.
    --
    -- Cabal packages may contain several components (programs, libraries, etc.).
    -- As far as GHC is concerned, installed package components ("units") are
    -- identified by an opaque UnitId 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 a unit database.
    pprUnitIdForUser :: UnitState -> UnitId -> SDoc
    pprUnitIdForUser :: UnitState -> UnitId -> SDoc
    pprUnitIdForUser UnitState
    state uid :: UnitId
    uid@(UnitId FastString
    fs) =
       case UnitState -> UnitId -> Maybe UnitPprInfo
    lookupUnitPprInfo UnitState
    state UnitId
    uid of
          Maybe UnitPprInfo
    Nothing -> FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext FastString
    fs -- we didn't find the unit at all
          Just UnitPprInfo
    i  -> UnitPprInfo -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr UnitPprInfo
    i

    pprUnitInfoForUser :: UnitInfo -> SDoc
    pprUnitInfoForUser :: UnitInfo -> SDoc
    pprUnitInfoForUser UnitInfo
    info = UnitPprInfo -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ((UnitId -> FastString) -> UnitInfo -> UnitPprInfo
    forall u. (u -> FastString) -> GenUnitInfo u -> UnitPprInfo
    mkUnitPprInfo UnitId -> FastString
    unitIdFS UnitInfo
    info)

    lookupUnitPprInfo :: UnitState -> UnitId -> Maybe UnitPprInfo
    lookupUnitPprInfo :: UnitState -> UnitId -> Maybe UnitPprInfo
    lookupUnitPprInfo UnitState
    state UnitId
    uid = (UnitInfo -> UnitPprInfo) -> Maybe UnitInfo -> Maybe UnitPprInfo
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((UnitId -> FastString) -> UnitInfo -> UnitPprInfo
    forall u. (u -> FastString) -> GenUnitInfo u -> UnitPprInfo
    mkUnitPprInfo UnitId -> FastString
    unitIdFS) (UnitState -> UnitId -> Maybe UnitInfo
    lookupUnitId UnitState
    state UnitId
    uid)

    -- -----------------------------------------------------------------------------
    -- Displaying packages

    -- | Show (very verbose) package info
    pprUnits :: UnitState -> SDoc
    pprUnits :: UnitState -> SDoc
    pprUnits = (UnitInfo -> SDoc) -> UnitState -> SDoc
    pprUnitsWith UnitInfo -> SDoc
    pprUnitInfo

    pprUnitsWith :: (UnitInfo -> SDoc) -> UnitState -> SDoc
    pprUnitsWith :: (UnitInfo -> SDoc) -> UnitState -> SDoc
    pprUnitsWith UnitInfo -> SDoc
    pprIPI UnitState
    pkgstate =
        [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat (SDoc -> [SDoc] -> [SDoc]
    forall a. a -> [a] -> [a]
    intersperse (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "---") ((UnitInfo -> SDoc) -> [UnitInfo] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map UnitInfo -> SDoc
    pprIPI (UnitState -> [UnitInfo]
    listUnitInfo UnitState
    pkgstate)))

    -- | Show simplified unit info.
    --
    -- The idea is to only print package id, and any information that might
    -- be different from the package databases (exposure, trust)
    pprUnitsSimple :: UnitState -> SDoc
    pprUnitsSimple :: UnitState -> SDoc
    pprUnitsSimple = (UnitInfo -> SDoc) -> UnitState -> SDoc
    pprUnitsWith UnitInfo -> SDoc
    forall {doc} {srcpkgid} {srcpkgname} {modulename} {mod}.
    IsLine doc =>
    GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod -> doc
    pprIPI
        where pprIPI :: GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod -> doc
    pprIPI GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    ipi = let i :: FastString
    i = UnitId -> FastString
    unitIdFS (GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    ipi)
                               e :: doc
    e = if GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod -> Bool
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> Bool
    unitIsExposed GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    ipi then String -> doc
    forall doc. IsLine doc => String -> doc
    text String
    "E" else String -> doc
    forall doc. IsLine doc => String -> doc
    text String
    " "
                               t :: doc
    t = if GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod -> Bool
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> Bool
    unitIsTrusted GenericUnitInfo srcpkgid srcpkgname UnitId modulename mod
    ipi then String -> doc
    forall doc. IsLine doc => String -> doc
    text String
    "T" else String -> doc
    forall doc. IsLine doc => String -> doc
    text String
    " "
                           in doc
    e doc -> doc -> doc
    forall doc. IsLine doc => doc -> doc -> doc
    <> doc
    t doc -> doc -> doc
    forall doc. IsLine doc => doc -> doc -> doc
    <> String -> doc
    forall doc. IsLine doc => String -> doc
    text String
    "  " doc -> doc -> doc
    forall doc. IsLine doc => doc -> doc -> doc
    <> FastString -> doc
    forall doc. IsLine doc => FastString -> doc
    ftext FastString
    i

    -- | Show the mapping of modules to where they come from.
    pprModuleMap :: ModuleNameProvidersMap -> SDoc
    pprModuleMap :: ModuleNameProvidersMap -> SDoc
    pprModuleMap ModuleNameProvidersMap
    mod_map =
      [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat (((ModuleName, UniqMap Module ModuleOrigin) -> SDoc)
    -> [(ModuleName, UniqMap Module ModuleOrigin)] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (ModuleName, UniqMap Module ModuleOrigin) -> SDoc
    forall {a}. Outputable a => (ModuleName, UniqMap Module a) -> SDoc
    pprLine (ModuleNameProvidersMap
    -> [(ModuleName, UniqMap Module ModuleOrigin)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList ModuleNameProvidersMap
    mod_map))
        where
          pprLine :: (ModuleName, UniqMap Module a) -> SDoc
    pprLine (ModuleName
    m,UniqMap Module a
    e) = ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ModuleName
    m SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ Int -> SDoc -> SDoc
    nest Int
    50 ([SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat (((Module, a) -> SDoc) -> [(Module, a)] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map (ModuleName -> (Module, a) -> SDoc
    forall a. Outputable a => ModuleName -> (Module, a) -> SDoc
    pprEntry ModuleName
    m) (UniqMap Module a -> [(Module, a)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetUniqMapToList UniqMap Module a
    e)))
          pprEntry :: Outputable a => ModuleName -> (Module, a) -> SDoc
          pprEntry :: forall a. Outputable a => ModuleName -> (Module, a) -> SDoc
    pprEntry ModuleName
    m (Module
    m',a
    o)
            | ModuleName
    m ModuleName -> ModuleName -> Bool
    forall a. Eq a => a -> a -> Bool
    == Module -> ModuleName
    forall unit. GenModule unit -> ModuleName
    moduleName Module
    m' = Unit -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    m') SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    parens (a -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr a
    o)
            | Bool
    otherwise = Module -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Module
    m' SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    parens (a -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr a
    o)

    fsPackageName :: UnitInfo -> FastString
    fsPackageName :: UnitInfo -> FastString
    fsPackageName UnitInfo
    info = FastString
    fs
       where
          PackageName FastString
    fs = UnitInfo -> PackageName
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod
    -> srcpkgname
    unitPackageName UnitInfo
    info

    -- | Given a fully instantiated 'InstantiatedUnit', improve it into a
    -- 'RealUnit' if we can find it in the package database.
    improveUnit :: UnitState -> Unit -> Unit
    improveUnit :: UnitState -> Unit -> Unit
    improveUnit UnitState
    state Unit
    u = UnitInfoMap -> PreloadUnitClosure -> Unit -> Unit
    improveUnit' (UnitState -> UnitInfoMap
    unitInfoMap UnitState
    state) (UnitState -> PreloadUnitClosure
    preloadClosure UnitState
    state) Unit
    u

    -- | Given a fully instantiated 'InstantiatedUnit', improve it into a
    -- 'RealUnit' if we can find it in the package database.
    improveUnit' :: UnitInfoMap -> PreloadUnitClosure -> Unit -> Unit
    improveUnit' :: UnitInfoMap -> PreloadUnitClosure -> Unit -> Unit
    improveUnit' UnitInfoMap
    _       PreloadUnitClosure
    _       uid :: Unit
    uid@(RealUnit Definite UnitId
    _) = Unit
    uid -- short circuit
    improveUnit' UnitInfoMap
    pkg_map PreloadUnitClosure
    closure Unit
    uid =
        -- Do NOT lookup indefinite ones, they won't be useful!
        case Bool -> UnitInfoMap -> PreloadUnitClosure -> Unit -> Maybe UnitInfo
    lookupUnit' Bool
    False UnitInfoMap
    pkg_map PreloadUnitClosure
    closure Unit
    uid of
            Maybe UnitInfo
    Nothing  -> Unit
    uid
            Just UnitInfo
    pkg ->
                -- Do NOT improve if the indefinite unit id is not
                -- part of the closure unique set.  See
                -- Note [VirtUnit to RealUnit improvement]
                if UnitInfo -> UnitId
    forall srcpkgid srcpkgname uid modulename mod.
    GenericUnitInfo srcpkgid srcpkgname uid modulename mod -> uid
    unitId UnitInfo
    pkg UnitId -> PreloadUnitClosure -> Bool
    forall a. Uniquable a => a -> UniqSet a -> Bool
    `elementOfUniqSet` PreloadUnitClosure
    closure
                    then UnitInfo -> Unit
    mkUnit UnitInfo
    pkg
                    else Unit
    uid

    -- | Check the database to see if we already have an installed unit that
    -- corresponds to the given 'InstantiatedUnit'.
    --
    -- Return a `UnitId` which either wraps the `InstantiatedUnit` unchanged or
    -- references a matching installed unit.
    --
    -- See Note [VirtUnit to RealUnit improvement]
    instUnitToUnit :: UnitState -> InstantiatedUnit -> Unit
    instUnitToUnit :: UnitState -> GenInstantiatedUnit UnitId -> Unit
    instUnitToUnit UnitState
    state GenInstantiatedUnit UnitId
    iuid =
        -- NB: suppose that we want to compare the instantiated
        -- unit p[H=impl:H] against p+abcd (where p+abcd
        -- happens to be the existing, installed version of
        -- p[H=impl:H].  If we *only* wrap in p[H=impl:H]
        -- VirtUnit, they won't compare equal; only
        -- after improvement will the equality hold.
        UnitState -> Unit -> Unit
    improveUnit UnitState
    state (Unit -> Unit) -> Unit -> Unit
    forall a b. (a -> b) -> a -> b
    $ GenInstantiatedUnit UnitId -> Unit
    forall uid. GenInstantiatedUnit uid -> GenUnit uid
    VirtUnit GenInstantiatedUnit UnitId
    iuid

    -- | Substitution on module variables, mapping module names to module
    -- identifiers.
    type ShHoleSubst = ModuleNameEnv Module

    -- | Substitutes holes in a 'Module'.  NOT suitable for being called
    -- directly on a 'nameModule', see Note [Representation of module/name variables].
    -- @p[A=\<A>]:B@ maps to @p[A=q():A]:B@ with @A=q():A@;
    -- similarly, @\<A>@ maps to @q():A@.
    renameHoleModule :: UnitState -> ShHoleSubst -> Module -> Module
    renameHoleModule :: UnitState -> UniqFM ModuleName Module -> Module -> Module
    renameHoleModule UnitState
    state = UnitInfoMap
    -> PreloadUnitClosure
    -> UniqFM ModuleName Module
    -> Module
    -> Module
    renameHoleModule' (UnitState -> UnitInfoMap
    unitInfoMap UnitState
    state) (UnitState -> PreloadUnitClosure
    preloadClosure UnitState
    state)

    -- | Substitutes holes in a 'Unit', suitable for renaming when
    -- an include occurs; see Note [Representation of module/name variables].
    --
    -- @p[A=\<A>]@ maps to @p[A=\<B>]@ with @A=\<B>@.
    renameHoleUnit :: UnitState -> ShHoleSubst -> Unit -> Unit
    renameHoleUnit :: UnitState -> UniqFM ModuleName Module -> Unit -> Unit
    renameHoleUnit UnitState
    state = UnitInfoMap
    -> PreloadUnitClosure -> UniqFM ModuleName Module -> Unit -> Unit
    renameHoleUnit' (UnitState -> UnitInfoMap
    unitInfoMap UnitState
    state) (UnitState -> PreloadUnitClosure
    preloadClosure UnitState
    state)

    -- | Like 'renameHoleModule', but requires only 'ClosureUnitInfoMap'
    -- so it can be used by "GHC.Unit.State".
    renameHoleModule' :: UnitInfoMap -> PreloadUnitClosure -> ShHoleSubst -> Module -> Module
    renameHoleModule' :: UnitInfoMap
    -> PreloadUnitClosure
    -> UniqFM ModuleName Module
    -> Module
    -> Module
    renameHoleModule' UnitInfoMap
    pkg_map PreloadUnitClosure
    closure UniqFM ModuleName Module
    env Module
    m
      | Bool -> Bool
    not (Module -> Bool
    forall u. GenModule (GenUnit u) -> Bool
    isHoleModule Module
    m) =
            let uid :: Unit
    uid = UnitInfoMap
    -> PreloadUnitClosure -> UniqFM ModuleName Module -> Unit -> Unit
    renameHoleUnit' UnitInfoMap
    pkg_map PreloadUnitClosure
    closure UniqFM ModuleName Module
    env (Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    m)
            in Unit -> ModuleName -> Module
    forall unit. unit -> ModuleName -> GenModule unit
    mkModule Unit
    uid (Module -> ModuleName
    forall unit. GenModule unit -> ModuleName
    moduleName Module
    m)
      | Just Module
    m' <- UniqFM ModuleName Module -> ModuleName -> Maybe Module
    forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
    lookupUFM UniqFM ModuleName Module
    env (Module -> ModuleName
    forall unit. GenModule unit -> ModuleName
    moduleName Module
    m) = Module
    m'
      -- NB m = <Blah>, that's what's in scope.
      | Bool
    otherwise = Module
    m

    -- | Like 'renameHoleUnit, but requires only 'ClosureUnitInfoMap'
    -- so it can be used by "GHC.Unit.State".
    renameHoleUnit' :: UnitInfoMap -> PreloadUnitClosure -> ShHoleSubst -> Unit -> Unit
    renameHoleUnit' :: UnitInfoMap
    -> PreloadUnitClosure -> UniqFM ModuleName Module -> Unit -> Unit
    renameHoleUnit' UnitInfoMap
    pkg_map PreloadUnitClosure
    closure UniqFM ModuleName Module
    env Unit
    uid =
        case Unit
    uid of
          (VirtUnit
            InstantiatedUnit{ instUnitInstanceOf :: forall unit. GenInstantiatedUnit unit -> unit
    instUnitInstanceOf = UnitId
    cid
                            , instUnitInsts :: forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
    instUnitInsts      = [(ModuleName, Module)]
    insts
                            , instUnitHoles :: forall unit. GenInstantiatedUnit unit -> UniqDSet ModuleName
    instUnitHoles      = UniqDSet ModuleName
    fh })
              -> if UniqFM ModuleName ModuleName -> Bool
    forall {k} (key :: k) elt. UniqFM key elt -> Bool
    isNullUFM ((ModuleName -> Module -> ModuleName)
    -> UniqFM ModuleName ModuleName
    -> UniqFM ModuleName Module
    -> UniqFM ModuleName ModuleName
    forall {k} elt1 elt2 elt3 (key :: k).
    (elt1 -> elt2 -> elt3)
    -> UniqFM key elt1 -> UniqFM key elt2 -> UniqFM key elt3
    intersectUFM_C ModuleName -> Module -> ModuleName
    forall a b. a -> b -> a
    const (UniqDFM ModuleName ModuleName -> UniqFM ModuleName ModuleName
    forall {k} (key :: k) elt. UniqDFM key elt -> UniqFM key elt
    udfmToUfm (UniqDSet ModuleName -> UniqDFM ModuleName ModuleName
    forall a. UniqDSet a -> UniqDFM a a
    getUniqDSet UniqDSet ModuleName
    fh)) UniqFM ModuleName Module
    env)
                    then Unit
    uid
                    -- Functorially apply the substitution to the instantiation,
                    -- then check the 'ClosureUnitInfoMap' to see if there is
                    -- a compiled version of this 'InstantiatedUnit' we can improve to.
                    -- See Note [VirtUnit to RealUnit improvement]
                    else UnitInfoMap -> PreloadUnitClosure -> Unit -> Unit
    improveUnit' UnitInfoMap
    pkg_map PreloadUnitClosure
    closure (Unit -> Unit) -> Unit -> Unit
    forall a b. (a -> b) -> a -> b
    $
                            UnitId -> [(ModuleName, Module)] -> Unit
    forall u.
    IsUnitId u =>
    u -> [(ModuleName, GenModule (GenUnit u))] -> GenUnit u
    mkVirtUnit UnitId
    cid
                                (((ModuleName, Module) -> (ModuleName, Module))
    -> [(ModuleName, Module)] -> [(ModuleName, Module)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(ModuleName
    k,Module
    v) -> (ModuleName
    k, UnitInfoMap
    -> PreloadUnitClosure
    -> UniqFM ModuleName Module
    -> Module
    -> Module
    renameHoleModule' UnitInfoMap
    pkg_map PreloadUnitClosure
    closure UniqFM ModuleName Module
    env Module
    v)) [(ModuleName, Module)]
    insts)
          Unit
    _ -> Unit
    uid

    -- | Injects an 'InstantiatedModule' to 'Module' (see also
    -- 'instUnitToUnit'.
    instModuleToModule :: UnitState -> InstantiatedModule -> Module
    instModuleToModule :: UnitState -> InstantiatedModule -> Module
    instModuleToModule UnitState
    pkgstate (Module GenInstantiatedUnit UnitId
    iuid ModuleName
    mod_name) =
        Unit -> ModuleName -> Module
    forall unit. unit -> ModuleName -> GenModule unit
    mkModule (UnitState -> GenInstantiatedUnit UnitId -> Unit
    instUnitToUnit UnitState
    pkgstate GenInstantiatedUnit UnitId
    iuid) ModuleName
    mod_name

    -- | Print unit-ids with UnitInfo found in the given UnitState
    pprWithUnitState :: UnitState -> SDoc -> SDoc
    pprWithUnitState :: UnitState -> SDoc -> SDoc
    pprWithUnitState UnitState
    state = (SDocContext -> SDocContext) -> SDoc -> SDoc
    updSDocContext (\SDocContext
    ctx -> SDocContext
    ctx
       { sdocUnitIdForUser = \FastString
    fs -> UnitState -> UnitId -> SDoc
    pprUnitIdForUser UnitState
    state (FastString -> UnitId
    UnitId FastString
    fs)
       })