Describe the bug
On master, passing --allow-boot-library-installs turns an otherwise working
plan into a failure, on any GHC that does not report wired-in unit ids (GHC < 9.14).
The error names ghc-internal, a package the user never mentioned:
Error:
Dependency on unbuildable library from ghc-internal
In the stanza 'library'
In the package 'base-4.22.0.0'
Note that the solver does not report an unsolvable plan. It succeeds, having
selected base-4.22.0.0 from Hackage; the failure happens afterwards, during
elaboration.
This is a regression on master only. Released cabal-install 3.18.1.0 is not
affected.
To Reproduce
#!/usr/bin/env bash
# Usage: ./repro.sh # uses `cabal` and `ghc` from PATH
# CABAL=/path/to/cabal GHC=ghc-9.12.2 ./repro.sh
#
# Exits 0 if cabal behaves correctly, non-zero if the bug is present.
set -eu
CABAL=${CABAL:-cabal}
GHC=${GHC:-ghc}
dir=$(mktemp -d)
trap 'rm -rf "$dir"' EXIT
cd "$dir"
cat > repro.cabal <<'EOF'
cabal-version: 2.4
name: repro
version: 0
build-type: Simple
library
exposed-modules: Lib
build-depends: base
default-language: Haskell2010
EOF
printf 'module Lib where\n' > Lib.hs
echo "cabal-install $("$CABAL" --numeric-version), ghc $("$GHC" --numeric-version)"
echo
echo "=== 1. without --allow-boot-library-installs (expected: succeeds) ==="
"$CABAL" build --dry-run -w "$GHC"
echo
echo "=== 2. with --allow-boot-library-installs (expected: succeeds) ==="
if "$CABAL" build --dry-run -w "$GHC" --allow-boot-library-installs; then
echo
echo "RESULT: ok -- no bug on this cabal/ghc combination."
else
echo
echo "RESULT: BUG -- the same plan fails once --allow-boot-library-installs is passed."
exit 1
fi
Step 1 establishes that the plan is fine; step 2 differs only by the flag.
| GHC |
result |
| 9.10.3 |
fails |
| 9.12.2 |
fails |
| 9.14.1 |
succeeds (reports wired-in unit ids) |
Without the flag, all three succeed.
Expected behavior
--allow-boot-library-installs should not make a plan fail. It relaxes a
restriction; it should never turn a solvable plan into an unsolvable one.
System information
- Linux
cabal-install built from master (a0c8112), version 3.19.0.0
- GHC 9.10.3, 9.12.2, 9.14.1
Additional context
dependOnWiredIns adds two kinds of constraint: one installed-unit-id
constraint per wired-in unit of the compiler, and one base >= 4.22 version
constraint added in #12055.
|
dependOnWiredIns :: CompilerInfo -> DepResolverParams -> DepResolverParams |
|
dependOnWiredIns compiler params = addConstraints extraConstraints params |
|
where |
|
extraConstraints = |
|
[ LabeledPackageConstraint |
|
(PackageConstraint (ScopeAnyQualifier pkgName) (PackagePropertyInstalledSpecificUnitId unitId)) |
|
ConstraintSourceNonReinstallablePackage |
|
| (pkgName, unitId) <- fromMaybe [] $ compilerInfoWiredInUnitIds compiler |
|
] |
|
++ |
|
-- Old versions of `base` must be excluded from build plans still as they do not depend on any version of a wired-in unit. |
|
-- If we do not do this then we will get confusing error messages about old versions of `base` being unbuildable. |
|
-- Newer versions of `base` will be handled gracefully as they were designed to be reinstallable. |
|
[ LabeledPackageConstraint |
|
(PackageConstraint (ScopeAnyQualifier $ mkPackageName "base") (PackagePropertyVersion (orLaterVersion (mkVersion [4, 22])))) |
|
ConstraintSourceNonReinstallablePackage |
|
] |
The second constraint only makes sense next to the first. The unit-id
constraints pin the new, reinstallable base; the version constraint then
excludes the old, non-reinstallable one. But it is added unconditionally, while
the unit-id constraints are empty for a compiler that reports no wired-in units.
That path is reachable for such a compiler, because the caller enters it on
either of two conditions:
|
if isJust (compilerInfoWiredInUnitIds comp) || asBool (depResolverAllowBootLibInstalls params) |
|
then dependOnWiredIns comp params |
|
else dontInstallNonReinstallablePackages params |
--allow-boot-library-installs alone is enough. So on GHC 9.12, the installed
base-4.21.0.0 is excluded by the version constraint, base-4.22.0.0 is
selected from Hackage instead, and it cannot be built because ghc-internal is
not available there.
Fixed by #12301, which guards the version constraint on the compiler actually
reporting wired-in unit ids.
Describe the bug
On
master, passing--allow-boot-library-installsturns an otherwise workingplan into a failure, on any GHC that does not report wired-in unit ids (GHC < 9.14).
The error names
ghc-internal, a package the user never mentioned:Note that the solver does not report an unsolvable plan. It succeeds, having
selected
base-4.22.0.0from Hackage; the failure happens afterwards, duringelaboration.
This is a regression on
masteronly. Releasedcabal-install3.18.1.0 is notaffected.
To Reproduce
Step 1 establishes that the plan is fine; step 2 differs only by the flag.
Without the flag, all three succeed.
Expected behavior
--allow-boot-library-installsshould not make a plan fail. It relaxes arestriction; it should never turn a solvable plan into an unsolvable one.
System information
cabal-installbuilt frommaster(a0c8112), version 3.19.0.0Additional context
dependOnWiredInsadds two kinds of constraint: one installed-unit-idconstraint per wired-in unit of the compiler, and one
base >= 4.22versionconstraint added in #12055.
cabal/cabal-install/src/Distribution/Client/Dependency.hs
Lines 447 to 463 in a0c8112
The second constraint only makes sense next to the first. The unit-id
constraints pin the new, reinstallable
base; the version constraint thenexcludes the old, non-reinstallable one. But it is added unconditionally, while
the unit-id constraints are empty for a compiler that reports no wired-in units.
That path is reachable for such a compiler, because the caller enters it on
either of two conditions:
cabal/cabal-install/src/Distribution/Client/Dependency.hs
Lines 919 to 921 in a0c8112
--allow-boot-library-installsalone is enough. So on GHC 9.12, the installedbase-4.21.0.0is excluded by the version constraint,base-4.22.0.0isselected from Hackage instead, and it cannot be built because
ghc-internalisnot available there.
Fixed by #12301, which guards the version constraint on the compiler actually
reporting wired-in unit ids.