Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d1057df
filter == version constraints
philderbeast Jan 30, 2026
3147c23
Show flag setting in FailReason
philderbeast Feb 2, 2026
4097b8a
Add changelog
philderbeast Feb 2, 2026
e4e4054
Add tests using projects
philderbeast Feb 6, 2026
22ea64a
SkipIfOSX
philderbeast Feb 6, 2026
8507a1d
Update expectation in solver unit test
philderbeast Feb 7, 2026
a070d5d
Add constrained solving tests
philderbeast Feb 9, 2026
19e2793
Add mkConstraint
philderbeast Feb 9, 2026
edbd815
Use normalise not normaliseVersionRange
philderbeast Feb 10, 2026
2c1a881
Add >= version constraint check
philderbeast Feb 10, 2026
42dd321
Finer grained test groups; pass and rejects
philderbeast Feb 10, 2026
d49fd8c
Add <= tests
philderbeast Feb 10, 2026
461d76c
Combine >= with <= tests
philderbeast Feb 10, 2026
35453ae
Test >0 && ==1 and also ==1 && >0
philderbeast Feb 10, 2026
485bea4
Test B <=1 && >=1, C <=1 && >=1
philderbeast Feb 10, 2026
3755db7
Reuse solutions
philderbeast Feb 10, 2026
7471da0
Test >0 && ==1 && <2
philderbeast Feb 10, 2026
0fefbc4
Lines between commented bindings
philderbeast Feb 10, 2026
deaa768
Add test for B ==1 || >0, C >0 || ==1
philderbeast Feb 10, 2026
05d6b6d
Add eqFailure
philderbeast Feb 10, 2026
e1d6c64
Add test for ^>=1 constraint
philderbeast Feb 11, 2026
7e07b69
Change s/all goals/goal all/
philderbeast Feb 11, 2026
31205b6
Add test for ==1 || ==2
philderbeast Feb 11, 2026
555999d
Add test for ==1 || >1 and ==1 || <1
philderbeast Feb 11, 2026
7c9d4c3
Add VersionEqualitiesInPackages test
philderbeast Feb 11, 2026
befd474
Follow hlint suggestion: redundant $
philderbeast Mar 20, 2026
7b1b38d
Satisfy fourmolu
philderbeast Mar 20, 2026
330ed0e
Update expectation of #11626
philderbeast May 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import Distribution.Types.UnqualComponentName
( unUnqualComponentName )

import Text.PrettyPrint ( nest, render )
import Distribution.Solver.Types.Settings (OnlyConstrained(..))

-- A data type to hold log information from the modular solver.
data Message =
Expand Down Expand Up @@ -311,7 +312,7 @@ showFR _ (PackageRequiresMissingComponent qpn comp) = " (requires " ++ showExpos
showFR _ (PackageRequiresPrivateComponent qpn comp) = " (requires " ++ showExposedComponent comp ++ " from " ++ showQPN qpn ++ ", but the component is private)"
showFR _ (PackageRequiresUnbuildableComponent qpn comp) = " (requires " ++ showExposedComponent comp ++ " from " ++ showQPN qpn ++ ", but the component is not buildable in the current environment)"
showFR _ CannotReinstall = " (avoiding to reinstall a package with same version but new dependencies)"
showFR _ NotExplicit = " (not a user-provided goal nor mentioned as a constraint, but reject-unconstrained-dependencies was set)"
showFR _ (NotExplicit oc) = showNotExplicit oc
showFR _ Shadowed = " (shadowed by another installed package with same version)"
showFR _ (Broken u) = " (package is broken, missing dependency " ++ prettyShow u ++ ")"
showFR _ UnknownPackage = " (unknown package)"
Expand All @@ -334,6 +335,11 @@ showFR _ (MalformedFlagChoice qfn) = " (INTERNAL ERROR: MALFORMED FLAG CH
showFR _ (MalformedStanzaChoice qsn) = " (INTERNAL ERROR: MALFORMED STANZA CHOICE: " ++ showQSN qsn ++ ")"
showFR _ EmptyGoalChoice = " (INTERNAL ERROR: EMPTY GOAL CHOICE)"

