    -- | Module environment
    module GHC.Unit.Module.Env
       ( -- * Module mappings
         ModuleEnv
       , elemModuleEnv, extendModuleEnv, extendModuleEnvList
       , extendModuleEnvList_C, plusModuleEnv_C
       , delModuleEnvList, delModuleEnv, plusModuleEnv, lookupModuleEnv
       , lookupWithDefaultModuleEnv, mapModuleEnv, mkModuleEnv, emptyModuleEnv
       , alterModuleEnv
       , partitionModuleEnv
       , moduleEnvKeys, moduleEnvElts, moduleEnvToList
       , unitModuleEnv, isEmptyModuleEnv
       , extendModuleEnvWith, filterModuleEnv, mapMaybeModuleEnv

         -- * ModuleName mappings
       , ModuleNameEnv, DModuleNameEnv

         -- * Sets of Modules
       , ModuleSet
       , emptyModuleSet, mkModuleSet, moduleSetElts
       , extendModuleSet, extendModuleSetList, delModuleSet
       , elemModuleSet, intersectModuleSet, minusModuleSet, unionModuleSet
       , unitModuleSet, isEmptyModuleSet
       , unionManyModuleSets

         -- * InstalledModuleEnv
       , InstalledModuleEnv
       , emptyInstalledModuleEnv
       , lookupInstalledModuleEnv
       , extendInstalledModuleEnv
       , filterInstalledModuleEnv
       , delInstalledModuleEnv
       , mergeInstalledModuleEnv
       , plusInstalledModuleEnv
       , installedModuleEnvElts

         -- * InstalledModuleWithIsBootEnv
       , InstalledModuleWithIsBootEnv
       , emptyInstalledModuleWithIsBootEnv
       , lookupInstalledModuleWithIsBootEnv
       , extendInstalledModuleWithIsBootEnv
       , filterInstalledModuleWithIsBootEnv
       , delInstalledModuleWithIsBootEnv
       , mergeInstalledModuleWithIsBootEnv
       , plusInstalledModuleWithIsBootEnv
       , installedModuleWithIsBootEnvElts
       )
    where

    import GHC.Prelude

    import GHC.Types.Unique
    import GHC.Types.Unique.FM
    import GHC.Types.Unique.DFM
    import GHC.Unit.Types
    import Data.List (sortBy, sort)
    import Data.Ord

    import Data.Coerce
    import Data.Map (Map)
    import Data.Set (Set)
    import qualified Data.Map as Map
    import qualified Data.Set as Set
    import qualified Data.Semigroup as S
    import qualified GHC.Data.FiniteMap as Map
    import GHC.Utils.Outputable

    import Language.Haskell.Syntax.Module.Name

    -- | A map keyed off of 'Module's
    newtype ModuleEnv elt = ModuleEnv (Map NDModule elt)

    instance Outputable a => Outputable (ModuleEnv a) where
      ppr :: ModuleEnv a -> SDoc
    ppr (ModuleEnv Map NDModule a
    m) = Map NDModule a -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Map NDModule a
    m

    {-
    Note [ModuleEnv performance and determinism]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    To prevent accidental reintroduction of nondeterminism the Ord instance
    for Module was changed to not depend on Unique ordering and to use the
    lexicographic order. This is potentially expensive, but when measured
    there was no difference in performance.

    To be on the safe side and not pessimize ModuleEnv uses nondeterministic
    ordering on Module and normalizes by doing the lexicographic sort when
    turning the env to a list.
    See Note [Unique Determinism] for more information about the source of
    nondeterminism and Note [Deterministic UniqFM] for explanation of why
    it matters for maps.
    -}

    newtype NDModule = NDModule { NDModule -> Module
    unNDModule :: Module }
      deriving NDModule -> NDModule -> Bool
    (NDModule -> NDModule -> Bool)
    -> (NDModule -> NDModule -> Bool) -> Eq NDModule
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: NDModule -> NDModule -> Bool
    == :: NDModule -> NDModule -> Bool
    $c/= :: NDModule -> NDModule -> Bool
    /= :: NDModule -> NDModule -> Bool
    Eq
      -- A wrapper for Module with faster nondeterministic Ord.
      -- Don't export, See [ModuleEnv performance and determinism]
      --
    instance Outputable NDModule where
      ppr :: NDModule -> SDoc
    ppr (NDModule Module
    a) = Module -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Module
    a

    instance Ord NDModule where
      compare :: NDModule -> NDModule -> Ordering
    compare (NDModule (Module GenUnit UnitId
    p1 ModuleName
    n1)) (NDModule (Module GenUnit UnitId
    p2 ModuleName
    n2)) =
        (GenUnit UnitId -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique GenUnit UnitId
    p1 Unique -> Unique -> Ordering
    `nonDetCmpUnique` GenUnit UnitId -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique GenUnit UnitId
    p2) Ordering -> Ordering -> Ordering
    forall a. Semigroup a => a -> a -> a
    S.<>
        (ModuleName -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique ModuleName
    n1 Unique -> Unique -> Ordering
    `nonDetCmpUnique` ModuleName -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique ModuleName
    n2)

    filterModuleEnv :: (Module -> a -> Bool) -> ModuleEnv a -> ModuleEnv a
    filterModuleEnv :: forall a. (Module -> a -> Bool) -> ModuleEnv a -> ModuleEnv a
    filterModuleEnv Module -> a -> Bool
    f (ModuleEnv Map NDModule a
    e) =
      Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ((NDModule -> a -> Bool) -> Map NDModule a -> Map NDModule a
    forall k a. (k -> a -> Bool) -> Map k a -> Map k a
    Map.filterWithKey (Module -> a -> Bool
    f (Module -> a -> Bool)
    -> (NDModule -> Module) -> NDModule -> a -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NDModule -> Module
    unNDModule) Map NDModule a
    e)

    mapMaybeModuleEnv :: (Module -> a -> Maybe b) -> ModuleEnv a -> ModuleEnv b
    mapMaybeModuleEnv :: forall a b. (Module -> a -> Maybe b) -> ModuleEnv a -> ModuleEnv b
    mapMaybeModuleEnv Module -> a -> Maybe b
    f (ModuleEnv Map NDModule a
    e) =
      Map NDModule b -> ModuleEnv b
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ((NDModule -> a -> Maybe b) -> Map NDModule a -> Map NDModule b
    forall k a b. (k -> a -> Maybe b) -> Map k a -> Map k b
    Map.mapMaybeWithKey (Module -> a -> Maybe b
    f (Module -> a -> Maybe b)
    -> (NDModule -> Module) -> NDModule -> a -> Maybe b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NDModule -> Module
    unNDModule) Map NDModule a
    e)

    elemModuleEnv :: Module -> ModuleEnv a -> Bool
    elemModuleEnv :: forall a. Module -> ModuleEnv a -> Bool
    elemModuleEnv Module
    m (ModuleEnv Map NDModule a
    e) = NDModule -> Map NDModule a -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    Map.member (Module -> NDModule
    NDModule Module
    m) Map NDModule a
    e

    extendModuleEnv :: ModuleEnv a -> Module -> a -> ModuleEnv a
    extendModuleEnv :: forall a. ModuleEnv a -> Module -> a -> ModuleEnv a
    extendModuleEnv (ModuleEnv Map NDModule a
    e) Module
    m a
    x = Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv (NDModule -> a -> Map NDModule a -> Map NDModule a
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert (Module -> NDModule
    NDModule Module
    m) a
    x Map NDModule a
    e)

    extendModuleEnvWith :: (a -> a -> a) -> ModuleEnv a -> Module -> a
                        -> ModuleEnv a
    extendModuleEnvWith :: forall a.
    (a -> a -> a) -> ModuleEnv a -> Module -> a -> ModuleEnv a
    extendModuleEnvWith a -> a -> a
    f (ModuleEnv Map NDModule a
    e) Module
    m a
    x =
      Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ((a -> a -> a) -> NDModule -> a -> Map NDModule a -> Map NDModule a
    forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
    Map.insertWith a -> a -> a
    f (Module -> NDModule
    NDModule Module
    m) a
    x Map NDModule a
    e)

    extendModuleEnvList :: ModuleEnv a -> [(Module, a)] -> ModuleEnv a
    extendModuleEnvList :: forall a. ModuleEnv a -> [(Module, a)] -> ModuleEnv a
    extendModuleEnvList (ModuleEnv Map NDModule a
    e) [(Module, a)]
    xs =
      Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ([(NDModule, a)] -> Map NDModule a -> Map NDModule a
    forall key elt.
    Ord key =>
    [(key, elt)] -> Map key elt -> Map key elt
    Map.insertList [(Module -> NDModule
    NDModule Module
    k, a
    v) | (Module
    k,a
    v) <- [(Module, a)]
    xs] Map NDModule a
    e)

    extendModuleEnvList_C :: (a -> a -> a) -> ModuleEnv a -> [(Module, a)]
                          -> ModuleEnv a
    extendModuleEnvList_C :: forall a.
    (a -> a -> a) -> ModuleEnv a -> [(Module, a)] -> ModuleEnv a
    extendModuleEnvList_C a -> a -> a
    f (ModuleEnv Map NDModule a
    e) [(Module, a)]
    xs =
      Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ((a -> a -> a)
    -> [(NDModule, a)] -> Map NDModule a -> Map NDModule a
    forall key elt.
    Ord key =>
    (elt -> elt -> elt) -> [(key, elt)] -> Map key elt -> Map key elt
    Map.insertListWith a -> a -> a
    f [(Module -> NDModule
    NDModule Module
    k, a
    v) | (Module
    k,a
    v) <- [(Module, a)]
    xs] Map NDModule a
    e)

    plusModuleEnv_C :: (a -> a -> a) -> ModuleEnv a -> ModuleEnv a -> ModuleEnv a
    plusModuleEnv_C :: forall a.
    (a -> a -> a) -> ModuleEnv a -> ModuleEnv a -> ModuleEnv a
    plusModuleEnv_C a -> a -> a
    f (ModuleEnv Map NDModule a
    e1) (ModuleEnv Map NDModule a
    e2) =
      Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ((a -> a -> a) -> Map NDModule a -> Map NDModule a -> Map NDModule a
    forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
    Map.unionWith a -> a -> a
    f Map NDModule a
    e1 Map NDModule a
    e2)

    delModuleEnvList :: ModuleEnv a -> [Module] -> ModuleEnv a
    delModuleEnvList :: forall a. ModuleEnv a -> [Module] -> ModuleEnv a
    delModuleEnvList (ModuleEnv Map NDModule a
    e) [Module]
    ms =
      Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ([NDModule] -> Map NDModule a -> Map NDModule a
    forall key elt. Ord key => [key] -> Map key elt -> Map key elt
    Map.deleteList ((Module -> NDModule) -> [Module] -> [NDModule]
    forall a b. (a -> b) -> [a] -> [b]
    map Module -> NDModule
    NDModule [Module]
    ms) Map NDModule a
    e)

    delModuleEnv :: ModuleEnv a -> Module -> ModuleEnv a
    delModuleEnv :: forall a. ModuleEnv a -> Module -> ModuleEnv a
    delModuleEnv (ModuleEnv Map NDModule a
    e) Module
    m = Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv (NDModule -> Map NDModule a -> Map NDModule a
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete (Module -> NDModule
    NDModule Module
    m) Map NDModule a
    e)

    plusModuleEnv :: ModuleEnv a -> ModuleEnv a -> ModuleEnv a
    plusModuleEnv :: forall a. ModuleEnv a -> ModuleEnv a -> ModuleEnv a
    plusModuleEnv (ModuleEnv Map NDModule a
    e1) (ModuleEnv Map NDModule a
    e2) = Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv (Map NDModule a -> Map NDModule a -> Map NDModule a
    forall k a. Ord k => Map k a -> Map k a -> Map k a
    Map.union Map NDModule a
    e1 Map NDModule a
    e2)

    lookupModuleEnv :: ModuleEnv a -> Module -> Maybe a
    lookupModuleEnv :: forall a. ModuleEnv a -> Module -> Maybe a
    lookupModuleEnv (ModuleEnv Map NDModule a
    e) Module
    m = NDModule -> Map NDModule a -> Maybe a
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup (Module -> NDModule
    NDModule Module
    m) Map NDModule a
    e

    lookupWithDefaultModuleEnv :: ModuleEnv a -> a -> Module -> a
    lookupWithDefaultModuleEnv :: forall a. ModuleEnv a -> a -> Module -> a
    lookupWithDefaultModuleEnv (ModuleEnv Map NDModule a
    e) a
    x Module
    m =
      a -> NDModule -> Map NDModule a -> a
    forall k a. Ord k => a -> k -> Map k a -> a
    Map.findWithDefault a
    x (Module -> NDModule
    NDModule Module
    m) Map NDModule a
    e

    mapModuleEnv :: (a -> b) -> ModuleEnv a -> ModuleEnv b
    mapModuleEnv :: forall a b. (a -> b) -> ModuleEnv a -> ModuleEnv b
    mapModuleEnv a -> b
    f (ModuleEnv Map NDModule a
    e) = Map NDModule b -> ModuleEnv b
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ((NDModule -> a -> b) -> Map NDModule a -> Map NDModule b
    forall k a b. (k -> a -> b) -> Map k a -> Map k b
    Map.mapWithKey (\NDModule
    _ a
    v -> a -> b
    f a
    v) Map NDModule a
    e)

    partitionModuleEnv :: (a -> Bool) -> ModuleEnv a -> (ModuleEnv a, ModuleEnv a)
    partitionModuleEnv :: forall a. (a -> Bool) -> ModuleEnv a -> (ModuleEnv a, ModuleEnv a)
    partitionModuleEnv a -> Bool
    f (ModuleEnv Map NDModule a
    e) = (Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv Map NDModule a
    a, Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv Map NDModule a
    b)
      where
        (Map NDModule a
    a,Map NDModule a
    b) = (a -> Bool) -> Map NDModule a -> (Map NDModule a, Map NDModule a)
    forall a k. (a -> Bool) -> Map k a -> (Map k a, Map k a)
    Map.partition a -> Bool
    f Map NDModule a
    e

    alterModuleEnv :: (Maybe a -> Maybe a) -> Module -> ModuleEnv a -> ModuleEnv a
    alterModuleEnv :: forall a.
    (Maybe a -> Maybe a) -> Module -> ModuleEnv a -> ModuleEnv a
    alterModuleEnv Maybe a -> Maybe a
    f Module
    m (ModuleEnv Map NDModule a
    e) = Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ((Maybe a -> Maybe a)
    -> NDModule -> Map NDModule a -> Map NDModule a
    forall k a.
    Ord k =>
    (Maybe a -> Maybe a) -> k -> Map k a -> Map k a
    Map.alter Maybe a -> Maybe a
    f (Module -> NDModule
    NDModule Module
    m) Map NDModule a
    e)

    mkModuleEnv :: [(Module, a)] -> ModuleEnv a
    mkModuleEnv :: forall a. [(Module, a)] -> ModuleEnv a
    mkModuleEnv [(Module, a)]
    xs = Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv ([(NDModule, a)] -> Map NDModule a
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [(Module -> NDModule
    NDModule Module
    k, a
    v) | (Module
    k,a
    v) <- [(Module, a)]
    xs])

    emptyModuleEnv :: ModuleEnv a
    emptyModuleEnv :: forall a. ModuleEnv a
    emptyModuleEnv = Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv Map NDModule a
    forall k a. Map k a
    Map.empty

    moduleEnvKeys :: ModuleEnv a -> [Module]
    moduleEnvKeys :: forall a. ModuleEnv a -> [Module]
    moduleEnvKeys (ModuleEnv Map NDModule a
    e) = [Module] -> [Module]
    forall a. Ord a => [a] -> [a]
    sort ([Module] -> [Module]) -> [Module] -> [Module]
    forall a b. (a -> b) -> a -> b
    $ (NDModule -> Module) -> [NDModule] -> [Module]
    forall a b. (a -> b) -> [a] -> [b]
    map NDModule -> Module
    unNDModule ([NDModule] -> [Module]) -> [NDModule] -> [Module]
    forall a b. (a -> b) -> a -> b
    $ Map NDModule a -> [NDModule]
    forall k a. Map k a -> [k]
    Map.keys Map NDModule a
    e
      -- See Note [ModuleEnv performance and determinism]

    moduleEnvElts :: ModuleEnv a -> [a]
    moduleEnvElts :: forall a. ModuleEnv a -> [a]
    moduleEnvElts ModuleEnv a
    e = ((Module, a) -> a) -> [(Module, a)] -> [a]
    forall a b. (a -> b) -> [a] -> [b]
    map (Module, a) -> a
    forall a b. (a, b) -> b
    snd ([(Module, a)] -> [a]) -> [(Module, a)] -> [a]
    forall a b. (a -> b) -> a -> b
    $ ModuleEnv a -> [(Module, a)]
    forall a. ModuleEnv a -> [(Module, a)]
    moduleEnvToList ModuleEnv a
    e
      -- See Note [ModuleEnv performance and determinism]

    moduleEnvToList :: ModuleEnv a -> [(Module, a)]
    moduleEnvToList :: forall a. ModuleEnv a -> [(Module, a)]
    moduleEnvToList (ModuleEnv Map NDModule a
    e) =
      ((Module, a) -> (Module, a) -> Ordering)
    -> [(Module, a)] -> [(Module, a)]
    forall a. (a -> a -> Ordering) -> [a] -> [a]
    sortBy (((Module, a) -> Module) -> (Module, a) -> (Module, a) -> Ordering
    forall a b. Ord a => (b -> a) -> b -> b -> Ordering
    comparing (Module, a) -> Module
    forall a b. (a, b) -> a
    fst) [(Module
    m, a
    v) | (NDModule Module
    m, a
    v) <- Map NDModule a -> [(NDModule, a)]
    forall k a. Map k a -> [(k, a)]
    Map.toList Map NDModule a
    e]
      -- See Note [ModuleEnv performance and determinism]

    unitModuleEnv :: Module -> a -> ModuleEnv a
    unitModuleEnv :: forall a. Module -> a -> ModuleEnv a
    unitModuleEnv Module
    m a
    x = Map NDModule a -> ModuleEnv a
    forall elt. Map NDModule elt -> ModuleEnv elt
    ModuleEnv (NDModule -> a -> Map NDModule a
    forall k a. k -> a -> Map k a
    Map.singleton (Module -> NDModule
    NDModule Module
    m) a
    x)

    isEmptyModuleEnv :: ModuleEnv a -> Bool
    isEmptyModuleEnv :: forall a. ModuleEnv a -> Bool
    isEmptyModuleEnv (ModuleEnv Map NDModule a
    e) = Map NDModule a -> Bool
    forall k a. Map k a -> Bool
    Map.null Map NDModule a
    e

    -- | A set of 'Module's
    type ModuleSet = Set NDModule

    mkModuleSet :: [Module] -> ModuleSet
    mkModuleSet :: [Module] -> Set NDModule
    mkModuleSet = [NDModule] -> Set NDModule
    forall a. Ord a => [a] -> Set a
    Set.fromList ([NDModule] -> Set NDModule)
    -> ([Module] -> [NDModule]) -> [Module] -> Set NDModule
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Module] -> [NDModule]
    forall a b. Coercible a b => a -> b
    coerce

    extendModuleSet :: ModuleSet -> Module -> ModuleSet
    extendModuleSet :: Set NDModule -> Module -> Set NDModule
    extendModuleSet Set NDModule
    s Module
    m = NDModule -> Set NDModule -> Set NDModule
    forall a. Ord a => a -> Set a -> Set a
    Set.insert (Module -> NDModule
    NDModule Module
    m) Set NDModule
    s

    extendModuleSetList :: ModuleSet -> [Module] -> ModuleSet
    extendModuleSetList :: Set NDModule -> [Module] -> Set NDModule
    extendModuleSetList Set NDModule
    s [Module]
    ms = (Set NDModule -> Module -> Set NDModule)
    -> Set NDModule -> [Module] -> Set NDModule
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' ((NDModule -> Set NDModule) -> Module -> Set NDModule
    forall a b. Coercible a b => a -> b
    coerce ((NDModule -> Set NDModule) -> Module -> Set NDModule)
    -> (Set NDModule -> NDModule -> Set NDModule)
    -> Set NDModule
    -> Module
    -> Set NDModule
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (NDModule -> Set NDModule -> Set NDModule)
    -> Set NDModule -> NDModule -> Set NDModule
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip NDModule -> Set NDModule -> Set NDModule
    forall a. Ord a => a -> Set a -> Set a
    Set.insert) Set NDModule
    s [Module]
    ms

    emptyModuleSet :: ModuleSet
    emptyModuleSet :: Set NDModule
    emptyModuleSet = Set NDModule
    forall a. Set a
    Set.empty

    isEmptyModuleSet :: ModuleSet -> Bool
    isEmptyModuleSet :: Set NDModule -> Bool
    isEmptyModuleSet = Set NDModule -> Bool
    forall a. Set a -> Bool
    Set.null

    moduleSetElts :: ModuleSet -> [Module]
    moduleSetElts :: Set NDModule -> [Module]
    moduleSetElts = [Module] -> [Module]
    forall a. Ord a => [a] -> [a]
    sort ([Module] -> [Module])
    -> (Set NDModule -> [Module]) -> Set NDModule -> [Module]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [NDModule] -> [Module]
    forall a b. Coercible a b => a -> b
    coerce ([NDModule] -> [Module])
    -> (Set NDModule -> [NDModule]) -> Set NDModule -> [Module]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Set NDModule -> [NDModule]
    forall a. Set a -> [a]
    Set.toList

    elemModuleSet :: Module -> ModuleSet -> Bool
    elemModuleSet :: Module -> Set NDModule -> Bool
    elemModuleSet = NDModule -> Set NDModule -> Bool
    forall a. Ord a => a -> Set a -> Bool
    Set.member (NDModule -> Set NDModule -> Bool)
    -> (Module -> NDModule) -> Module -> Set NDModule -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Module -> NDModule
    forall a b. Coercible a b => a -> b
    coerce

    intersectModuleSet :: ModuleSet -> ModuleSet -> ModuleSet
    intersectModuleSet :: Set NDModule -> Set NDModule -> Set NDModule
    intersectModuleSet = (Set NDModule -> Set NDModule -> Set NDModule)
    -> Set NDModule -> Set NDModule -> Set NDModule
    forall a b. Coercible a b => a -> b
    coerce Set NDModule -> Set NDModule -> Set NDModule
    forall a. Ord a => Set a -> Set a -> Set a
    Set.intersection

    minusModuleSet :: ModuleSet -> ModuleSet -> ModuleSet
    minusModuleSet :: Set NDModule -> Set NDModule -> Set NDModule
    minusModuleSet = (Set NDModule -> Set NDModule -> Set NDModule)
    -> Set NDModule -> Set NDModule -> Set NDModule
    forall a b. Coercible a b => a -> b
    coerce Set NDModule -> Set NDModule -> Set NDModule
    forall a. Ord a => Set a -> Set a -> Set a
    Set.difference

    delModuleSet :: ModuleSet -> Module -> ModuleSet
    delModuleSet :: Set NDModule -> Module -> Set NDModule
    delModuleSet = (Set NDModule -> NDModule -> Set NDModule)
    -> Set NDModule -> Module -> Set NDModule
    forall a b. Coercible a b => a -> b
    coerce ((NDModule -> Set NDModule -> Set NDModule)
    -> Set NDModule -> NDModule -> Set NDModule
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip NDModule -> Set NDModule -> Set NDModule
    forall a. Ord a => a -> Set a -> Set a
    Set.delete)

    unionModuleSet :: ModuleSet -> ModuleSet -> ModuleSet
    unionModuleSet :: Set NDModule -> Set NDModule -> Set NDModule
    unionModuleSet = (Set NDModule -> Set NDModule -> Set NDModule)
    -> Set NDModule -> Set NDModule -> Set NDModule
    forall a b. Coercible a b => a -> b
    coerce Set NDModule -> Set NDModule -> Set NDModule
    forall a. Ord a => Set a -> Set a -> Set a
    Set.union

    unionManyModuleSets :: [ModuleSet] -> ModuleSet
    unionManyModuleSets :: [Set NDModule] -> Set NDModule
    unionManyModuleSets = ([Set NDModule] -> Set NDModule) -> [Set NDModule] -> Set NDModule
    forall a b. Coercible a b => a -> b
    coerce ([Set NDModule] -> Set NDModule
    forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
    Set.unions :: [Set NDModule] -> Set NDModule)

    unitModuleSet :: Module -> ModuleSet
    unitModuleSet :: Module -> Set NDModule
    unitModuleSet = (NDModule -> Set NDModule) -> Module -> Set NDModule
    forall a b. Coercible a b => a -> b
    coerce NDModule -> Set NDModule
    forall a. a -> Set a
    Set.singleton

    {-
    A ModuleName has a Unique, so we can build mappings of these using
    UniqFM.
    -}

    -- | A map keyed off of 'ModuleName's (actually, their 'Unique's)
    type ModuleNameEnv elt = UniqFM ModuleName elt

    -- | A map keyed off of 'ModuleName's (actually, their 'Unique's)
    -- Has deterministic folds and can be deterministically converted to a list
    type DModuleNameEnv elt = UniqDFM ModuleName elt

    --------------------------------------------------------------------
    -- InstalledModuleEnv
    --------------------------------------------------------------------

    -- | A map keyed off of 'InstalledModule'
    newtype InstalledModuleEnv elt = InstalledModuleEnv (Map InstalledModule elt)

    instance Outputable elt => Outputable (InstalledModuleEnv elt) where
      ppr :: InstalledModuleEnv elt -> SDoc
    ppr (InstalledModuleEnv Map InstalledModule elt
    env) = Map InstalledModule elt -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Map InstalledModule elt
    env

    emptyInstalledModuleEnv :: InstalledModuleEnv a
    emptyInstalledModuleEnv :: forall a. InstalledModuleEnv a
    emptyInstalledModuleEnv = Map InstalledModule a -> InstalledModuleEnv a
    forall elt. Map InstalledModule elt -> InstalledModuleEnv elt
    InstalledModuleEnv Map InstalledModule a
    forall k a. Map k a
    Map.empty

    lookupInstalledModuleEnv :: InstalledModuleEnv a -> InstalledModule -> Maybe a
    lookupInstalledModuleEnv :: forall a. InstalledModuleEnv a -> InstalledModule -> Maybe a
    lookupInstalledModuleEnv (InstalledModuleEnv Map InstalledModule a
    e) InstalledModule
    m = InstalledModule -> Map InstalledModule a -> Maybe a
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup InstalledModule
    m Map InstalledModule a
    e

    extendInstalledModuleEnv :: InstalledModuleEnv a -> InstalledModule -> a -> InstalledModuleEnv a
    extendInstalledModuleEnv :: forall a.
    InstalledModuleEnv a
    -> InstalledModule -> a -> InstalledModuleEnv a
    extendInstalledModuleEnv (InstalledModuleEnv Map InstalledModule a
    e) InstalledModule
    m a
    x = Map InstalledModule a -> InstalledModuleEnv a
    forall elt. Map InstalledModule elt -> InstalledModuleEnv elt
    InstalledModuleEnv (InstalledModule
    -> a -> Map InstalledModule a -> Map InstalledModule a
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert InstalledModule
    m a
    x Map InstalledModule a
    e)

    filterInstalledModuleEnv :: (InstalledModule -> a -> Bool) -> InstalledModuleEnv a -> InstalledModuleEnv a
    filterInstalledModuleEnv :: forall a.
    (InstalledModule -> a -> Bool)
    -> InstalledModuleEnv a -> InstalledModuleEnv a
    filterInstalledModuleEnv InstalledModule -> a -> Bool
    f (InstalledModuleEnv Map InstalledModule a
    e) =
      Map InstalledModule a -> InstalledModuleEnv a
    forall elt. Map InstalledModule elt -> InstalledModuleEnv elt
    InstalledModuleEnv ((InstalledModule -> a -> Bool)
    -> Map InstalledModule a -> Map InstalledModule a
    forall k a. (k -> a -> Bool) -> Map k a -> Map k a
    Map.filterWithKey InstalledModule -> a -> Bool
    f Map InstalledModule a
    e)

    delInstalledModuleEnv :: InstalledModuleEnv a -> InstalledModule -> InstalledModuleEnv a
    delInstalledModuleEnv :: forall a.
    InstalledModuleEnv a -> InstalledModule -> InstalledModuleEnv a
    delInstalledModuleEnv (InstalledModuleEnv Map InstalledModule a
    e) InstalledModule
    m = Map InstalledModule a -> InstalledModuleEnv a
    forall elt. Map InstalledModule elt -> InstalledModuleEnv elt
    InstalledModuleEnv (InstalledModule -> Map InstalledModule a -> Map InstalledModule a
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete InstalledModule
    m Map InstalledModule a
    e)

    installedModuleEnvElts :: InstalledModuleEnv a -> [(InstalledModule, a)]
    installedModuleEnvElts :: forall a. InstalledModuleEnv a -> [(InstalledModule, a)]
    installedModuleEnvElts (InstalledModuleEnv Map InstalledModule a
    e) = Map InstalledModule a -> [(InstalledModule, a)]
    forall k a. Map k a -> [(k, a)]
    Map.assocs Map InstalledModule a
    e

    mergeInstalledModuleEnv
      :: (elta -> eltb -> Maybe eltc)
      -> (InstalledModuleEnv elta -> InstalledModuleEnv eltc)  -- map X
      -> (InstalledModuleEnv eltb -> InstalledModuleEnv eltc) -- map Y
      -> InstalledModuleEnv elta
      -> InstalledModuleEnv eltb
      -> InstalledModuleEnv eltc
    mergeInstalledModuleEnv :: forall elta eltb eltc.
    (elta -> eltb -> Maybe eltc)
    -> (InstalledModuleEnv elta -> InstalledModuleEnv eltc)
    -> (InstalledModuleEnv eltb -> InstalledModuleEnv eltc)
    -> InstalledModuleEnv elta
    -> InstalledModuleEnv eltb
    -> InstalledModuleEnv eltc
    mergeInstalledModuleEnv elta -> eltb -> Maybe eltc
    f InstalledModuleEnv elta -> InstalledModuleEnv eltc
    g InstalledModuleEnv eltb -> InstalledModuleEnv eltc
    h (InstalledModuleEnv Map InstalledModule elta
    xm) (InstalledModuleEnv Map InstalledModule eltb
    ym)
      = Map InstalledModule eltc -> InstalledModuleEnv eltc
    forall elt. Map InstalledModule elt -> InstalledModuleEnv elt
    InstalledModuleEnv (Map InstalledModule eltc -> InstalledModuleEnv eltc)
    -> Map InstalledModule eltc -> InstalledModuleEnv eltc
    forall a b. (a -> b) -> a -> b
    $ (InstalledModule -> elta -> eltb -> Maybe eltc)
    -> (Map InstalledModule elta -> Map InstalledModule eltc)
    -> (Map InstalledModule eltb -> Map InstalledModule eltc)
    -> Map InstalledModule elta
    -> Map InstalledModule eltb
    -> Map InstalledModule eltc
    forall k a b c.
    Ord k =>
    (k -> a -> b -> Maybe c)
    -> (Map k a -> Map k c)
    -> (Map k b -> Map k c)
    -> Map k a
    -> Map k b
    -> Map k c
    Map.mergeWithKey
          (\InstalledModule
    _ elta
    x eltb
    y -> (elta
    x elta -> eltb -> Maybe eltc
    `f` eltb
    y))
          ((InstalledModuleEnv elta -> InstalledModuleEnv eltc)
    -> Map InstalledModule elta -> Map InstalledModule eltc
    forall a b. Coercible a b => a -> b
    coerce InstalledModuleEnv elta -> InstalledModuleEnv eltc
    g)
          ((InstalledModuleEnv eltb -> InstalledModuleEnv eltc)
    -> Map InstalledModule eltb -> Map InstalledModule eltc
    forall a b. Coercible a b => a -> b
    coerce InstalledModuleEnv eltb -> InstalledModuleEnv eltc
    h)
          Map InstalledModule elta
    xm Map InstalledModule eltb
    ym

    plusInstalledModuleEnv :: (elt -> elt -> elt)
      -> InstalledModuleEnv elt
      -> InstalledModuleEnv elt
      -> InstalledModuleEnv elt
    plusInstalledModuleEnv :: forall elt.
    (elt -> elt -> elt)
    -> InstalledModuleEnv elt
    -> InstalledModuleEnv elt
    -> InstalledModuleEnv elt
    plusInstalledModuleEnv elt -> elt -> elt
    f (InstalledModuleEnv Map InstalledModule elt
    xm) (InstalledModuleEnv Map InstalledModule elt
    ym) =
      Map InstalledModule elt -> InstalledModuleEnv elt
    forall elt. Map InstalledModule elt -> InstalledModuleEnv elt
    InstalledModuleEnv (Map InstalledModule elt -> InstalledModuleEnv elt)
    -> Map InstalledModule elt -> InstalledModuleEnv elt
    forall a b. (a -> b) -> a -> b
    $ (elt -> elt -> elt)
    -> Map InstalledModule elt
    -> Map InstalledModule elt
    -> Map InstalledModule elt
    forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
    Map.unionWith elt -> elt -> elt
    f Map InstalledModule elt
    xm Map InstalledModule elt
    ym

    --------------------------------------------------------------------
    -- InstalledModuleWithIsBootEnv
    --------------------------------------------------------------------

    -- | A map keyed off of 'InstalledModuleWithIsBoot'
    newtype InstalledModuleWithIsBootEnv elt = InstalledModuleWithIsBootEnv (Map InstalledModuleWithIsBoot elt)

    instance Outputable elt => Outputable (InstalledModuleWithIsBootEnv elt) where
      ppr :: InstalledModuleWithIsBootEnv elt -> SDoc
    ppr (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot elt
    env) = Map InstalledModuleWithIsBoot elt -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Map InstalledModuleWithIsBoot elt
    env

    emptyInstalledModuleWithIsBootEnv :: InstalledModuleWithIsBootEnv a
    emptyInstalledModuleWithIsBootEnv :: forall a. InstalledModuleWithIsBootEnv a
    emptyInstalledModuleWithIsBootEnv = Map InstalledModuleWithIsBoot a -> InstalledModuleWithIsBootEnv a
    forall elt.
    Map InstalledModuleWithIsBoot elt
    -> InstalledModuleWithIsBootEnv elt
    InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot a
    forall k a. Map k a
    Map.empty

    lookupInstalledModuleWithIsBootEnv :: InstalledModuleWithIsBootEnv a -> InstalledModuleWithIsBoot -> Maybe a
    lookupInstalledModuleWithIsBootEnv :: forall a.
    InstalledModuleWithIsBootEnv a
    -> InstalledModuleWithIsBoot -> Maybe a
    lookupInstalledModuleWithIsBootEnv (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot a
    e) InstalledModuleWithIsBoot
    m = InstalledModuleWithIsBoot
    -> Map InstalledModuleWithIsBoot a -> Maybe a
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup InstalledModuleWithIsBoot
    m Map InstalledModuleWithIsBoot a
    e

    extendInstalledModuleWithIsBootEnv :: InstalledModuleWithIsBootEnv a -> InstalledModuleWithIsBoot -> a -> InstalledModuleWithIsBootEnv a
    extendInstalledModuleWithIsBootEnv :: forall a.
    InstalledModuleWithIsBootEnv a
    -> InstalledModuleWithIsBoot -> a -> InstalledModuleWithIsBootEnv a
    extendInstalledModuleWithIsBootEnv (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot a
    e) InstalledModuleWithIsBoot
    m a
    x = Map InstalledModuleWithIsBoot a -> InstalledModuleWithIsBootEnv a
    forall elt.
    Map InstalledModuleWithIsBoot elt
    -> InstalledModuleWithIsBootEnv elt
    InstalledModuleWithIsBootEnv (InstalledModuleWithIsBoot
    -> a
    -> Map InstalledModuleWithIsBoot a
    -> Map InstalledModuleWithIsBoot a
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    Map.insert InstalledModuleWithIsBoot
    m a
    x Map InstalledModuleWithIsBoot a
    e)

    filterInstalledModuleWithIsBootEnv :: (InstalledModuleWithIsBoot -> a -> Bool) -> InstalledModuleWithIsBootEnv a -> InstalledModuleWithIsBootEnv a
    filterInstalledModuleWithIsBootEnv :: forall a.
    (InstalledModuleWithIsBoot -> a -> Bool)
    -> InstalledModuleWithIsBootEnv a -> InstalledModuleWithIsBootEnv a
    filterInstalledModuleWithIsBootEnv InstalledModuleWithIsBoot -> a -> Bool
    f (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot a
    e) =
      Map InstalledModuleWithIsBoot a -> InstalledModuleWithIsBootEnv a
    forall elt.
    Map InstalledModuleWithIsBoot elt
    -> InstalledModuleWithIsBootEnv elt
    InstalledModuleWithIsBootEnv ((InstalledModuleWithIsBoot -> a -> Bool)
    -> Map InstalledModuleWithIsBoot a
    -> Map InstalledModuleWithIsBoot a
    forall k a. (k -> a -> Bool) -> Map k a -> Map k a
    Map.filterWithKey InstalledModuleWithIsBoot -> a -> Bool
    f Map InstalledModuleWithIsBoot a
    e)

    delInstalledModuleWithIsBootEnv :: InstalledModuleWithIsBootEnv a -> InstalledModuleWithIsBoot -> InstalledModuleWithIsBootEnv a
    delInstalledModuleWithIsBootEnv :: forall a.
    InstalledModuleWithIsBootEnv a
    -> InstalledModuleWithIsBoot -> InstalledModuleWithIsBootEnv a
    delInstalledModuleWithIsBootEnv (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot a
    e) InstalledModuleWithIsBoot
    m = Map InstalledModuleWithIsBoot a -> InstalledModuleWithIsBootEnv a
    forall elt.
    Map InstalledModuleWithIsBoot elt
    -> InstalledModuleWithIsBootEnv elt
    InstalledModuleWithIsBootEnv (InstalledModuleWithIsBoot
    -> Map InstalledModuleWithIsBoot a
    -> Map InstalledModuleWithIsBoot a
    forall k a. Ord k => k -> Map k a -> Map k a
    Map.delete InstalledModuleWithIsBoot
    m Map InstalledModuleWithIsBoot a
    e)

    installedModuleWithIsBootEnvElts :: InstalledModuleWithIsBootEnv a -> [(InstalledModuleWithIsBoot, a)]
    installedModuleWithIsBootEnvElts :: forall a.
    InstalledModuleWithIsBootEnv a -> [(InstalledModuleWithIsBoot, a)]
    installedModuleWithIsBootEnvElts (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot a
    e) = Map InstalledModuleWithIsBoot a -> [(InstalledModuleWithIsBoot, a)]
    forall k a. Map k a -> [(k, a)]
    Map.assocs Map InstalledModuleWithIsBoot a
    e

    mergeInstalledModuleWithIsBootEnv
      :: (elta -> eltb -> Maybe eltc)
      -> (InstalledModuleWithIsBootEnv elta -> InstalledModuleWithIsBootEnv eltc)  -- map X
      -> (InstalledModuleWithIsBootEnv eltb -> InstalledModuleWithIsBootEnv eltc) -- map Y
      -> InstalledModuleWithIsBootEnv elta
      -> InstalledModuleWithIsBootEnv eltb
      -> InstalledModuleWithIsBootEnv eltc
    mergeInstalledModuleWithIsBootEnv :: forall elta eltb eltc.
    (elta -> eltb -> Maybe eltc)
    -> (InstalledModuleWithIsBootEnv elta
        -> InstalledModuleWithIsBootEnv eltc)
    -> (InstalledModuleWithIsBootEnv eltb
        -> InstalledModuleWithIsBootEnv eltc)
    -> InstalledModuleWithIsBootEnv elta
    -> InstalledModuleWithIsBootEnv eltb
    -> InstalledModuleWithIsBootEnv eltc
    mergeInstalledModuleWithIsBootEnv elta -> eltb -> Maybe eltc
    f InstalledModuleWithIsBootEnv elta
    -> InstalledModuleWithIsBootEnv eltc
    g InstalledModuleWithIsBootEnv eltb
    -> InstalledModuleWithIsBootEnv eltc
    h (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot elta
    xm) (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot eltb
    ym)
      = Map InstalledModuleWithIsBoot eltc
    -> InstalledModuleWithIsBootEnv eltc
    forall elt.
    Map InstalledModuleWithIsBoot elt
    -> InstalledModuleWithIsBootEnv elt
    InstalledModuleWithIsBootEnv (Map InstalledModuleWithIsBoot eltc
     -> InstalledModuleWithIsBootEnv eltc)
    -> Map InstalledModuleWithIsBoot eltc
    -> InstalledModuleWithIsBootEnv eltc
    forall a b. (a -> b) -> a -> b
    $ (InstalledModuleWithIsBoot -> elta -> eltb -> Maybe eltc)
    -> (Map InstalledModuleWithIsBoot elta
        -> Map InstalledModuleWithIsBoot eltc)
    -> (Map InstalledModuleWithIsBoot eltb
        -> Map InstalledModuleWithIsBoot eltc)
    -> Map InstalledModuleWithIsBoot elta
    -> Map InstalledModuleWithIsBoot eltb
    -> Map InstalledModuleWithIsBoot eltc
    forall k a b c.
    Ord k =>
    (k -> a -> b -> Maybe c)
    -> (Map k a -> Map k c)
    -> (Map k b -> Map k c)
    -> Map k a
    -> Map k b
    -> Map k c
    Map.mergeWithKey
          (\InstalledModuleWithIsBoot
    _ elta
    x eltb
    y -> (elta
    x elta -> eltb -> Maybe eltc
    `f` eltb
    y))
          ((InstalledModuleWithIsBootEnv elta
     -> InstalledModuleWithIsBootEnv eltc)
    -> Map InstalledModuleWithIsBoot elta
    -> Map InstalledModuleWithIsBoot eltc
    forall a b. Coercible a b => a -> b
    coerce InstalledModuleWithIsBootEnv elta
    -> InstalledModuleWithIsBootEnv eltc
    g)
          ((InstalledModuleWithIsBootEnv eltb
     -> InstalledModuleWithIsBootEnv eltc)
    -> Map InstalledModuleWithIsBoot eltb
    -> Map InstalledModuleWithIsBoot eltc
    forall a b. Coercible a b => a -> b
    coerce InstalledModuleWithIsBootEnv eltb
    -> InstalledModuleWithIsBootEnv eltc
    h)
          Map InstalledModuleWithIsBoot elta
    xm Map InstalledModuleWithIsBoot eltb
    ym

    plusInstalledModuleWithIsBootEnv :: (elt -> elt -> elt)
      -> InstalledModuleWithIsBootEnv elt
      -> InstalledModuleWithIsBootEnv elt
      -> InstalledModuleWithIsBootEnv elt
    plusInstalledModuleWithIsBootEnv :: forall elt.
    (elt -> elt -> elt)
    -> InstalledModuleWithIsBootEnv elt
    -> InstalledModuleWithIsBootEnv elt
    -> InstalledModuleWithIsBootEnv elt
    plusInstalledModuleWithIsBootEnv elt -> elt -> elt
    f (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot elt
    xm) (InstalledModuleWithIsBootEnv Map InstalledModuleWithIsBoot elt
    ym) =
      Map InstalledModuleWithIsBoot elt
    -> InstalledModuleWithIsBootEnv elt
    forall elt.
    Map InstalledModuleWithIsBoot elt
    -> InstalledModuleWithIsBootEnv elt
    InstalledModuleWithIsBootEnv (Map InstalledModuleWithIsBoot elt
     -> InstalledModuleWithIsBootEnv elt)
    -> Map InstalledModuleWithIsBoot elt
    -> InstalledModuleWithIsBootEnv elt
    forall a b. (a -> b) -> a -> b
    $ (elt -> elt -> elt)
    -> Map InstalledModuleWithIsBoot elt
    -> Map InstalledModuleWithIsBoot elt
    -> Map InstalledModuleWithIsBoot elt
    forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
    Map.unionWith elt -> elt -> elt
    f Map InstalledModuleWithIsBoot elt
    xm Map InstalledModuleWithIsBoot elt
    ym