@@ -27,9 +27,10 @@ pub struct State<P: Package, VS: VersionSet, Priority: Ord + Clone> {
27
27
28
28
incompatibilities : Map < P , Vec < IncompId < P , VS > > > ,
29
29
30
- /// Store the ids of incompatibilities that are already contradicted
31
- /// and will stay that way until the next conflict and backtrack is operated.
32
- contradicted_incompatibilities : rustc_hash:: FxHashSet < IncompId < P , VS > > ,
30
+ /// Store the ids of incompatibilities that are already contradicted.
31
+ /// For each one keep track of the decision level when it was found to be contradicted.
32
+ /// These will stay contradicted until we have backtracked beyond its associated decision level.
33
+ contradicted_incompatibilities : Map < IncompId < P , VS > , DecisionLevel > ,
33
34
34
35
/// All incompatibilities expressing dependencies,
35
36
/// with common dependents merged.
@@ -62,7 +63,7 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> State<P, VS, Priority> {
62
63
root_package,
63
64
root_version,
64
65
incompatibilities,
65
- contradicted_incompatibilities : rustc_hash :: FxHashSet :: default ( ) ,
66
+ contradicted_incompatibilities : Map :: default ( ) ,
66
67
partial_solution : PartialSolution :: empty ( ) ,
67
68
incompatibility_store,
68
69
unit_propagation_buffer : SmallVec :: Empty ,
@@ -111,7 +112,10 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> State<P, VS, Priority> {
111
112
let mut conflict_id = None ;
112
113
// We only care about incompatibilities if it contains the current package.
113
114
for & incompat_id in self . incompatibilities [ & current_package] . iter ( ) . rev ( ) {
114
- if self . contradicted_incompatibilities . contains ( & incompat_id) {
115
+ if self
116
+ . contradicted_incompatibilities
117
+ . contains_key ( & incompat_id)
118
+ {
115
119
continue ;
116
120
}
117
121
let current_incompat = & self . incompatibility_store [ incompat_id] ;
@@ -135,10 +139,12 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> State<P, VS, Priority> {
135
139
& self . incompatibility_store ,
136
140
) ;
137
141
// With the partial solution updated, the incompatibility is now contradicted.
138
- self . contradicted_incompatibilities . insert ( incompat_id) ;
142
+ self . contradicted_incompatibilities
143
+ . insert ( incompat_id, self . partial_solution . current_decision_level ( ) ) ;
139
144
}
140
145
Relation :: Contradicted ( _) => {
141
- self . contradicted_incompatibilities . insert ( incompat_id) ;
146
+ self . contradicted_incompatibilities
147
+ . insert ( incompat_id, self . partial_solution . current_decision_level ( ) ) ;
142
148
}
143
149
_ => { }
144
150
}
@@ -155,7 +161,8 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> State<P, VS, Priority> {
155
161
) ;
156
162
// After conflict resolution and the partial solution update,
157
163
// the root cause incompatibility is now contradicted.
158
- self . contradicted_incompatibilities . insert ( root_cause) ;
164
+ self . contradicted_incompatibilities
165
+ . insert ( root_cause, self . partial_solution . current_decision_level ( ) ) ;
159
166
}
160
167
}
161
168
// If there are no more changed packages, unit propagation is done.
@@ -220,7 +227,9 @@ impl<P: Package, VS: VersionSet, Priority: Ord + Clone> State<P, VS, Priority> {
220
227
) {
221
228
self . partial_solution
222
229
. backtrack ( decision_level, & self . incompatibility_store ) ;
223
- self . contradicted_incompatibilities . clear ( ) ;
230
+ // Remove contradicted incompatibilities that depend on decisions we just backtracked away.
231
+ self . contradicted_incompatibilities
232
+ . retain ( |_, dl| * dl <= decision_level) ;
224
233
if incompat_changed {
225
234
self . merge_incompatibility ( incompat) ;
226
235
}
0 commit comments