Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace <0 with some other construct to avoid confusion #10156

Open
jasagredo opened this issue Jun 27, 2024 · 2 comments
Open

Replace <0 with some other construct to avoid confusion #10156

jasagredo opened this issue Jun 27, 2024 · 2 comments

Comments

@jasagredo
Copy link
Collaborator

Having a bound <0 means that it is unsatisfiable, it is not a real bound as it cannot be influenced by --allow-newer:

➜ cat aa.cabal
cabal-version:   3.0
name:            aa
version:         0.1.0.0
license:         NONE
build-type:      Simple
extra-doc-files: CHANGELOG.md

common warnings
    ghc-options: -Wall

library
    import:           warnings
    exposed-modules:  MyLib
    build-depends:    base <0
    hs-source-dirs:   src
    default-language: Haskell2010

➜ cabal build --allow-newer
Resolving dependencies...
Error: [Cabal-7107]
Could not resolve dependencies:
[__0] trying: aa-0.1.0.0 (user goal)
[__1] next goal: base (dependency of aa)
[__1] rejecting: base-4.18.2.1/installed-4.18.2.1 (conflict: aa => base<0)
[__1] skipping: base; 4.20.0.1, 4.20.0.0, 4.19.1.0, 4.19.0.0, 4.18.2.1, 4.18.2.0, 4.18.1.0, 4.18.0.0, 4.17.2.1, 4.17.2.0, 4.17.1.0, 4.17.0.0, 4.16.4.0, 4.16.3.0, 4.16.2.0, 4.16.1.0, 4.16.0.0, 4.15.1.0, 4.15.0.0, 4.14.3.0, 4.14.2.0, 4.14.1.0, 4.14.0.0, 4.13.0.0, 4.12.0.0, 4.11.1.0, 4.11.0.0, 4.10.1.0, 4.10.0.0, 4.9.1.0, 4.9.0.0, 4.8.2.0, 4.8.1.0, 4.8.0.0, 4.7.0.2, 4.7.0.1, 4.7.0.0, 4.6.0.1, 4.6.0.0, 4.5.1.0, 4.5.0.0, 4.4.1.0, 4.4.0.0, 4.3.1.0, 4.3.0.0, 4.2.0.2, 4.2.0.1, 4.2.0.0, 4.1.0.0, 4.0.0.0, 3.0.3.2, 3.0.3.1 (has the same characteristics that caused the previous version to fail: excluded by constraint '<0' from 'aa')
[__1] fail (backjumping, conflict set: aa, base)
After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: aa, base

➜ sed -i 's/<0/<0.0/g' aa.cabal

➜ cabal build --allow-newer
Resolving dependencies...
Build profile: -w ghc-9.6.5 -O1
In order, the following will be built (use -v for more details):
 - aa-0.1.0.0 (lib) (first run)
Configuring library for aa-0.1.0.0...

I think it would be good if we used some other construct that what looks like a normal bound when we want something to be unbuildable.

@jasagredo
Copy link
Collaborator Author

FTR, Cabal 1.22 introduced the -none version:

➜ cat aa.cabal
cabal-version:   3.0
name:            aa
version:         0.1.0.0
license:         NONE
build-type:      Simple
extra-doc-files: CHANGELOG.md

common warnings
    ghc-options: -Wall

library
    import:           warnings
    exposed-modules:  MyLib
    build-depends:    base -none
    hs-source-dirs:   src
    default-language: Haskell2010

This would be precisely the construct I'm talking about. However -none results in the range <0 which is still considered unsat because noVersion = EarlierVersion (mkVersion [0]).

@andreabedini
Copy link
Collaborator

The code path is

-- in Distribution.Client.Dependency

removeUpperBounds :: AllowNewer -> DepResolverParams -> DepResolverParams

removeBounds :: RelaxKind -> RelaxDeps -> DepResolverParams -> DepResolverParams

relaxPackageDeps
  :: RelaxKind
  -> RelaxDeps
  -> PD.GenericPackageDescription
  -> PD.GenericPackageDescription

removeBound :: RelaxKind -> RelaxDepMod -> VersionRange -> VersionRange

-- in Distribution.Version

-- | Given a version range, remove the highest upper bound. Example: @(>= 1 && <
-- 3) || (>= 4 && < 5)@ is converted to @(>= 1 && < 3) || (>= 4)@.
removeUpperBound :: VersionRange -> VersionRange
removeUpperBound = fromVersionIntervals . relaxLastInterval . toVersionIntervals

-- | Given a version range, remove the lowest lower bound.
-- Example: @(>= 1 && < 3) || (>= 4 && < 5)@ is converted to
-- @(>= 0 && < 3) || (>= 4 && < 5)@.
removeLowerBound :: VersionRange -> VersionRange
removeLowerBound = fromVersionIntervals . relaxHeadInterval . toVersionIntervals

and indeed

ghci> noVersion
EarlierVersion (mkVersion [0])
ghci> removeUpperBound noVersion
EarlierVersion (mkVersion [0])

I guess the logic bug is in toVersionIntervals:

ghci> toVersionIntervals noVersion
VersionIntervals []

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants