    -- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
    module Distribution.Backpack.PreExistingComponent (
        PreExistingComponent(..),
        ipiToPreExistingComponent,
    ) where

    import Prelude ()
    import Distribution.Compat.Prelude

    import Distribution.Backpack.ModuleShape
    import Distribution.Backpack
    import Distribution.Types.ComponentId
    import Distribution.Types.MungedPackageId
    import Distribution.Types.PackageId
    import Distribution.Types.UnitId
    import Distribution.Types.ComponentName
    import Distribution.Types.PackageName
    import Distribution.Package

    import qualified Data.Map as Map
    import qualified Distribution.InstalledPackageInfo as Installed
    import Distribution.InstalledPackageInfo (InstalledPackageInfo)

    -- | Stripped down version of 'LinkedComponent' for things
    -- we don't need to know how to build.
    data PreExistingComponent
        = PreExistingComponent {
            -- | The actual name of the package. This may DISAGREE with 'pc_pkgid'
            -- for internal dependencies: e.g., an internal component @lib@ may be
            -- munged to @z-pkg-z-lib@, but we still want to use it when we see
            -- @lib@ in @build-depends@
            PreExistingComponent -> PackageName
    pc_pkgname :: PackageName,
            -- | The actual name of the component.
            PreExistingComponent -> ComponentName
    pc_compname :: ComponentName,
            PreExistingComponent -> MungedPackageId
    pc_munged_id :: MungedPackageId,
            PreExistingComponent -> UnitId
    pc_uid   :: UnitId,
            PreExistingComponent -> ComponentId
    pc_cid   :: ComponentId,
            PreExistingComponent -> OpenUnitId
    pc_open_uid :: OpenUnitId,
            PreExistingComponent -> ModuleShape
    pc_shape :: ModuleShape
        }

    -- | Convert an 'InstalledPackageInfo' into a 'PreExistingComponent',
    -- which was brought into scope under the 'PackageName' (important for
    -- a package qualified reference.)
    ipiToPreExistingComponent :: InstalledPackageInfo -> PreExistingComponent
    ipiToPreExistingComponent :: InstalledPackageInfo -> PreExistingComponent
    ipiToPreExistingComponent InstalledPackageInfo
    ipi =
        PreExistingComponent {
            pc_pkgname :: PackageName
    pc_pkgname = InstalledPackageInfo -> PackageName
    forall pkg. Package pkg => pkg -> PackageName
    packageName InstalledPackageInfo
    ipi,
            pc_compname :: ComponentName
    pc_compname = LibraryName -> ComponentName
    CLibName (LibraryName -> ComponentName) -> LibraryName -> ComponentName
    forall a b. (a -> b) -> a -> b
    $ InstalledPackageInfo -> LibraryName
    Installed.sourceLibName InstalledPackageInfo
    ipi,
            pc_munged_id :: MungedPackageId
    pc_munged_id = InstalledPackageInfo -> MungedPackageId
    forall pkg. HasMungedPackageId pkg => pkg -> MungedPackageId
    mungedId InstalledPackageInfo
    ipi,
            pc_uid :: UnitId
    pc_uid   = InstalledPackageInfo -> UnitId
    Installed.installedUnitId InstalledPackageInfo
    ipi,
            pc_cid :: ComponentId
    pc_cid   = InstalledPackageInfo -> ComponentId
    Installed.installedComponentId InstalledPackageInfo
    ipi,
            pc_open_uid :: OpenUnitId
    pc_open_uid =
                ComponentId -> OpenModuleSubst -> OpenUnitId
    IndefFullUnitId (InstalledPackageInfo -> ComponentId
    Installed.installedComponentId InstalledPackageInfo
    ipi)
                                ([(ModuleName, OpenModule)] -> OpenModuleSubst
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList (InstalledPackageInfo -> [(ModuleName, OpenModule)]
    Installed.instantiatedWith InstalledPackageInfo
    ipi)),
            pc_shape :: ModuleShape
    pc_shape = InstalledPackageInfo -> ModuleShape
    shapeInstalledPackage InstalledPackageInfo
    ipi
        }

    instance HasMungedPackageId PreExistingComponent where
      mungedId :: PreExistingComponent -> MungedPackageId
    mungedId = PreExistingComponent -> MungedPackageId
    pc_munged_id

    instance Package PreExistingComponent where
      packageId :: PreExistingComponent -> PackageIdentifier
    packageId PreExistingComponent
    pec = PackageName -> Version -> PackageIdentifier
    PackageIdentifier (PreExistingComponent -> PackageName
    pc_pkgname PreExistingComponent
    pec) Version
    v
        where MungedPackageId MungedPackageName
    _ Version
    v = PreExistingComponent -> MungedPackageId
    pc_munged_id PreExistingComponent
    pec

    instance HasUnitId PreExistingComponent where
      installedUnitId :: PreExistingComponent -> UnitId
    installedUnitId = PreExistingComponent -> UnitId
    pc_uid