    module Distribution.Solver.Modular.IndexConversion
        ( convPIs
        ) where

    import Distribution.Solver.Compat.Prelude
    import Prelude ()

    import qualified Data.List as L
    import qualified Data.Map.Strict as M
    import qualified Distribution.Compat.NonEmptySet as NonEmptySet
    import qualified Data.Set as S

    import qualified Distribution.InstalledPackageInfo as IPI
    import Distribution.Compiler
    import Distribution.Package                          -- from Cabal
    import Distribution.Simple.BuildToolDepends          -- from Cabal
    import Distribution.Types.ExeDependency              -- from Cabal
    import Distribution.Types.PkgconfigDependency        -- from Cabal
    import Distribution.Types.ComponentName              -- from Cabal
    import Distribution.Types.CondTree                   -- from Cabal
    import Distribution.Types.MungedPackageId            -- from Cabal
    import Distribution.Types.MungedPackageName          -- from Cabal
    import Distribution.PackageDescription               -- from Cabal
    import Distribution.PackageDescription.Configuration
    import qualified Distribution.Simple.PackageIndex as SI
    import Distribution.System

    import           Distribution.Solver.Types.ComponentDeps
                       ( Component(..), componentNameToComponent )
    import           Distribution.Solver.Types.Flag
    import           Distribution.Solver.Types.LabeledPackageConstraint
    import           Distribution.Solver.Types.OptionalStanza
    import           Distribution.Solver.Types.PackageConstraint
    import qualified Distribution.Solver.Types.PackageIndex as CI
    import           Distribution.Solver.Types.Settings
    import           Distribution.Solver.Types.SourcePackage

    import Distribution.Solver.Modular.Dependency as D
    import Distribution.Solver.Modular.Flag as F
    import Distribution.Solver.Modular.Index
    import Distribution.Solver.Modular.Package
    import Distribution.Solver.Modular.Tree
    import Distribution.Solver.Modular.Version

    -- | Convert both the installed package index and the source package
    -- index into one uniform solver index.
    --
    -- We use 'allPackagesBySourcePackageId' for the installed package index
    -- because that returns us several instances of the same package and version
    -- in order of preference. This allows us in principle to \"shadow\"
    -- packages if there are several installed packages of the same version.
    -- There are currently some shortcomings in both GHC and Cabal in
    -- resolving these situations. However, the right thing to do is to
    -- fix the problem there, so for now, shadowing is only activated if
    -- explicitly requested.
    convPIs :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint]
            -> ShadowPkgs -> StrongFlags -> SolveExecutables
            -> SI.InstalledPackageIndex -> CI.PackageIndex (SourcePackage loc)
            -> Index
    convPIs :: forall loc.
    OS
    -> Arch
    -> CompilerInfo
    -> Map PN [LabeledPackageConstraint]
    -> ShadowPkgs
    -> StrongFlags
    -> SolveExecutables
    -> InstalledPackageIndex
    -> PackageIndex (SourcePackage loc)
    -> Index
    convPIs OS
    os Arch
    arch CompilerInfo
    comp Map PN [LabeledPackageConstraint]
    constraints ShadowPkgs
    sip StrongFlags
    strfl SolveExecutables
    solveExes InstalledPackageIndex
    iidx PackageIndex (SourcePackage loc)
    sidx =
      [(PN, I, PInfo)] -> Index
    mkIndex ([(PN, I, PInfo)] -> Index) -> [(PN, I, PInfo)] -> Index
    forall a b. (a -> b) -> a -> b
    $
      ShadowPkgs -> InstalledPackageIndex -> [(PN, I, PInfo)]
    convIPI' ShadowPkgs
    sip InstalledPackageIndex
    iidx [(PN, I, PInfo)] -> [(PN, I, PInfo)] -> [(PN, I, PInfo)]
    forall a. [a] -> [a] -> [a]
    ++ OS
    -> Arch
    -> CompilerInfo
    -> Map PN [LabeledPackageConstraint]
    -> StrongFlags
    -> SolveExecutables
    -> PackageIndex (SourcePackage loc)
    -> [(PN, I, PInfo)]
    forall loc.
    OS
    -> Arch
    -> CompilerInfo
    -> Map PN [LabeledPackageConstraint]
    -> StrongFlags
    -> SolveExecutables
    -> PackageIndex (SourcePackage loc)
    -> [(PN, I, PInfo)]
    convSPI' OS
    os Arch
    arch CompilerInfo
    comp Map PN [LabeledPackageConstraint]
    constraints StrongFlags
    strfl SolveExecutables
    solveExes PackageIndex (SourcePackage loc)
    sidx

    -- | Convert a Cabal installed package index to the simpler,
    -- more uniform index format of the solver.
    convIPI' :: ShadowPkgs -> SI.InstalledPackageIndex -> [(PN, I, PInfo)]
    convIPI' :: ShadowPkgs -> InstalledPackageIndex -> [(PN, I, PInfo)]
    convIPI' (ShadowPkgs Bool
    sip) InstalledPackageIndex
    idx =
        -- apply shadowing whenever there are multiple installed packages with
        -- the same version
        [ (PN, I, PInfo) -> (PN, I, PInfo)
    maybeShadow (InstalledPackageIndex -> InstalledPackageInfo -> (PN, I, PInfo)
    convIP InstalledPackageIndex
    idx InstalledPackageInfo
    pkg)
        -- IMPORTANT to get internal libraries. See
        -- Note [Index conversion with internal libraries]
        | ((PackageId, LibraryName)
    _, [InstalledPackageInfo]
    pkgs) <- InstalledPackageIndex
    -> [((PackageId, LibraryName), [InstalledPackageInfo])]
    forall a.
    HasUnitId a =>
    PackageIndex a -> [((PackageId, LibraryName), [a])]
    SI.allPackagesBySourcePackageIdAndLibName InstalledPackageIndex
    idx
        , ((PN, I, PInfo) -> (PN, I, PInfo)
    maybeShadow, InstalledPackageInfo
    pkg) <- [(PN, I, PInfo) -> (PN, I, PInfo)]
    -> [InstalledPackageInfo]
    -> [((PN, I, PInfo) -> (PN, I, PInfo), InstalledPackageInfo)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip ((PN, I, PInfo) -> (PN, I, PInfo)
    forall a. a -> a
    id ((PN, I, PInfo) -> (PN, I, PInfo))
    -> [(PN, I, PInfo) -> (PN, I, PInfo)]
    -> [(PN, I, PInfo) -> (PN, I, PInfo)]
    forall a. a -> [a] -> [a]
    : ((PN, I, PInfo) -> (PN, I, PInfo))
    -> [(PN, I, PInfo) -> (PN, I, PInfo)]
    forall a. a -> [a]
    repeat (PN, I, PInfo) -> (PN, I, PInfo)
    forall {a} {b}. (a, b, PInfo) -> (a, b, PInfo)
    shadow) [InstalledPackageInfo]
    pkgs ]
      where

        -- shadowing is recorded in the package info
        shadow :: (a, b, PInfo) -> (a, b, PInfo)
    shadow (a
    pn, b
    i, PInfo FlaggedDeps PN
    fdeps Map ExposedComponent ComponentInfo
    comps FlagInfo
    fds Maybe FailReason
    _)
          | Bool
    sip = (a
    pn, b
    i, FlaggedDeps PN
    -> Map ExposedComponent ComponentInfo
    -> FlagInfo
    -> Maybe FailReason
    -> PInfo
    PInfo FlaggedDeps PN
    fdeps Map ExposedComponent ComponentInfo
    comps FlagInfo
    fds (FailReason -> Maybe FailReason
    forall a. a -> Maybe a
    Just FailReason
    Shadowed))
        shadow (a, b, PInfo)
    x                                     = (a, b, PInfo)
    x

    -- | Extract/recover the package ID from an installed package info, and convert it to a solver's I.
    convId :: IPI.InstalledPackageInfo -> (PN, I)
    convId :: InstalledPackageInfo -> (PN, I)
    convId InstalledPackageInfo
    ipi = (PN
    pn, Ver -> Loc -> I
    I Ver
    ver (Loc -> I) -> Loc -> I
    forall a b. (a -> b) -> a -> b
    $ UnitId -> Loc
    Inst (UnitId -> Loc) -> UnitId -> Loc
    forall a b. (a -> b) -> a -> b
    $ InstalledPackageInfo -> UnitId
    IPI.installedUnitId InstalledPackageInfo
    ipi)
      where MungedPackageId MungedPackageName
    mpn Ver
    ver = InstalledPackageInfo -> MungedPackageId
    forall pkg. HasMungedPackageId pkg => pkg -> MungedPackageId
    mungedId InstalledPackageInfo
    ipi
            -- HACK. See Note [Index conversion with internal libraries]
            pn :: PN
    pn = MungedPackageName -> PN
    encodeCompatPackageName MungedPackageName
    mpn

    -- | Convert a single installed package into the solver-specific format.
    convIP :: SI.InstalledPackageIndex -> IPI.InstalledPackageInfo -> (PN, I, PInfo)
    convIP :: InstalledPackageIndex -> InstalledPackageInfo -> (PN, I, PInfo)
    convIP InstalledPackageIndex
    idx InstalledPackageInfo
    ipi =
      case (UnitId -> Either UnitId (FlaggedDep PN))
    -> [UnitId] -> Either UnitId (FlaggedDeps PN)
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> [a] -> f [b]
    traverse (DependencyReason PN
    -> Component
    -> InstalledPackageIndex
    -> UnitId
    -> Either UnitId (FlaggedDep PN)
    convIPId (PN -> Map Flag FlagValue -> Set Stanza -> DependencyReason PN
    forall qpn.
    qpn -> Map Flag FlagValue -> Set Stanza -> DependencyReason qpn
    DependencyReason PN
    pn Map Flag FlagValue
    forall k a. Map k a
    M.empty Set Stanza
    forall a. Set a
    S.empty) Component
    comp InstalledPackageIndex
    idx) (InstalledPackageInfo -> [UnitId]
    IPI.depends InstalledPackageInfo
    ipi) of
            Left UnitId
    u    -> (PN
    pn, I
    i, FlaggedDeps PN
    -> Map ExposedComponent ComponentInfo
    -> FlagInfo
    -> Maybe FailReason
    -> PInfo
    PInfo [] Map ExposedComponent ComponentInfo
    forall k a. Map k a
    M.empty FlagInfo
    forall k a. Map k a
    M.empty (FailReason -> Maybe FailReason
    forall a. a -> Maybe a
    Just (UnitId -> FailReason
    Broken UnitId
    u)))
            Right FlaggedDeps PN
    fds -> (PN
    pn, I
    i, FlaggedDeps PN
    -> Map ExposedComponent ComponentInfo
    -> FlagInfo
    -> Maybe FailReason
    -> PInfo
    PInfo FlaggedDeps PN
    fds Map ExposedComponent ComponentInfo
    components FlagInfo
    forall k a. Map k a
    M.empty Maybe FailReason
    forall a. Maybe a
    Nothing)
     where
      -- TODO: Handle sub-libraries and visibility.
      components :: Map ExposedComponent ComponentInfo
    components =
          ExposedComponent
    -> ComponentInfo -> Map ExposedComponent ComponentInfo
    forall k a. k -> a -> Map k a
    M.singleton (LibraryName -> ExposedComponent
    ExposedLib LibraryName
    LMainLibName)
                      ComponentInfo {
                          compIsVisible :: IsVisible
    compIsVisible = Bool -> IsVisible
    IsVisible Bool
    True
                        , compIsBuildable :: IsBuildable
    compIsBuildable = Bool -> IsBuildable
    IsBuildable Bool
    True
                        }

      (PN
    pn, I
    i) = InstalledPackageInfo -> (PN, I)
    convId InstalledPackageInfo
    ipi

      -- 'sourceLibName' is unreliable, but for now we only really use this for
      -- primary libs anyways
      comp :: Component
    comp = ComponentName -> Component
    componentNameToComponent (ComponentName -> Component) -> ComponentName -> Component
    forall a b. (a -> b) -> a -> b
    $ LibraryName -> ComponentName
    CLibName (LibraryName -> ComponentName) -> LibraryName -> ComponentName
    forall a b. (a -> b) -> a -> b
    $ InstalledPackageInfo -> LibraryName
    IPI.sourceLibName InstalledPackageInfo
    ipi
    -- TODO: Installed packages should also store their encapsulations!

    -- Note [Index conversion with internal libraries]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- Something very interesting happens when we have internal libraries
    -- in our index.  In this case, we maybe have p-0.1, which itself
    -- depends on the internal library p-internal ALSO from p-0.1.
    -- Here's the danger:
    --
    --      - If we treat both of these packages as having PN "p",
    --        then the solver will try to pick one or the other,
    --        but never both.
    --
    --      - If we drop the internal packages, now p-0.1 has a
    --        dangling dependency on an "installed" package we know
    --        nothing about. Oops.
    --
    -- An expedient hack is to put p-internal into cabal-install's
    -- index as a MUNGED package name, so that it doesn't conflict
    -- with anyone else (except other instances of itself).  But
    -- yet, we ought NOT to say that PNs in the solver are munged
    -- package names, because they're not; for source packages,
    -- we really will never see munged package names.
    --
    -- The tension here is that the installed package index is actually
    -- per library, but the solver is per package.  We need to smooth
    -- it over, and munging the package names is a pretty good way to
    -- do it.

    -- | Convert dependencies specified by an installed package id into
    -- flagged dependencies of the solver.
    --
    -- May return Nothing if the package can't be found in the index. That
    -- indicates that the original package having this dependency is broken
    -- and should be ignored.
    convIPId :: DependencyReason PN -> Component -> SI.InstalledPackageIndex -> UnitId -> Either UnitId (FlaggedDep PN)
    convIPId :: DependencyReason PN
    -> Component
    -> InstalledPackageIndex
    -> UnitId
    -> Either UnitId (FlaggedDep PN)
    convIPId DependencyReason PN
    dr Component
    comp InstalledPackageIndex
    idx UnitId
    ipid =
      case InstalledPackageIndex -> UnitId -> Maybe InstalledPackageInfo
    forall a. PackageIndex a -> UnitId -> Maybe a
    SI.lookupUnitId InstalledPackageIndex
    idx UnitId
    ipid of
        Maybe InstalledPackageInfo
    Nothing  -> UnitId -> Either UnitId (FlaggedDep PN)
    forall a b. a -> Either a b
    Left UnitId
    ipid
        Just InstalledPackageInfo
    ipi -> let (PN
    pn, I
    i) = InstalledPackageInfo -> (PN, I)
    convId InstalledPackageInfo
    ipi
                        name :: ExposedComponent
    name = LibraryName -> ExposedComponent
    ExposedLib LibraryName
    LMainLibName  -- TODO: Handle sub-libraries.
                    in  FlaggedDep PN -> Either UnitId (FlaggedDep PN)
    forall a b. b -> Either a b
    Right (LDep PN -> Component -> FlaggedDep PN
    forall qpn. LDep qpn -> Component -> FlaggedDep qpn
    D.Simple (DependencyReason PN -> Dep PN -> LDep PN
    forall qpn. DependencyReason qpn -> Dep qpn -> LDep qpn
    LDep DependencyReason PN
    dr (PkgComponent PN -> CI -> Dep PN
    forall qpn. PkgComponent qpn -> CI -> Dep qpn
    Dep (PN -> ExposedComponent -> PkgComponent PN
    forall qpn. qpn -> ExposedComponent -> PkgComponent qpn
    PkgComponent PN
    pn ExposedComponent
    name) (I -> CI
    Fixed I
    i))) Component
    comp)
                    -- NB: something we pick up from the
                    -- InstalledPackageIndex is NEVER an executable

    -- | Convert a cabal-install source package index to the simpler,
    -- more uniform index format of the solver.
    convSPI' :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint]
             -> StrongFlags -> SolveExecutables
             -> CI.PackageIndex (SourcePackage loc) -> [(PN, I, PInfo)]
    convSPI' :: forall loc.
    OS
    -> Arch
    -> CompilerInfo
    -> Map PN [LabeledPackageConstraint]
    -> StrongFlags
    -> SolveExecutables
    -> PackageIndex (SourcePackage loc)
    -> [(PN, I, PInfo)]
    convSPI' OS
    os Arch
    arch CompilerInfo
    cinfo Map PN [LabeledPackageConstraint]
    constraints StrongFlags
    strfl SolveExecutables
    solveExes =
        (SourcePackage loc -> (PN, I, PInfo))
    -> [SourcePackage loc] -> [(PN, I, PInfo)]
    forall a b. (a -> b) -> [a] -> [b]
    L.map (OS
    -> Arch
    -> CompilerInfo
    -> Map PN [LabeledPackageConstraint]
    -> StrongFlags
    -> SolveExecutables
    -> SourcePackage loc
    -> (PN, I, PInfo)
    forall loc.
    OS
    -> Arch
    -> CompilerInfo
    -> Map PN [LabeledPackageConstraint]
    -> StrongFlags
    -> SolveExecutables
    -> SourcePackage loc
    -> (PN, I, PInfo)
    convSP OS
    os Arch
    arch CompilerInfo
    cinfo Map PN [LabeledPackageConstraint]
    constraints StrongFlags
    strfl SolveExecutables
    solveExes) ([SourcePackage loc] -> [(PN, I, PInfo)])
    -> (PackageIndex (SourcePackage loc) -> [SourcePackage loc])
    -> PackageIndex (SourcePackage loc)
    -> [(PN, I, PInfo)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PackageIndex (SourcePackage loc) -> [SourcePackage loc]
    forall pkg. PackageIndex pkg -> [pkg]
    CI.allPackages

    -- | Convert a single source package into the solver-specific format.
    convSP :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint]
           -> StrongFlags -> SolveExecutables -> SourcePackage loc -> (PN, I, PInfo)
    convSP :: forall loc.
    OS
    -> Arch
    -> CompilerInfo
    -> Map PN [LabeledPackageConstraint]
    -> StrongFlags
    -> SolveExecutables
    -> SourcePackage loc
    -> (PN, I, PInfo)
    convSP OS
    os Arch
    arch CompilerInfo
    cinfo Map PN [LabeledPackageConstraint]
    constraints StrongFlags
    strfl SolveExecutables
    solveExes (SourcePackage (PackageIdentifier PN
    pn Ver
    pv) GenericPackageDescription
    gpd loc
    _ PackageDescriptionOverride
    _pl) =
      let i :: I
    i = Ver -> Loc -> I
    I Ver
    pv Loc
    InRepo
          pkgConstraints :: [LabeledPackageConstraint]
    pkgConstraints = [LabeledPackageConstraint]
    -> Maybe [LabeledPackageConstraint] -> [LabeledPackageConstraint]
    forall a. a -> Maybe a -> a
    fromMaybe [] (Maybe [LabeledPackageConstraint] -> [LabeledPackageConstraint])
    -> Maybe [LabeledPackageConstraint] -> [LabeledPackageConstraint]
    forall a b. (a -> b) -> a -> b
    $ PN
    -> Map PN [LabeledPackageConstraint]
    -> Maybe [LabeledPackageConstraint]
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup PN
    pn Map PN [LabeledPackageConstraint]
    constraints
      in  (PN
    pn, I
    i, OS
    -> Arch
    -> CompilerInfo
    -> [LabeledPackageConstraint]
    -> StrongFlags
    -> SolveExecutables
    -> PN
    -> GenericPackageDescription
    -> PInfo
    convGPD OS
    os Arch
    arch CompilerInfo
    cinfo [LabeledPackageConstraint]
    pkgConstraints StrongFlags
    strfl SolveExecutables
    solveExes PN
    pn GenericPackageDescription
    gpd)

    -- We do not use 'flattenPackageDescription' or 'finalizePD'
    -- from 'Distribution.PackageDescription.Configuration' here, because we
    -- want to keep the condition tree, but simplify much of the test.

    -- | Convert a generic package description to a solver-specific 'PInfo'.
    convGPD :: OS -> Arch -> CompilerInfo -> [LabeledPackageConstraint]
            -> StrongFlags -> SolveExecutables -> PN -> GenericPackageDescription
            -> PInfo
    convGPD :: OS
    -> Arch
    -> CompilerInfo
    -> [LabeledPackageConstraint]
    -> StrongFlags
    -> SolveExecutables
    -> PN
    -> GenericPackageDescription
    -> PInfo
    convGPD OS
    os Arch
    arch CompilerInfo
    cinfo [LabeledPackageConstraint]
    constraints StrongFlags
    strfl SolveExecutables
    solveExes PN
    pn
            (GenericPackageDescription PackageDescription
    pkg Maybe Ver
    scannedVersion [PackageFlag]
    flags Maybe (CondTree ConfVar [Dependency] Library)
    mlib [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
    sub_libs [(UnqualComponentName, CondTree ConfVar [Dependency] ForeignLib)]
    flibs [(UnqualComponentName, CondTree ConfVar [Dependency] Executable)]
    exes [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
    tests [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
    benchs) =
      let
        fds :: FlagInfo
    fds  = StrongFlags -> [PackageFlag] -> FlagInfo
    flagInfo StrongFlags
    strfl [PackageFlag]
    flags

        conv :: Monoid a => Component -> (a -> BuildInfo) -> DependencyReason PN ->
                CondTree ConfVar [Dependency] a -> FlaggedDeps PN
        conv :: forall a.
    Monoid a =>
    Component
    -> (a -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    conv Component
    comp a -> BuildInfo
    getInfo DependencyReason PN
    dr =
            Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    forall a.
    Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    convCondTree Map Flag Bool
    forall k a. Map k a
    M.empty DependencyReason PN
    dr PackageDescription
    pkg OS
    os Arch
    arch CompilerInfo
    cinfo PN
    pn FlagInfo
    fds Component
    comp a -> BuildInfo
    getInfo SolveExecutables
    solveExes (CondTree ConfVar [Dependency] a -> FlaggedDeps PN)
    -> (CondTree ConfVar [Dependency] a
        -> CondTree ConfVar [Dependency] a)
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
            (a -> BuildInfo)
    -> CondTree ConfVar [Dependency] a
    -> CondTree ConfVar [Dependency] a
    forall v a c.
    (Eq v, Monoid a, Monoid c) =>
    (a -> BuildInfo) -> CondTree v c a -> CondTree v c a
    addBuildableCondition a -> BuildInfo
    getInfo

        initDR :: DependencyReason PN
    initDR = PN -> Map Flag FlagValue -> Set Stanza -> DependencyReason PN
    forall qpn.
    qpn -> Map Flag FlagValue -> Set Stanza -> DependencyReason qpn
    DependencyReason PN
    pn Map Flag FlagValue
    forall k a. Map k a
    M.empty Set Stanza
    forall a. Set a
    S.empty

        flagged_deps :: FlaggedDeps PN
    flagged_deps
            = (CondTree ConfVar [Dependency] Library -> FlaggedDeps PN)
    -> [CondTree ConfVar [Dependency] Library] -> FlaggedDeps PN
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (\CondTree ConfVar [Dependency] Library
    ds ->       Component
    -> (Library -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] Library
    -> FlaggedDeps PN
    forall a.
    Monoid a =>
    Component
    -> (a -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    conv Component
    ComponentLib         Library -> BuildInfo
    libBuildInfo        DependencyReason PN
    initDR CondTree ConfVar [Dependency] Library
    ds) (Maybe (CondTree ConfVar [Dependency] Library)
    -> [CondTree ConfVar [Dependency] Library]
    forall a. Maybe a -> [a]
    maybeToList Maybe (CondTree ConfVar [Dependency] Library)
    mlib)
           FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ ((UnqualComponentName, CondTree ConfVar [Dependency] Library)
     -> FlaggedDeps PN)
    -> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
    -> FlaggedDeps PN
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (\(UnqualComponentName
    nm, CondTree ConfVar [Dependency] Library
    ds) -> Component
    -> (Library -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] Library
    -> FlaggedDeps PN
    forall a.
    Monoid a =>
    Component
    -> (a -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    conv (UnqualComponentName -> Component
    ComponentSubLib UnqualComponentName
    nm) Library -> BuildInfo
    libBuildInfo        DependencyReason PN
    initDR CondTree ConfVar [Dependency] Library
    ds) [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
    sub_libs
           FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ ((UnqualComponentName, CondTree ConfVar [Dependency] ForeignLib)
     -> FlaggedDeps PN)
    -> [(UnqualComponentName,
         CondTree ConfVar [Dependency] ForeignLib)]
    -> FlaggedDeps PN
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (\(UnqualComponentName
    nm, CondTree ConfVar [Dependency] ForeignLib
    ds) -> Component
    -> (ForeignLib -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] ForeignLib
    -> FlaggedDeps PN
    forall a.
    Monoid a =>
    Component
    -> (a -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    conv (UnqualComponentName -> Component
    ComponentFLib UnqualComponentName
    nm)   ForeignLib -> BuildInfo
    foreignLibBuildInfo DependencyReason PN
    initDR CondTree ConfVar [Dependency] ForeignLib
    ds) [(UnqualComponentName, CondTree ConfVar [Dependency] ForeignLib)]
    flibs
           FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ ((UnqualComponentName, CondTree ConfVar [Dependency] Executable)
     -> FlaggedDeps PN)
    -> [(UnqualComponentName,
         CondTree ConfVar [Dependency] Executable)]
    -> FlaggedDeps PN
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (\(UnqualComponentName
    nm, CondTree ConfVar [Dependency] Executable
    ds) -> Component
    -> (Executable -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] Executable
    -> FlaggedDeps PN
    forall a.
    Monoid a =>
    Component
    -> (a -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    conv (UnqualComponentName -> Component
    ComponentExe UnqualComponentName
    nm)    Executable -> BuildInfo
    buildInfo           DependencyReason PN
    initDR CondTree ConfVar [Dependency] Executable
    ds) [(UnqualComponentName, CondTree ConfVar [Dependency] Executable)]
    exes
           FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ (FlaggedDeps PN -> FlaggedDep PN)
    -> [FlaggedDeps PN] -> FlaggedDeps PN
    forall qpn.
    (FlaggedDeps qpn -> FlaggedDep qpn)
    -> [FlaggedDeps qpn] -> FlaggedDeps qpn
    prefix (SN PN -> FlaggedDeps PN -> FlaggedDep PN
    forall qpn. SN qpn -> TrueFlaggedDeps qpn -> FlaggedDep qpn
    Stanza (PN -> Stanza -> SN PN
    forall qpn. qpn -> Stanza -> SN qpn
    SN PN
    pn Stanza
    TestStanzas))
                (((UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
     -> FlaggedDeps PN)
    -> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
    -> [FlaggedDeps PN]
    forall a b. (a -> b) -> [a] -> [b]
    L.map  (\(UnqualComponentName
    nm, CondTree ConfVar [Dependency] TestSuite
    ds) -> Component
    -> (TestSuite -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] TestSuite
    -> FlaggedDeps PN
    forall a.
    Monoid a =>
    Component
    -> (a -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    conv (UnqualComponentName -> Component
    ComponentTest UnqualComponentName
    nm)   TestSuite -> BuildInfo
    testBuildInfo (Stanza -> DependencyReason PN -> DependencyReason PN
    forall pn. Stanza -> DependencyReason pn -> DependencyReason pn
    addStanza Stanza
    TestStanzas DependencyReason PN
    initDR) CondTree ConfVar [Dependency] TestSuite
    ds)
                        [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
    tests)
           FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ (FlaggedDeps PN -> FlaggedDep PN)
    -> [FlaggedDeps PN] -> FlaggedDeps PN
    forall qpn.
    (FlaggedDeps qpn -> FlaggedDep qpn)
    -> [FlaggedDeps qpn] -> FlaggedDeps qpn
    prefix (SN PN -> FlaggedDeps PN -> FlaggedDep PN
    forall qpn. SN qpn -> TrueFlaggedDeps qpn -> FlaggedDep qpn
    Stanza (PN -> Stanza -> SN PN
    forall qpn. qpn -> Stanza -> SN qpn
    SN PN
    pn Stanza
    BenchStanzas))
                (((UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
     -> FlaggedDeps PN)
    -> [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
    -> [FlaggedDeps PN]
    forall a b. (a -> b) -> [a] -> [b]
    L.map  (\(UnqualComponentName
    nm, CondTree ConfVar [Dependency] Benchmark
    ds) -> Component
    -> (Benchmark -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] Benchmark
    -> FlaggedDeps PN
    forall a.
    Monoid a =>
    Component
    -> (a -> BuildInfo)
    -> DependencyReason PN
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    conv (UnqualComponentName -> Component
    ComponentBench UnqualComponentName
    nm)  Benchmark -> BuildInfo
    benchmarkBuildInfo (Stanza -> DependencyReason PN -> DependencyReason PN
    forall pn. Stanza -> DependencyReason pn -> DependencyReason pn
    addStanza Stanza
    BenchStanzas DependencyReason PN
    initDR) CondTree ConfVar [Dependency] Benchmark
    ds)
                        [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
    benchs)
           FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ FlaggedDeps PN
    -> (SetupBuildInfo -> FlaggedDeps PN)
    -> Maybe SetupBuildInfo
    -> FlaggedDeps PN
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe []  (PN -> SetupBuildInfo -> FlaggedDeps PN
    convSetupBuildInfo PN
    pn) (PackageDescription -> Maybe SetupBuildInfo
    setupBuildInfo PackageDescription
    pkg)

        addStanza :: Stanza -> DependencyReason pn -> DependencyReason pn
        addStanza :: forall pn. Stanza -> DependencyReason pn -> DependencyReason pn
    addStanza Stanza
    s (DependencyReason pn
    pn' Map Flag FlagValue
    fs Set Stanza
    ss) = pn -> Map Flag FlagValue -> Set Stanza -> DependencyReason pn
    forall qpn.
    qpn -> Map Flag FlagValue -> Set Stanza -> DependencyReason qpn
    DependencyReason pn
    pn' Map Flag FlagValue
    fs (Stanza -> Set Stanza -> Set Stanza
    forall a. Ord a => a -> Set a -> Set a
    S.insert Stanza
    s Set Stanza
    ss)

        -- | A too-new specVersion is turned into a global 'FailReason'
        -- which prevents the solver from selecting this release (and if
        -- forced to, emit a meaningful solver error message).
        fr :: Maybe FailReason
    fr = case Maybe Ver
    scannedVersion of
            Just Ver
    ver -> FailReason -> Maybe FailReason
    forall a. a -> Maybe a
    Just (Ver -> FailReason
    UnsupportedSpecVer Ver
    ver)
            Maybe Ver
    Nothing  -> Maybe FailReason
    forall a. Maybe a
    Nothing

        components :: Map ExposedComponent ComponentInfo
        components :: Map ExposedComponent ComponentInfo
    components = [(ExposedComponent, ComponentInfo)]
    -> Map ExposedComponent ComponentInfo
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([(ExposedComponent, ComponentInfo)]
     -> Map ExposedComponent ComponentInfo)
    -> [(ExposedComponent, ComponentInfo)]
    -> Map ExposedComponent ComponentInfo
    forall a b. (a -> b) -> a -> b
    $ [(ExposedComponent, ComponentInfo)]
    libComps [(ExposedComponent, ComponentInfo)]
    -> [(ExposedComponent, ComponentInfo)]
    -> [(ExposedComponent, ComponentInfo)]
    forall a. [a] -> [a] -> [a]
    ++ [(ExposedComponent, ComponentInfo)]
    subLibComps [(ExposedComponent, ComponentInfo)]
    -> [(ExposedComponent, ComponentInfo)]
    -> [(ExposedComponent, ComponentInfo)]
    forall a. [a] -> [a] -> [a]
    ++ [(ExposedComponent, ComponentInfo)]
    exeComps
          where
            libComps :: [(ExposedComponent, ComponentInfo)]
    libComps = [ (LibraryName -> ExposedComponent
    ExposedLib LibraryName
    LMainLibName, CondTree ConfVar [Dependency] Library -> ComponentInfo
    libToComponentInfo CondTree ConfVar [Dependency] Library
    lib)
                       | CondTree ConfVar [Dependency] Library
    lib <- Maybe (CondTree ConfVar [Dependency] Library)
    -> [CondTree ConfVar [Dependency] Library]
    forall a. Maybe a -> [a]
    maybeToList Maybe (CondTree ConfVar [Dependency] Library)
    mlib ]
            subLibComps :: [(ExposedComponent, ComponentInfo)]
    subLibComps = [ (LibraryName -> ExposedComponent
    ExposedLib (UnqualComponentName -> LibraryName
    LSubLibName UnqualComponentName
    name), CondTree ConfVar [Dependency] Library -> ComponentInfo
    libToComponentInfo CondTree ConfVar [Dependency] Library
    lib)
                          | (UnqualComponentName
    name, CondTree ConfVar [Dependency] Library
    lib) <- [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
    sub_libs ]
            exeComps :: [(ExposedComponent, ComponentInfo)]
    exeComps = [ ( UnqualComponentName -> ExposedComponent
    ExposedExe UnqualComponentName
    name
                         , ComponentInfo {
                               compIsVisible :: IsVisible
    compIsVisible = Bool -> IsVisible
    IsVisible Bool
    True
                             , compIsBuildable :: IsBuildable
    compIsBuildable = Bool -> IsBuildable
    IsBuildable (Bool -> IsBuildable) -> Bool -> IsBuildable
    forall a b. (a -> b) -> a -> b
    $ (Executable -> Bool)
    -> CondTree ConfVar [Dependency] Executable -> Maybe Bool
    forall {a}.
    (a -> Bool) -> CondTree ConfVar [Dependency] a -> Maybe Bool
    testCondition (BuildInfo -> Bool
    buildable (BuildInfo -> Bool)
    -> (Executable -> BuildInfo) -> Executable -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Executable -> BuildInfo
    buildInfo) CondTree ConfVar [Dependency] Executable
    exe Maybe Bool -> Maybe Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    False
                             }
                         )
                       | (UnqualComponentName
    name, CondTree ConfVar [Dependency] Executable
    exe) <- [(UnqualComponentName, CondTree ConfVar [Dependency] Executable)]
    exes ]

            libToComponentInfo :: CondTree ConfVar [Dependency] Library -> ComponentInfo
    libToComponentInfo CondTree ConfVar [Dependency] Library
    lib =
                ComponentInfo {
                    compIsVisible :: IsVisible
    compIsVisible = Bool -> IsVisible
    IsVisible (Bool -> IsVisible) -> Bool -> IsVisible
    forall a b. (a -> b) -> a -> b
    $ (Library -> Bool)
    -> CondTree ConfVar [Dependency] Library -> Maybe Bool
    forall {a}.
    (a -> Bool) -> CondTree ConfVar [Dependency] a -> Maybe Bool
    testCondition (LibraryVisibility -> Bool
    isPrivate (LibraryVisibility -> Bool)
    -> (Library -> LibraryVisibility) -> Library -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Library -> LibraryVisibility
    libVisibility) CondTree ConfVar [Dependency] Library
    lib Maybe Bool -> Maybe Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    True
                  , compIsBuildable :: IsBuildable
    compIsBuildable = Bool -> IsBuildable
    IsBuildable (Bool -> IsBuildable) -> Bool -> IsBuildable
    forall a b. (a -> b) -> a -> b
    $ (Library -> Bool)
    -> CondTree ConfVar [Dependency] Library -> Maybe Bool
    forall {a}.
    (a -> Bool) -> CondTree ConfVar [Dependency] a -> Maybe Bool
    testCondition (BuildInfo -> Bool
    buildable (BuildInfo -> Bool) -> (Library -> BuildInfo) -> Library -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Library -> BuildInfo
    libBuildInfo) CondTree ConfVar [Dependency] Library
    lib Maybe Bool -> Maybe Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    False
                  }

            testCondition :: (a -> Bool) -> CondTree ConfVar [Dependency] a -> Maybe Bool
    testCondition = OS
    -> Arch
    -> CompilerInfo
    -> [LabeledPackageConstraint]
    -> (a -> Bool)
    -> CondTree ConfVar [Dependency] a
    -> Maybe Bool
    forall a.
    OS
    -> Arch
    -> CompilerInfo
    -> [LabeledPackageConstraint]
    -> (a -> Bool)
    -> CondTree ConfVar [Dependency] a
    -> Maybe Bool
    testConditionForComponent OS
    os Arch
    arch CompilerInfo
    cinfo [LabeledPackageConstraint]
    constraints

            isPrivate :: LibraryVisibility -> Bool
    isPrivate LibraryVisibility
    LibraryVisibilityPrivate = Bool
    True
            isPrivate LibraryVisibility
    LibraryVisibilityPublic  = Bool
    False

      in FlaggedDeps PN
    -> Map ExposedComponent ComponentInfo
    -> FlagInfo
    -> Maybe FailReason
    -> PInfo
    PInfo FlaggedDeps PN
    flagged_deps Map ExposedComponent ComponentInfo
    components FlagInfo
    fds Maybe FailReason
    fr

    -- | Applies the given predicate (for example, testing buildability or
    -- visibility) to the given component and environment. Values are combined with
    -- AND. This function returns 'Nothing' when the result cannot be determined
    -- before dependency solving. Additionally, this function only considers flags
    -- that are set by unqualified flag constraints, and it doesn't check the
    -- intra-package dependencies of a component.
    testConditionForComponent :: OS
                              -> Arch
                              -> CompilerInfo
                              -> [LabeledPackageConstraint]
                              -> (a -> Bool)
                              -> CondTree ConfVar [Dependency] a
                              -> Maybe Bool
    testConditionForComponent :: forall a.
    OS
    -> Arch
    -> CompilerInfo
    -> [LabeledPackageConstraint]
    -> (a -> Bool)
    -> CondTree ConfVar [Dependency] a
    -> Maybe Bool
    testConditionForComponent OS
    os Arch
    arch CompilerInfo
    cinfo [LabeledPackageConstraint]
    constraints a -> Bool
    p CondTree ConfVar [Dependency] a
    tree =
        case Condition ConfVar -> Condition ConfVar
    go (Condition ConfVar -> Condition ConfVar)
    -> Condition ConfVar -> Condition ConfVar
    forall a b. (a -> b) -> a -> b
    $ (a -> Bool) -> CondTree ConfVar [Dependency] a -> Condition ConfVar
    forall v a c. Eq v => (a -> Bool) -> CondTree v c a -> Condition v
    extractCondition a -> Bool
    p CondTree ConfVar [Dependency] a
    tree of
          Lit Bool
    True  -> Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    True
          Lit Bool
    False -> Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    False
          Condition ConfVar
    _         -> Maybe Bool
    forall a. Maybe a
    Nothing
      where
        flagAssignment :: [(FlagName, Bool)]
        flagAssignment :: [(Flag, Bool)]
    flagAssignment =
            [[(Flag, Bool)]] -> [(Flag, Bool)]
    forall a. Monoid a => [a] -> a
    mconcat [ FlagAssignment -> [(Flag, Bool)]
    unFlagAssignment FlagAssignment
    fa
                    | PackageConstraint (ScopeAnyQualifier PN
    _) (PackagePropertyFlags FlagAssignment
    fa)
                        <- (LabeledPackageConstraint -> PackageConstraint)
    -> [LabeledPackageConstraint] -> [PackageConstraint]
    forall a b. (a -> b) -> [a] -> [b]
    L.map LabeledPackageConstraint -> PackageConstraint
    unlabelPackageConstraint [LabeledPackageConstraint]
    constraints]

        -- Simplify the condition, using the current environment. Most of this
        -- function was copied from convBranch and
        -- Distribution.Types.Condition.simplifyCondition.
        go :: Condition ConfVar -> Condition ConfVar
        go :: Condition ConfVar -> Condition ConfVar
    go (Var (OS OS
    os')) = Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit (OS
    os OS -> OS -> Bool
    forall a. Eq a => a -> a -> Bool
    == OS
    os')
        go (Var (Arch Arch
    arch')) = Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit (Arch
    arch Arch -> Arch -> Bool
    forall a. Eq a => a -> a -> Bool
    == Arch
    arch')
        go (Var (Impl CompilerFlavor
    cf VersionRange
    cvr))
            | CompilerId -> Bool
    matchImpl (CompilerInfo -> CompilerId
    compilerInfoId CompilerInfo
    cinfo) Bool -> Bool -> Bool
    ||
                  -- fixme: Nothing should be treated as unknown, rather than empty
                  --        list. This code should eventually be changed to either
                  --        support partial resolution of compiler flags or to
                  --        complain about incompletely configured compilers.
              (CompilerId -> Bool) -> [CompilerId] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any CompilerId -> Bool
    matchImpl ([CompilerId] -> Maybe [CompilerId] -> [CompilerId]
    forall a. a -> Maybe a -> a
    fromMaybe [] (Maybe [CompilerId] -> [CompilerId])
    -> Maybe [CompilerId] -> [CompilerId]
    forall a b. (a -> b) -> a -> b
    $ CompilerInfo -> Maybe [CompilerId]
    compilerInfoCompat CompilerInfo
    cinfo) = Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    True
            | Bool
    otherwise = Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    False
          where
            matchImpl :: CompilerId -> Bool
    matchImpl (CompilerId CompilerFlavor
    cf' Ver
    cv) = CompilerFlavor
    cf CompilerFlavor -> CompilerFlavor -> Bool
    forall a. Eq a => a -> a -> Bool
    == CompilerFlavor
    cf' Bool -> Bool -> Bool
    && VersionRange -> Ver -> Bool
    checkVR VersionRange
    cvr Ver
    cv
        go (Var (PackageFlag Flag
    f))
            | Just Bool
    b <- Flag -> [(Flag, Bool)] -> Maybe Bool
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    L.lookup Flag
    f [(Flag, Bool)]
    flagAssignment = Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    b
        go (Var ConfVar
    v) = ConfVar -> Condition ConfVar
    forall c. c -> Condition c
    Var ConfVar
    v
        go (Lit Bool
    b) = Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    b
        go (CNot Condition ConfVar
    c) =
            case Condition ConfVar -> Condition ConfVar
    go Condition ConfVar
    c of
              Lit Bool
    True -> Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    False
              Lit Bool
    False -> Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    True
              Condition ConfVar
    c' -> Condition ConfVar -> Condition ConfVar
    forall c. Condition c -> Condition c
    CNot Condition ConfVar
    c'
        go (COr Condition ConfVar
    c Condition ConfVar
    d) =
            case (Condition ConfVar -> Condition ConfVar
    go Condition ConfVar
    c, Condition ConfVar -> Condition ConfVar
    go Condition ConfVar
    d) of
              (Lit Bool
    False, Condition ConfVar
    d') -> Condition ConfVar
    d'
              (Lit Bool
    True, Condition ConfVar
    _)   -> Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    True
              (Condition ConfVar
    c', Lit Bool
    False) -> Condition ConfVar
    c'
              (Condition ConfVar
    _, Lit Bool
    True)   -> Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    True
              (Condition ConfVar
    c', Condition ConfVar
    d')        -> Condition ConfVar -> Condition ConfVar -> Condition ConfVar
    forall c. Condition c -> Condition c -> Condition c
    COr Condition ConfVar
    c' Condition ConfVar
    d'
        go (CAnd Condition ConfVar
    c Condition ConfVar
    d) =
            case (Condition ConfVar -> Condition ConfVar
    go Condition ConfVar
    c, Condition ConfVar -> Condition ConfVar
    go Condition ConfVar
    d) of
              (Lit Bool
    False, Condition ConfVar
    _) -> Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    False
              (Lit Bool
    True, Condition ConfVar
    d') -> Condition ConfVar
    d'
              (Condition ConfVar
    _, Lit Bool
    False) -> Bool -> Condition ConfVar
    forall c. Bool -> Condition c
    Lit Bool
    False
              (Condition ConfVar
    c', Lit Bool
    True) -> Condition ConfVar
    c'
              (Condition ConfVar
    c', Condition ConfVar
    d')       -> Condition ConfVar -> Condition ConfVar -> Condition ConfVar
    forall c. Condition c -> Condition c -> Condition c
    CAnd Condition ConfVar
    c' Condition ConfVar
    d'

    -- | Create a flagged dependency tree from a list @fds@ of flagged
    -- dependencies, using @f@ to form the tree node (@f@ will be
    -- something like @Stanza sn@).
    prefix :: (FlaggedDeps qpn -> FlaggedDep qpn)
           -> [FlaggedDeps qpn] -> FlaggedDeps qpn
    prefix :: forall qpn.
    (FlaggedDeps qpn -> FlaggedDep qpn)
    -> [FlaggedDeps qpn] -> FlaggedDeps qpn
    prefix FlaggedDeps qpn -> FlaggedDep qpn
    _ []  = []
    prefix FlaggedDeps qpn -> FlaggedDep qpn
    f [FlaggedDeps qpn]
    fds = [FlaggedDeps qpn -> FlaggedDep qpn
    f ([FlaggedDeps qpn] -> FlaggedDeps qpn
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [FlaggedDeps qpn]
    fds)]

    -- | Convert flag information. Automatic flags are now considered weak
    -- unless strong flags have been selected explicitly.
    flagInfo :: StrongFlags -> [PackageFlag] -> FlagInfo
    flagInfo :: StrongFlags -> [PackageFlag] -> FlagInfo
    flagInfo (StrongFlags Bool
    strfl) =
        [(Flag, FInfo)] -> FlagInfo
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([(Flag, FInfo)] -> FlagInfo)
    -> ([PackageFlag] -> [(Flag, FInfo)]) -> [PackageFlag] -> FlagInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (PackageFlag -> (Flag, FInfo)) -> [PackageFlag] -> [(Flag, FInfo)]
    forall a b. (a -> b) -> [a] -> [b]
    L.map (\ (MkPackageFlag Flag
    fn String
    _ Bool
    b Bool
    m) -> (Flag
    fn, Bool -> FlagType -> WeakOrTrivial -> FInfo
    FInfo Bool
    b (Bool -> FlagType
    flagType Bool
    m) (Bool -> WeakOrTrivial
    weak Bool
    m)))
      where
        weak :: Bool -> WeakOrTrivial
    weak Bool
    m = Bool -> WeakOrTrivial
    WeakOrTrivial (Bool -> WeakOrTrivial) -> Bool -> WeakOrTrivial
    forall a b. (a -> b) -> a -> b
    $ Bool -> Bool
    not (Bool
    strfl Bool -> Bool -> Bool
    || Bool
    m)
        flagType :: Bool -> FlagType
    flagType Bool
    m = if Bool
    m then FlagType
    Manual else FlagType
    Automatic

    -- | Convert condition trees to flagged dependencies.  Mutually
    -- recursive with 'convBranch'.  See 'convBranch' for an explanation
    -- of all arguments preceding the input 'CondTree'.
    convCondTree :: Map FlagName Bool -> DependencyReason PN -> PackageDescription -> OS -> Arch -> CompilerInfo -> PN -> FlagInfo ->
                    Component ->
                    (a -> BuildInfo) ->
                    SolveExecutables ->
                    CondTree ConfVar [Dependency] a -> FlaggedDeps PN
    convCondTree :: forall a.
    Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    convCondTree Map Flag Bool
    flags DependencyReason PN
    dr PackageDescription
    pkg OS
    os Arch
    arch CompilerInfo
    cinfo PN
    pn FlagInfo
    fds Component
    comp a -> BuildInfo
    getInfo solveExes :: SolveExecutables
    solveExes@(SolveExecutables Bool
    solveExes') (CondNode a
    info [Dependency]
    ds [CondBranch ConfVar [Dependency] a]
    branches) =
                 -- Merge all library and build-tool dependencies at every level in
                 -- the tree of flagged dependencies. Otherwise 'extractCommon'
                 -- could create duplicate dependencies, and the number of
                 -- duplicates could grow exponentially from the leaves to the root
                 -- of the tree.
                 FlaggedDeps PN -> FlaggedDeps PN
    forall qpn. Ord qpn => FlaggedDeps qpn -> FlaggedDeps qpn
    mergeSimpleDeps (FlaggedDeps PN -> FlaggedDeps PN)
    -> FlaggedDeps PN -> FlaggedDeps PN
    forall a b. (a -> b) -> a -> b
    $
                     [ LDep PN -> Component -> FlaggedDep PN
    forall qpn. LDep qpn -> Component -> FlaggedDep qpn
    D.Simple LDep PN
    singleDep Component
    comp
                     | Dependency
    dep <- [Dependency]
    ds
                     , LDep PN
    singleDep <- DependencyReason PN -> Dependency -> [LDep PN]
    convLibDeps DependencyReason PN
    dr Dependency
    dep ]  -- unconditional package dependencies

                  FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ (Extension -> FlaggedDep PN) -> [Extension] -> FlaggedDeps PN
    forall a b. (a -> b) -> [a] -> [b]
    L.map (\Extension
    e -> LDep PN -> Component -> FlaggedDep PN
    forall qpn. LDep qpn -> Component -> FlaggedDep qpn
    D.Simple (DependencyReason PN -> Dep PN -> LDep PN
    forall qpn. DependencyReason qpn -> Dep qpn -> LDep qpn
    LDep DependencyReason PN
    dr (Extension -> Dep PN
    forall qpn. Extension -> Dep qpn
    Ext  Extension
    e)) Component
    comp) (BuildInfo -> [Extension]
    allExtensions BuildInfo
    bi) -- unconditional extension dependencies
                  FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ (Language -> FlaggedDep PN) -> [Language] -> FlaggedDeps PN
    forall a b. (a -> b) -> [a] -> [b]
    L.map (\Language
    l -> LDep PN -> Component -> FlaggedDep PN
    forall qpn. LDep qpn -> Component -> FlaggedDep qpn
    D.Simple (DependencyReason PN -> Dep PN -> LDep PN
    forall qpn. DependencyReason qpn -> Dep qpn -> LDep qpn
    LDep DependencyReason PN
    dr (Language -> Dep PN
    forall qpn. Language -> Dep qpn
    Lang Language
    l)) Component
    comp) (BuildInfo -> [Language]
    allLanguages  BuildInfo
    bi) -- unconditional language dependencies
                  FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ (PkgconfigDependency -> FlaggedDep PN)
    -> [PkgconfigDependency] -> FlaggedDeps PN
    forall a b. (a -> b) -> [a] -> [b]
    L.map (\(PkgconfigDependency PkgconfigName
    pkn PkgconfigVersionRange
    vr) -> LDep PN -> Component -> FlaggedDep PN
    forall qpn. LDep qpn -> Component -> FlaggedDep qpn
    D.Simple (DependencyReason PN -> Dep PN -> LDep PN
    forall qpn. DependencyReason qpn -> Dep qpn -> LDep qpn
    LDep DependencyReason PN
    dr (PkgconfigName -> PkgconfigVersionRange -> Dep PN
    forall qpn. PkgconfigName -> PkgconfigVersionRange -> Dep qpn
    Pkg PkgconfigName
    pkn PkgconfigVersionRange
    vr)) Component
    comp) (BuildInfo -> [PkgconfigDependency]
    pkgconfigDepends BuildInfo
    bi) -- unconditional pkg-config dependencies
                  FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ (CondBranch ConfVar [Dependency] a -> FlaggedDeps PN)
    -> [CondBranch ConfVar [Dependency] a] -> FlaggedDeps PN
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondBranch ConfVar [Dependency] a
    -> FlaggedDeps PN
    forall a.
    Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondBranch ConfVar [Dependency] a
    -> FlaggedDeps PN
    convBranch Map Flag Bool
    flags DependencyReason PN
    dr PackageDescription
    pkg OS
    os Arch
    arch CompilerInfo
    cinfo PN
    pn FlagInfo
    fds Component
    comp a -> BuildInfo
    getInfo SolveExecutables
    solveExes) [CondBranch ConfVar [Dependency] a]
    branches
                  -- build-tools dependencies
                  -- NB: Only include these dependencies if SolveExecutables
                  -- is True.  It might be false in the legacy solver
                  -- codepath, in which case there won't be any record of
                  -- an executable we need.
                  FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ [ LDep PN -> Component -> FlaggedDep PN
    forall qpn. LDep qpn -> Component -> FlaggedDep qpn
    D.Simple (DependencyReason PN -> ExeDependency -> LDep PN
    convExeDep DependencyReason PN
    dr ExeDependency
    exeDep) Component
    comp
                     | Bool
    solveExes'
                     , ExeDependency
    exeDep <- PackageDescription -> BuildInfo -> [ExeDependency]
    getAllToolDependencies PackageDescription
    pkg BuildInfo
    bi
                     , Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ PackageDescription -> ExeDependency -> Bool
    isInternal PackageDescription
    pkg ExeDependency
    exeDep
                     ]
      where
        bi :: BuildInfo
    bi = a -> BuildInfo
    getInfo a
    info

    data SimpleFlaggedDepKey qpn =
        SimpleFlaggedDepKey (PkgComponent qpn) Component
      deriving (SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    (SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool)
    -> (SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool)
    -> Eq (SimpleFlaggedDepKey qpn)
    forall qpn.
    Eq qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall qpn.
    Eq qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    == :: SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    $c/= :: forall qpn.
    Eq qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    /= :: SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    Eq, Eq (SimpleFlaggedDepKey qpn)
    Eq (SimpleFlaggedDepKey qpn) =>
    (SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Ordering)
    -> (SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool)
    -> (SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool)
    -> (SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool)
    -> (SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool)
    -> (SimpleFlaggedDepKey qpn
        -> SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn)
    -> (SimpleFlaggedDepKey qpn
        -> SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn)
    -> Ord (SimpleFlaggedDepKey qpn)
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Ordering
    SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    forall qpn. Ord qpn => Eq (SimpleFlaggedDepKey qpn)
    forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Ordering
    forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn
    $ccompare :: forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Ordering
    compare :: SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Ordering
    $c< :: forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    < :: SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    $c<= :: forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    <= :: SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    $c> :: forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    > :: SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    $c>= :: forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    >= :: SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn -> Bool
    $cmax :: forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn
    max :: SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn
    $cmin :: forall qpn.
    Ord qpn =>
    SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn
    min :: SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepKey qpn -> SimpleFlaggedDepKey qpn
    Ord)

    data SimpleFlaggedDepValue qpn = SimpleFlaggedDepValue (DependencyReason qpn) VR

    -- | Merge 'Simple' dependencies that apply to the same library or build-tool.
    -- This function should be able to merge any two dependencies that can be merged
    -- by extractCommon, in order to prevent the exponential growth of dependencies.
    --
    -- Note that this function can merge dependencies that have different
    -- DependencyReasons, which can make the DependencyReasons less precise. This
    -- loss of precision only affects performance and log messages, not correctness.
    -- However, when 'mergeSimpleDeps' is only called on dependencies at a single
    -- location in the dependency tree, the only difference between
    -- DependencyReasons should be flags that have value FlagBoth. Adding extra
    -- flags with value FlagBoth should not affect performance, since they are not
    -- added to the conflict set. The only downside is the possibility of the log
    -- incorrectly saying that the flag contributed to excluding a specific version
    -- of a dependency. For example, if +/-flagA introduces pkg >=2 and +/-flagB
    -- introduces pkg <5, the merged dependency would mean that
    -- +/-flagA and +/-flagB introduce pkg >=2 && <5, which would incorrectly imply
    -- that +/-flagA excludes pkg-6.
    mergeSimpleDeps :: Ord qpn => FlaggedDeps qpn -> FlaggedDeps qpn
    mergeSimpleDeps :: forall qpn. Ord qpn => FlaggedDeps qpn -> FlaggedDeps qpn
    mergeSimpleDeps FlaggedDeps qpn
    deps = ((SimpleFlaggedDepKey qpn, SimpleFlaggedDepValue qpn)
     -> FlaggedDep qpn)
    -> [(SimpleFlaggedDepKey qpn, SimpleFlaggedDepValue qpn)]
    -> FlaggedDeps qpn
    forall a b. (a -> b) -> [a] -> [b]
    L.map ((SimpleFlaggedDepKey qpn
     -> SimpleFlaggedDepValue qpn -> FlaggedDep qpn)
    -> (SimpleFlaggedDepKey qpn, SimpleFlaggedDepValue qpn)
    -> FlaggedDep qpn
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepValue qpn -> FlaggedDep qpn
    forall qpn.
    SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepValue qpn -> FlaggedDep qpn
    toFlaggedDep) (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    -> [(SimpleFlaggedDepKey qpn, SimpleFlaggedDepValue qpn)]
    forall k a. Map k a -> [(k, a)]
    M.toList Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    merged) FlaggedDeps qpn -> FlaggedDeps qpn -> FlaggedDeps qpn
    forall a. [a] -> [a] -> [a]
    ++ FlaggedDeps qpn
    unmerged
      where
        (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    merged, FlaggedDeps qpn
    unmerged) = ((Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
      FlaggedDeps qpn)
     -> FlaggedDep qpn
     -> (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
         FlaggedDeps qpn))
    -> (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
        FlaggedDeps qpn)
    -> FlaggedDeps qpn
    -> (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
        FlaggedDeps qpn)
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    L.foldl' (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
     FlaggedDeps qpn)
    -> FlaggedDep qpn
    -> (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
        FlaggedDeps qpn)
    forall qpn.
    Ord qpn =>
    (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
     FlaggedDeps qpn)
    -> FlaggedDep qpn
    -> (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
        FlaggedDeps qpn)
    f (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    forall k a. Map k a
    M.empty, []) FlaggedDeps qpn
    deps
          where
            f :: Ord qpn
              => (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn), FlaggedDeps qpn)
              -> FlaggedDep qpn
              -> (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn), FlaggedDeps qpn)
            f :: forall qpn.
    Ord qpn =>
    (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
     FlaggedDeps qpn)
    -> FlaggedDep qpn
    -> (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn),
        FlaggedDeps qpn)
    f (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    merged', FlaggedDeps qpn
    unmerged') (D.Simple (LDep DependencyReason qpn
    dr (Dep PkgComponent qpn
    dep (Constrained VersionRange
    vr))) Component
    comp) =
                ( (SimpleFlaggedDepValue qpn
     -> SimpleFlaggedDepValue qpn -> SimpleFlaggedDepValue qpn)
    -> SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepValue qpn
    -> Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    -> Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
    M.insertWith SimpleFlaggedDepValue qpn
    -> SimpleFlaggedDepValue qpn -> SimpleFlaggedDepValue qpn
    forall qpn.
    SimpleFlaggedDepValue qpn
    -> SimpleFlaggedDepValue qpn -> SimpleFlaggedDepValue qpn
    mergeValues
                               (PkgComponent qpn -> Component -> SimpleFlaggedDepKey qpn
    forall qpn.
    PkgComponent qpn -> Component -> SimpleFlaggedDepKey qpn
    SimpleFlaggedDepKey PkgComponent qpn
    dep Component
    comp)
                               (DependencyReason qpn -> VersionRange -> SimpleFlaggedDepValue qpn
    forall qpn.
    DependencyReason qpn -> VersionRange -> SimpleFlaggedDepValue qpn
    SimpleFlaggedDepValue DependencyReason qpn
    dr VersionRange
    vr)
                               Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    merged'
                , FlaggedDeps qpn
    unmerged')
            f (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    merged', FlaggedDeps qpn
    unmerged') FlaggedDep qpn
    unmergeableDep = (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn)
    merged', FlaggedDep qpn
    unmergeableDep FlaggedDep qpn -> FlaggedDeps qpn -> FlaggedDeps qpn
    forall a. a -> [a] -> [a]
    : FlaggedDeps qpn
    unmerged')

            mergeValues :: SimpleFlaggedDepValue qpn
                        -> SimpleFlaggedDepValue qpn
                        -> SimpleFlaggedDepValue qpn
            mergeValues :: forall qpn.
    SimpleFlaggedDepValue qpn
    -> SimpleFlaggedDepValue qpn -> SimpleFlaggedDepValue qpn
    mergeValues (SimpleFlaggedDepValue DependencyReason qpn
    dr1 VersionRange
    vr1) (SimpleFlaggedDepValue DependencyReason qpn
    dr2 VersionRange
    vr2) =
                DependencyReason qpn -> VersionRange -> SimpleFlaggedDepValue qpn
    forall qpn.
    DependencyReason qpn -> VersionRange -> SimpleFlaggedDepValue qpn
    SimpleFlaggedDepValue (DependencyReason qpn
    -> DependencyReason qpn -> DependencyReason qpn
    forall pn.
    DependencyReason pn -> DependencyReason pn -> DependencyReason pn
    unionDRs DependencyReason qpn
    dr1 DependencyReason qpn
    dr2) (VersionRange
    vr1 VersionRange -> VersionRange -> VersionRange
    .&&. VersionRange
    vr2)

        toFlaggedDep :: SimpleFlaggedDepKey qpn
                     -> SimpleFlaggedDepValue qpn
                     -> FlaggedDep qpn
        toFlaggedDep :: forall qpn.
    SimpleFlaggedDepKey qpn
    -> SimpleFlaggedDepValue qpn -> FlaggedDep qpn
    toFlaggedDep (SimpleFlaggedDepKey PkgComponent qpn
    dep Component
    comp) (SimpleFlaggedDepValue DependencyReason qpn
    dr VersionRange
    vr) =
            LDep qpn -> Component -> FlaggedDep qpn
    forall qpn. LDep qpn -> Component -> FlaggedDep qpn
    D.Simple (DependencyReason qpn -> Dep qpn -> LDep qpn
    forall qpn. DependencyReason qpn -> Dep qpn -> LDep qpn
    LDep DependencyReason qpn
    dr (PkgComponent qpn -> CI -> Dep qpn
    forall qpn. PkgComponent qpn -> CI -> Dep qpn
    Dep PkgComponent qpn
    dep (VersionRange -> CI
    Constrained VersionRange
    vr))) Component
    comp

    -- | Branch interpreter.  Mutually recursive with 'convCondTree'.
    --
    -- Here, we try to simplify one of Cabal's condition tree branches into the
    -- solver's flagged dependency format, which is weaker. Condition trees can
    -- contain complex logical expression composed from flag choices and special
    -- flags (such as architecture, or compiler flavour). We try to evaluate the
    -- special flags and subsequently simplify to a tree that only depends on
    -- simple flag choices.
    --
    -- This function takes a number of arguments:
    --
    --      1. A map of flag values that have already been chosen. It allows
    --         convBranch to avoid creating nested FlaggedDeps that are
    --         controlled by the same flag and avoid creating DependencyReasons with
    --         conflicting values for the same flag.
    --
    --      2. The DependencyReason calculated at this point in the tree of
    --         conditionals. The flag values in the DependencyReason are similar to
    --         the values in the map above, except for the use of FlagBoth.
    --
    --      3. Some pre dependency-solving known information ('OS', 'Arch',
    --         'CompilerInfo') for @os()@, @arch()@ and @impl()@ variables,
    --
    --      4. The package name @'PN'@ which this condition tree
    --         came from, so that we can correctly associate @flag()@
    --         variables with the correct package name qualifier,
    --
    --      5. The flag defaults 'FlagInfo' so that we can populate
    --         'Flagged' dependencies with 'FInfo',
    --
    --      6. The name of the component 'Component' so we can record where
    --         the fine-grained information about where the component came
    --         from (see 'convCondTree'), and
    --
    --      7. A selector to extract the 'BuildInfo' from the leaves of
    --         the 'CondTree' (which actually contains the needed
    --         dependency information.)
    --
    --      8. The set of package names which should be considered internal
    --         dependencies, and thus not handled as dependencies.
    convBranch :: Map FlagName Bool
               -> DependencyReason PN
               -> PackageDescription
               -> OS
               -> Arch
               -> CompilerInfo
               -> PN
               -> FlagInfo
               -> Component
               -> (a -> BuildInfo)
               -> SolveExecutables
               -> CondBranch ConfVar [Dependency] a
               -> FlaggedDeps PN
    convBranch :: forall a.
    Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondBranch ConfVar [Dependency] a
    -> FlaggedDeps PN
    convBranch Map Flag Bool
    flags DependencyReason PN
    dr PackageDescription
    pkg OS
    os Arch
    arch CompilerInfo
    cinfo PN
    pn FlagInfo
    fds Component
    comp a -> BuildInfo
    getInfo SolveExecutables
    solveExes (CondBranch Condition ConfVar
    c' CondTree ConfVar [Dependency] a
    t' Maybe (CondTree ConfVar [Dependency] a)
    mf') =
        Condition ConfVar
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> Map Flag Bool
    -> DependencyReason PN
    -> FlaggedDeps PN
    go Condition ConfVar
    c'
           (\Map Flag Bool
    flags' DependencyReason PN
    dr' ->           Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    forall a.
    Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    convCondTree Map Flag Bool
    flags' DependencyReason PN
    dr' PackageDescription
    pkg OS
    os Arch
    arch CompilerInfo
    cinfo PN
    pn FlagInfo
    fds Component
    comp a -> BuildInfo
    getInfo SolveExecutables
    solveExes  CondTree ConfVar [Dependency] a
    t')
           (\Map Flag Bool
    flags' DependencyReason PN
    dr' -> FlaggedDeps PN
    -> (CondTree ConfVar [Dependency] a -> FlaggedDeps PN)
    -> Maybe (CondTree ConfVar [Dependency] a)
    -> FlaggedDeps PN
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    forall a.
    Map Flag Bool
    -> DependencyReason PN
    -> PackageDescription
    -> OS
    -> Arch
    -> CompilerInfo
    -> PN
    -> FlagInfo
    -> Component
    -> (a -> BuildInfo)
    -> SolveExecutables
    -> CondTree ConfVar [Dependency] a
    -> FlaggedDeps PN
    convCondTree Map Flag Bool
    flags' DependencyReason PN
    dr' PackageDescription
    pkg OS
    os Arch
    arch CompilerInfo
    cinfo PN
    pn FlagInfo
    fds Component
    comp a -> BuildInfo
    getInfo SolveExecutables
    solveExes) Maybe (CondTree ConfVar [Dependency] a)
    mf')
           Map Flag Bool
    flags DependencyReason PN
    dr
      where
        go :: Condition ConfVar
           -> (Map FlagName Bool -> DependencyReason PN -> FlaggedDeps PN)
           -> (Map FlagName Bool -> DependencyReason PN -> FlaggedDeps PN)
           ->  Map FlagName Bool -> DependencyReason PN -> FlaggedDeps PN
        go :: Condition ConfVar
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> Map Flag Bool
    -> DependencyReason PN
    -> FlaggedDeps PN
    go (Lit Bool
    True)  Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    _ = Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t
        go (Lit Bool
    False) Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    _ Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f = Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f
        go (CNot Condition ConfVar
    c)    Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f = Condition ConfVar
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> Map Flag Bool
    -> DependencyReason PN
    -> FlaggedDeps PN
    go Condition ConfVar
    c Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t
        go (CAnd Condition ConfVar
    c Condition ConfVar
    d)  Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f = Condition ConfVar
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> Map Flag Bool
    -> DependencyReason PN
    -> FlaggedDeps PN
    go Condition ConfVar
    c (Condition ConfVar
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> Map Flag Bool
    -> DependencyReason PN
    -> FlaggedDeps PN
    go Condition ConfVar
    d Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f) Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f
        go (COr  Condition ConfVar
    c Condition ConfVar
    d)  Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f = Condition ConfVar
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> Map Flag Bool
    -> DependencyReason PN
    -> FlaggedDeps PN
    go Condition ConfVar
    c Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t (Condition ConfVar
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN)
    -> Map Flag Bool
    -> DependencyReason PN
    -> FlaggedDeps PN
    go Condition ConfVar
    d Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f)
        go (Var (PackageFlag Flag
    fn)) Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f = \Map Flag Bool
    flags' ->
            case Flag -> Map Flag Bool -> Maybe Bool
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup Flag
    fn Map Flag Bool
    flags' of
              Just Bool
    True  -> Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool
    flags'
              Just Bool
    False -> Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f Map Flag Bool
    flags'
              Maybe Bool
    Nothing    -> \DependencyReason PN
    dr' ->
                -- Add each flag to the DependencyReason for all dependencies below,
                -- including any extracted dependencies. Extracted dependencies are
                -- introduced by both flag values (FlagBoth). Note that we don't
                -- actually need to add the flag to the extracted dependencies for
                -- correct backjumping; the information only improves log messages
                -- by giving the user the full reason for each dependency.
                let addFlagValue :: FlagValue -> DependencyReason PN
    addFlagValue FlagValue
    v = Flag -> FlagValue -> DependencyReason PN -> DependencyReason PN
    forall pn.
    Flag -> FlagValue -> DependencyReason pn -> DependencyReason pn
    addFlagToDependencyReason Flag
    fn FlagValue
    v DependencyReason PN
    dr'
                    addFlag :: Bool -> Map Flag Bool
    addFlag Bool
    v = Flag -> Bool -> Map Flag Bool -> Map Flag Bool
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert Flag
    fn Bool
    v Map Flag Bool
    flags'
                in FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall pn.
    Eq pn =>
    FlaggedDeps pn -> FlaggedDeps pn -> FlaggedDeps pn
    extractCommon (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t (Bool -> Map Flag Bool
    addFlag Bool
    True)  (FlagValue -> DependencyReason PN
    addFlagValue FlagValue
    FlagBoth))
                                 (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f (Bool -> Map Flag Bool
    addFlag Bool
    False) (FlagValue -> DependencyReason PN
    addFlagValue FlagValue
    FlagBoth))
                    FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDeps PN
    forall a. [a] -> [a] -> [a]
    ++ [ FN PN -> FInfo -> FlaggedDeps PN -> FlaggedDeps PN -> FlaggedDep PN
    forall qpn.
    FN qpn
    -> FInfo
    -> TrueFlaggedDeps qpn
    -> TrueFlaggedDeps qpn
    -> FlaggedDep qpn
    Flagged (PN -> Flag -> FN PN
    forall qpn. qpn -> Flag -> FN qpn
    FN PN
    pn Flag
    fn) (FlagInfo
    fds FlagInfo -> Flag -> FInfo
    forall k a. Ord k => Map k a -> k -> a
    M.! Flag
    fn) (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t (Bool -> Map Flag Bool
    addFlag Bool
    True)  (FlagValue -> DependencyReason PN
    addFlagValue FlagValue
    FlagTrue))
                                                         (Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f (Bool -> Map Flag Bool
    addFlag Bool
    False) (FlagValue -> DependencyReason PN
    addFlagValue FlagValue
    FlagFalse)) ]
        go (Var (OS OS
    os')) Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f
          | OS
    os OS -> OS -> Bool
    forall a. Eq a => a -> a -> Bool
    == OS
    os'      = Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t
          | Bool
    otherwise      = Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f
        go (Var (Arch Arch
    arch')) Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f
          | Arch
    arch Arch -> Arch -> Bool
    forall a. Eq a => a -> a -> Bool
    == Arch
    arch'  = Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t
          | Bool
    otherwise      = Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f
        go (Var (Impl CompilerFlavor
    cf VersionRange
    cvr)) Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f
          | CompilerId -> Bool
    matchImpl (CompilerInfo -> CompilerId
    compilerInfoId CompilerInfo
    cinfo) Bool -> Bool -> Bool
    ||
                -- fixme: Nothing should be treated as unknown, rather than empty
                --        list. This code should eventually be changed to either
                --        support partial resolution of compiler flags or to
                --        complain about incompletely configured compilers.
            (CompilerId -> Bool) -> [CompilerId] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any CompilerId -> Bool
    matchImpl ([CompilerId] -> Maybe [CompilerId] -> [CompilerId]
    forall a. a -> Maybe a -> a
    fromMaybe [] (Maybe [CompilerId] -> [CompilerId])
    -> Maybe [CompilerId] -> [CompilerId]
    forall a b. (a -> b) -> a -> b
    $ CompilerInfo -> Maybe [CompilerId]
    compilerInfoCompat CompilerInfo
    cinfo) = Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    t
          | Bool
    otherwise      = Map Flag Bool -> DependencyReason PN -> FlaggedDeps PN
    f
          where
            matchImpl :: CompilerId -> Bool
    matchImpl (CompilerId CompilerFlavor
    cf' Ver
    cv) = CompilerFlavor
    cf CompilerFlavor -> CompilerFlavor -> Bool
    forall a. Eq a => a -> a -> Bool
    == CompilerFlavor
    cf' Bool -> Bool -> Bool
    && VersionRange -> Ver -> Bool
    checkVR VersionRange
    cvr Ver
    cv

        addFlagToDependencyReason :: FlagName -> FlagValue -> DependencyReason pn -> DependencyReason pn
        addFlagToDependencyReason :: forall pn.
    Flag -> FlagValue -> DependencyReason pn -> DependencyReason pn
    addFlagToDependencyReason Flag
    fn FlagValue
    v (DependencyReason pn
    pn' Map Flag FlagValue
    fs Set Stanza
    ss) =
            pn -> Map Flag FlagValue -> Set Stanza -> DependencyReason pn
    forall qpn.
    qpn -> Map Flag FlagValue -> Set Stanza -> DependencyReason qpn
    DependencyReason pn
    pn' (Flag -> FlagValue -> Map Flag FlagValue -> Map Flag FlagValue
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert Flag
    fn FlagValue
    v Map Flag FlagValue
    fs) Set Stanza
    ss

        -- If both branches contain the same package as a simple dep, we lift it to
        -- the next higher-level, but with the union of version ranges. This
        -- heuristic together with deferring flag choices will then usually first
        -- resolve this package, and try an already installed version before imposing
        -- a default flag choice that might not be what we want.
        --
        -- Note that we make assumptions here on the form of the dependencies that
        -- can occur at this point. In particular, no occurrences of Fixed, as all
        -- dependencies below this point have been generated using 'convLibDep'.
        --
        -- WARNING: This is quadratic!
        extractCommon :: Eq pn => FlaggedDeps pn -> FlaggedDeps pn -> FlaggedDeps pn
        extractCommon :: forall pn.
    Eq pn =>
    FlaggedDeps pn -> FlaggedDeps pn -> FlaggedDeps pn
    extractCommon FlaggedDeps pn
    ps FlaggedDeps pn
    ps' =
            -- Union the DependencyReasons, because the extracted dependency can be
            -- avoided by removing the dependency from either side of the
            -- conditional.
            [ LDep pn -> Component -> FlaggedDep pn
    forall qpn. LDep qpn -> Component -> FlaggedDep qpn
    D.Simple (DependencyReason pn -> Dep pn -> LDep pn
    forall qpn. DependencyReason qpn -> Dep qpn -> LDep qpn
    LDep (DependencyReason pn -> DependencyReason pn -> DependencyReason pn
    forall pn.
    DependencyReason pn -> DependencyReason pn -> DependencyReason pn
    unionDRs DependencyReason pn
    vs1 DependencyReason pn
    vs2) (PkgComponent pn -> CI -> Dep pn
    forall qpn. PkgComponent qpn -> CI -> Dep qpn
    Dep PkgComponent pn
    dep1 (VersionRange -> CI
    Constrained (VersionRange -> CI) -> VersionRange -> CI
    forall a b. (a -> b) -> a -> b
    $ VersionRange
    vr1 VersionRange -> VersionRange -> VersionRange
    .||. VersionRange
    vr2))) Component
    comp
            | D.Simple (LDep DependencyReason pn
    vs1                (Dep PkgComponent pn
    dep1 (Constrained VersionRange
    vr1))) Component
    _ <- FlaggedDeps pn
    ps
            , D.Simple (LDep DependencyReason pn
    vs2                (Dep PkgComponent pn
    dep2 (Constrained VersionRange
    vr2))) Component
    _ <- FlaggedDeps pn
    ps'
            , PkgComponent pn
    dep1 PkgComponent pn -> PkgComponent pn -> Bool
    forall a. Eq a => a -> a -> Bool
    == PkgComponent pn
    dep2
            ]

    -- | Merge DependencyReasons by unioning their variables.
    unionDRs :: DependencyReason pn -> DependencyReason pn -> DependencyReason pn
    unionDRs :: forall pn.
    DependencyReason pn -> DependencyReason pn -> DependencyReason pn
    unionDRs (DependencyReason pn
    pn' Map Flag FlagValue
    fs1 Set Stanza
    ss1) (DependencyReason pn
    _ Map Flag FlagValue
    fs2 Set Stanza
    ss2) =
        pn -> Map Flag FlagValue -> Set Stanza -> DependencyReason pn
    forall qpn.
    qpn -> Map Flag FlagValue -> Set Stanza -> DependencyReason qpn
    DependencyReason pn
    pn' (Map Flag FlagValue -> Map Flag FlagValue -> Map Flag FlagValue
    forall k a. Ord k => Map k a -> Map k a -> Map k a
    M.union Map Flag FlagValue
    fs1 Map Flag FlagValue
    fs2) (Set Stanza -> Set Stanza -> Set Stanza
    forall a. Ord a => Set a -> Set a -> Set a
    S.union Set Stanza
    ss1 Set Stanza
    ss2)

    -- | Convert a Cabal dependency on a set of library components (from a single
    -- package) to solver-specific dependencies.
    convLibDeps :: DependencyReason PN -> Dependency -> [LDep PN]
    convLibDeps :: DependencyReason PN -> Dependency -> [LDep PN]
    convLibDeps DependencyReason PN
    dr (Dependency PN
    pn VersionRange
    vr NonEmptySet LibraryName
    libs) =
        [ DependencyReason PN -> Dep PN -> LDep PN
    forall qpn. DependencyReason qpn -> Dep qpn -> LDep qpn
    LDep DependencyReason PN
    dr (Dep PN -> LDep PN) -> Dep PN -> LDep PN
    forall a b. (a -> b) -> a -> b
    $ PkgComponent PN -> CI -> Dep PN
    forall qpn. PkgComponent qpn -> CI -> Dep qpn
    Dep (PN -> ExposedComponent -> PkgComponent PN
    forall qpn. qpn -> ExposedComponent -> PkgComponent qpn
    PkgComponent PN
    pn (LibraryName -> ExposedComponent
    ExposedLib LibraryName
    lib)) (VersionRange -> CI
    Constrained VersionRange
    vr)
        | LibraryName
    lib <- NonEmptySet LibraryName -> [LibraryName]
    forall a. NonEmptySet a -> [a]
    NonEmptySet.toList NonEmptySet LibraryName
    libs ]

    -- | Convert a Cabal dependency on an executable (build-tools) to a solver-specific dependency.
    convExeDep :: DependencyReason PN -> ExeDependency -> LDep PN
    convExeDep :: DependencyReason PN -> ExeDependency -> LDep PN
    convExeDep DependencyReason PN
    dr (ExeDependency PN
    pn UnqualComponentName
    exe VersionRange
    vr) = DependencyReason PN -> Dep PN -> LDep PN
    forall qpn. DependencyReason qpn -> Dep qpn -> LDep qpn
    LDep DependencyReason PN
    dr (Dep PN -> LDep PN) -> Dep PN -> LDep PN
    forall a b. (a -> b) -> a -> b
    $ PkgComponent PN -> CI -> Dep PN
    forall qpn. PkgComponent qpn -> CI -> Dep qpn
    Dep (PN -> ExposedComponent -> PkgComponent PN
    forall qpn. qpn -> ExposedComponent -> PkgComponent qpn
    PkgComponent PN
    pn (UnqualComponentName -> ExposedComponent
    ExposedExe UnqualComponentName
    exe)) (VersionRange -> CI
    Constrained VersionRange
    vr)

    -- | Convert setup dependencies
    convSetupBuildInfo :: PN -> SetupBuildInfo -> FlaggedDeps PN
    convSetupBuildInfo :: PN -> SetupBuildInfo -> FlaggedDeps PN
    convSetupBuildInfo PN
    pn SetupBuildInfo
    nfo =
        [ LDep PN -> Component -> FlaggedDep PN
    forall qpn. LDep qpn -> Component -> FlaggedDep qpn
    D.Simple LDep PN
    singleDep Component
    ComponentSetup
        | Dependency
    dep <- SetupBuildInfo -> [Dependency]
    setupDepends SetupBuildInfo
    nfo
        , LDep PN
    singleDep <- DependencyReason PN -> Dependency -> [LDep PN]
    convLibDeps (PN -> Map Flag FlagValue -> Set Stanza -> DependencyReason PN
    forall qpn.
    qpn -> Map Flag FlagValue -> Set Stanza -> DependencyReason qpn
    DependencyReason PN
    pn Map Flag FlagValue
    forall k a. Map k a
    M.empty Set Stanza
    forall a. Set a
    S.empty) Dependency
    dep ]