showNotExplicit :: OnlyConstrained -> String
showNotExplicit oc = if oc == OnlyConstrainedNone
then " (INTERNAL ERROR: NOT EXPLICIT when reject-unconstrained-dependencies=" ++ prettyShow oc ++ " was set)"
else " (not a user-provided goal nor mentioned as a constraint, but reject-unconstrained-dependencies=" ++ prettyShow oc ++ " was set)"

showExposedComponent :: ExposedComponent -> String
showExposedComponent (ExposedLib LMainLibName) = "library"
showExposedComponent (ExposedLib (LSubLibName name)) = "library '" ++ unUnqualComponentName name ++ "'"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import Distribution.Solver.Modular.Tree
import Distribution.Solver.Modular.Version
import qualified Distribution.Solver.Modular.ConflictSet as CS
import qualified Distribution.Solver.Modular.WeightedPSQ as W
import Distribution.Solver.Types.Settings (OnlyConstrained(..))

-- | Update the weights of children under 'PChoice' nodes. 'addWeights' takes a
-- list of weight-calculating functions in order to avoid sorting the package
Expand Down Expand Up @@ -351,13 +352,13 @@ avoidReinstalls p = go
go x = x

-- | Require all packages to be mentioned in a constraint or as a goal.
onlyConstrained :: (PN -> Bool) -> EndoTreeTrav d QGoalReason
onlyConstrained p = go
onlyConstrained :: OnlyConstrained -> (PN -> Bool) -> EndoTreeTrav d QGoalReason
onlyConstrained oc p = go
where
go (PChoiceF v@(Q _ pn) _ gr _) | not (p pn)
= FailF
(varToConflictSet (P v) `CS.union` goalReasonToConflictSetWithConflict v gr)
NotExplicit
(NotExplicit oc)
go x
= x

