Skip to content

Commit 8194fab

Browse files
sebrightezyang
authored andcommitted
Enforce qualified constraints in the dependency solver.
1 parent 5495daf commit 8194fab

File tree

2 files changed

+47
-28
lines changed

2 files changed

+47
-28
lines changed

cabal-install/Distribution/Solver/Modular/Preference.hs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE ScopedTypeVariables #-}
12
-- | Reordering or pruning the tree in order to prefer or make certain choices.
23
module Distribution.Solver.Modular.Preference
34
( avoidReinstalls
@@ -25,7 +26,6 @@ import qualified Data.Map as M
2526
import Control.Monad.Reader hiding (sequence)
2627
import Data.Traversable (sequence)
2728

28-
import Distribution.Solver.Types.ConstraintSource
2929
import Distribution.Solver.Types.InstalledPreference
3030
import Distribution.Solver.Types.LabeledPackageConstraint
3131
import Distribution.Solver.Types.OptionalStanza
@@ -146,46 +146,47 @@ preferPackageStanzaPreferences pcs = trav go
146146
-- given instance for a P-node. Translates the constraint into a
147147
-- tree-transformer that either leaves the subtree untouched, or replaces it
148148
-- with an appropriate failure node.
149-
processPackageConstraintP :: PackagePath
149+
processPackageConstraintP :: forall d c. QPN
150150
-> ConflictSet
151151
-> I
152152
-> LabeledPackageConstraint
153153
-> Tree d c
154154
-> Tree d c
155-
processPackageConstraintP pp _ _ (LabeledPackageConstraint _ src) r
156-
| src == ConstraintSourceUserTarget && not (primaryPP pp) = r
157-
-- the constraints arising from targets, like "foo-1.0" only apply to
158-
-- the main packages in the solution, they don't constrain setup deps
159-
| src == ConstraintSetupCabalMinVersion && not (setupPP pp) = r
160-
-- the internal constraints on the Setup.hs CLI version don't apply to
161-
-- the main packages in the solution, they only constrain setup deps
162-
163-
processPackageConstraintP _ c i (LabeledPackageConstraint pc src) r = go i pc
155+
processPackageConstraintP qpn c i (LabeledPackageConstraint (PackageConstraint scope prop) src) r =
156+
if constraintScopeMatches scope qpn
157+
then go i prop
158+
else r
164159
where
165-
go (I v _) (PackageConstraint _ (PackagePropertyVersion vr))
160+
go :: I -> PackageProperty -> Tree d c
161+
go (I v _) (PackagePropertyVersion vr)
166162
| checkVR vr v = r
167163
| otherwise = Fail c (GlobalConstraintVersion vr src)
168-
go _ (PackageConstraint _ PackagePropertyInstalled)
164+
go _ PackagePropertyInstalled
169165
| instI i = r
170166
| otherwise = Fail c (GlobalConstraintInstalled src)
171-
go _ (PackageConstraint _ PackagePropertySource)
167+
go _ PackagePropertySource
172168
| not (instI i) = r
173169
| otherwise = Fail c (GlobalConstraintSource src)
174-
go _ _ = r
170+
go _ _ = r
175171

176172
-- | Helper function that tries to enforce a single package constraint on a
177173
-- given flag setting for an F-node. Translates the constraint into a
178174
-- tree-transformer that either leaves the subtree untouched, or replaces it
179175
-- with an appropriate failure node.
180-
processPackageConstraintF :: Flag
176+
processPackageConstraintF :: forall d c. QPN
177+
-> Flag
181178
-> ConflictSet
182179
-> Bool
183180
-> LabeledPackageConstraint
184181
-> Tree d c
185182
-> Tree d c
186-
processPackageConstraintF f c b' (LabeledPackageConstraint pc src) r = go pc
183+
processPackageConstraintF qpn f c b' (LabeledPackageConstraint (PackageConstraint scope prop) src) r =
184+
if constraintScopeMatches scope qpn
185+
then go prop
186+
else r
187187
where
188-
go (PackageConstraint _ (PackagePropertyFlags fa)) =
188+
go :: PackageProperty -> Tree d c
189+
go (PackagePropertyFlags fa) =
189190
case L.lookup f fa of
190191
Nothing -> r
191192
Just b | b == b' -> r
@@ -196,15 +197,20 @@ processPackageConstraintF f c b' (LabeledPackageConstraint pc src) r = go pc
196197
-- given flag setting for an F-node. Translates the constraint into a
197198
-- tree-transformer that either leaves the subtree untouched, or replaces it
198199
-- with an appropriate failure node.
199-
processPackageConstraintS :: OptionalStanza
200+
processPackageConstraintS :: forall d c. QPN
201+
-> OptionalStanza
200202
-> ConflictSet
201203
-> Bool
202204
-> LabeledPackageConstraint
203205
-> Tree d c
204206
-> Tree d c
205-
processPackageConstraintS s c b' (LabeledPackageConstraint pc src) r = go pc
207+
processPackageConstraintS qpn s c b' (LabeledPackageConstraint (PackageConstraint scope prop) src) r =
208+
if constraintScopeMatches scope qpn
209+
then go prop
210+
else r
206211
where
207-
go (PackageConstraint _ (PackagePropertyStanzas ss)) =
212+
go :: PackageProperty -> Tree d c
213+
go (PackagePropertyStanzas ss) =
208214
if not b' && s `elem` ss then Fail c (GlobalConstraintFlag src)
209215
else r
210216
go _ = r
@@ -217,22 +223,25 @@ enforcePackageConstraints :: M.Map PN [LabeledPackageConstraint]
217223
-> Tree d c
218224
enforcePackageConstraints pcs = trav go
219225
where
220-
go (PChoiceF qpn@(Q pp pn) rdm gr ts) =
226+
go (PChoiceF qpn@(Q _ pn) rdm gr ts) =
221227
let c = varToConflictSet (P qpn)
222228
-- compose the transformation functions for each of the relevant constraint
223-
g = \ (POption i _) -> foldl (\ h pc -> h . processPackageConstraintP pp c i pc) id
224-
(M.findWithDefault [] pn pcs)
229+
g = \ (POption i _) -> foldl (\ h pc -> h . processPackageConstraintP qpn c i pc)
230+
id
231+
(M.findWithDefault [] pn pcs)
225232
in PChoiceF qpn rdm gr (W.mapWithKey g ts)
226-
go (FChoiceF qfn@(FN (PI (Q _ pn) _) f) rdm gr tr m ts) =
233+
go (FChoiceF qfn@(FN (PI qpn@(Q _ pn) _) f) rdm gr tr m ts) =
227234
let c = varToConflictSet (F qfn)
228235
-- compose the transformation functions for each of the relevant constraint
229-
g = \ b -> foldl (\ h pc -> h . processPackageConstraintF f c b pc) id
236+
g = \ b -> foldl (\ h pc -> h . processPackageConstraintF qpn f c b pc)
237+
id
230238
(M.findWithDefault [] pn pcs)
231239
in FChoiceF qfn rdm gr tr m (W.mapWithKey g ts)
232-
go (SChoiceF qsn@(SN (PI (Q _ pn) _) f) rdm gr tr ts) =
240+
go (SChoiceF qsn@(SN (PI qpn@(Q _ pn) _) f) rdm gr tr ts) =
233241
let c = varToConflictSet (S qsn)
234242
-- compose the transformation functions for each of the relevant constraint
235-
g = \ b -> foldl (\ h pc -> h . processPackageConstraintS f c b pc) id
243+
g = \ b -> foldl (\ h pc -> h . processPackageConstraintS qpn f c b pc)
244+
id
236245
(M.findWithDefault [] pn pcs)
237246
in SChoiceF qsn rdm gr tr (W.mapWithKey g ts)
238247
go x = x

cabal-install/Distribution/Solver/Types/PackageConstraint.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module Distribution.Solver.Types.PackageConstraint (
99
ConstraintScope(..),
1010
scopeToplevel,
1111
scopeToPackageName,
12+
constraintScopeMatches,
1213
PackageProperty(..),
1314
dispPackageProperty,
1415
PackageConstraint(..),
@@ -58,6 +59,15 @@ scopeToPackageName (ScopeQualified _ pn) = pn
5859
scopeToPackageName (ScopeAnySetupQualifier pn) = pn
5960
scopeToPackageName (ScopeAnyQualifier pn) = pn
6061

62+
constraintScopeMatches :: ConstraintScope -> QPN -> Bool
63+
constraintScopeMatches (ScopeQualified q pn) (Q (PackagePath _ q') pn') =
64+
q == q' && pn == pn'
65+
constraintScopeMatches (ScopeAnySetupQualifier pn) (Q pp pn') =
66+
let setup (PackagePath _ (QualSetup _)) = True
67+
setup _ = False
68+
in setup pp && pn == pn'
69+
constraintScopeMatches (ScopeAnyQualifier pn) (Q _ pn') = pn == pn'
70+
6171
-- | Pretty-prints a constraint scope.
6272
dispConstraintScope :: ConstraintScope -> Disp.Doc
6373
dispConstraintScope (ScopeQualified q pn) = dispQualifier q <<>> disp pn

0 commit comments

Comments
 (0)