Expand Down
26 changes: 18 additions & 8 deletions cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
#ifdef DEBUG_TRACETREE
{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
Expand All @@ -11,6 +12,7 @@ module Distribution.Solver.Modular.Solver

import Distribution.Solver.Compat.Prelude
import Prelude ()
import Data.Function ((&))

import qualified Data.Map as M
import qualified Data.List as L
Expand All @@ -19,10 +21,12 @@ import Distribution.Verbosity

import Distribution.Compiler (CompilerInfo)

import Distribution.Version
import Distribution.Solver.Types.PackagePath
import Distribution.Solver.Types.PackagePreferences
import Distribution.Solver.Types.PkgConfigDb (PkgConfigDb)
import Distribution.Solver.Types.LabeledPackageConstraint
import Distribution.Solver.Types.PackageConstraint (PackageConstraint(..), PackageProperty(..))
import Distribution.Solver.Types.Settings
import Distribution.Solver.Types.Variable

Expand Down Expand Up @@ -139,18 +143,15 @@ solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals =
validateLinking idx .
validateTree cinfo idx pkgConfigDB
prunePhase = (if asBool (avoidReinstalls sc) then P.avoidReinstalls (const True) else id) .
(case onlyConstrained sc of
OnlyConstrainedAll ->
P.onlyConstrained pkgIsExplicit
OnlyConstrainedNone ->
id)
(let oc = onlyConstrained sc in oc & \case
OnlyConstrainedEq -> P.onlyConstrained oc (`S.member` allExplicitEq)
OnlyConstrainedAll -> P.onlyConstrained oc (`S.member` allExplicit)
OnlyConstrainedNone -> id)
buildPhase = buildTree idx (independentGoals sc) (S.toList userGoals)

allExplicitEq = M.keysSet (filterThisVersion userConstraints) `S.union` userGoals
allExplicit = M.keysSet userConstraints `S.union` userGoals

pkgIsExplicit :: PN -> Bool
pkgIsExplicit pn = S.member pn allExplicit

-- When --reorder-goals is set, we use preferReallyEasyGoalChoices, which
-- prefers (keeps) goals only if the have 0 or 1 enabled choice.
--
Expand All @@ -167,6 +168,15 @@ solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals =
| asBool (reorderGoals sc) = P.preferReallyEasyGoalChoices
| otherwise = id {- P.firstGoal -}

-- | Keep version ranges that normalise to equality version constraints (== v).
filterThisVersion :: M.Map PN [LabeledPackageConstraint] -> M.Map PN [LabeledPackageConstraint]
filterThisVersion = M.filter (not . null) . M.map (filter isThisVersion) where
normalise = fromVersionIntervals . toVersionIntervals
isThisVersion lpc
| LabeledPackageConstraint (PackageConstraint _ (PackagePropertyVersion vr)) _ <- lpc
, ThisVersionF _ <- projectVersionRange $ normalise vr = True
| otherwise = False

-- | Dump solver tree to a file (in debugging mode)
--
-- This only does something if the @debug-tracetree@ configure argument was
Expand Down
3 changes: 2 additions & 1 deletion cabal-install-solver/src/Distribution/Solver/Modular/Tree.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Distribution.Solver.Types.PackagePath
import Distribution.Types.PkgconfigVersionRange
import Distribution.Types.UnitId (UnitId)
import Language.Haskell.Extension (Extension, Language)
import Distribution.Solver.Types.Settings (OnlyConstrained(..))

type Weight = Double

Expand Down Expand Up @@ -112,7 +113,7 @@ data FailReason = UnsupportedExtension Extension
| PackageRequiresPrivateComponent QPN ExposedComponent
| PackageRequiresUnbuildableComponent QPN ExposedComponent
| CannotReinstall
| NotExplicit
| NotExplicit OnlyConstrained
| Shadowed
| Broken UnitId
| UnknownPackage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ newtype AllowBootLibInstalls = AllowBootLibInstalls Bool
data OnlyConstrained
= OnlyConstrainedNone
| OnlyConstrainedAll
| OnlyConstrainedEq
deriving (Eq, Generic, Show)

newtype EnableBackjumping = EnableBackjumping Bool
Expand Down Expand Up @@ -108,12 +109,14 @@ instance NFData AllowBootLibInstalls
instance NFData OnlyConstrained

instance Pretty OnlyConstrained where
pretty OnlyConstrainedEq = PP.text "eq"
pretty OnlyConstrainedAll = PP.text "all"
pretty OnlyConstrainedNone = PP.text "none"

instance Parsec OnlyConstrained where
parsec = P.choice
[ P.string "all" >> return OnlyConstrainedAll
[ P.string "eq" >> return OnlyConstrainedEq
, P.string "all" >> return OnlyConstrainedAll
, P.string "none" >> return OnlyConstrainedNone
]

Expand Down
4 changes: 2 additions & 2 deletions cabal-install/src/Distribution/Client/Setup.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3736,9 +3736,9 @@ optionSolverFlags
getoc
setoc
( reqArg
"none|all"
"none|all|eq"
( parsecToReadE
(const "reject-unconstrained-dependencies must be 'none' or 'all'")
(const "reject-unconstrained-dependencies must be 'none', 'all', or 'eq'")
(toFlag `fmap` parsec)
)
(flagToList . fmap prettyShow)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

-- | Utilities for creating HUnit test cases with the solver DSL.
module UnitTests.Distribution.Solver.Modular.DSL.TestCaseUtils
( SolverTest
( SolverTest (..)
, SolverResult (..)
, maxBackjumps
, disableFineGrainedConflicts
Expand Down Expand Up @@ -80,9 +80,9 @@ allowBootLibInstalls :: SolverTest -> SolverTest
allowBootLibInstalls test =
test{testAllowBootLibInstalls = AllowBootLibInstalls True}

onlyConstrained :: SolverTest -> SolverTest
onlyConstrained test =
test{testOnlyConstrained = OnlyConstrainedAll}
onlyConstrained :: OnlyConstrained -> SolverTest -> SolverTest
onlyConstrained oc test =
test{testOnlyConstrained = oc}

disableBackjumping :: SolverTest -> SolverTest
disableBackjumping test =
Expand Down
Loading
Loading