@@ -133,19 +133,41 @@ impl<M: Eq + Clone + Debug + Display> Display for DatedDerivation<M> {
133
133
}
134
134
}
135
135
136
- #[ derive( Clone , Debug ) ]
137
- enum AssignmentsIntersection {
138
- Decision ( ( u32 , VersionIndex , Term ) ) ,
139
- Derivations ( Term ) ,
136
+ #[ derive( Clone , Debug , Default ) ]
137
+ struct AssignmentsIntersection {
138
+ term : Term ,
139
+ is_decision : bool ,
140
+ decision_global_index : u32 ,
141
+ decision_version_index : VersionIndex ,
142
+ }
143
+
144
+ impl AssignmentsIntersection {
145
+ fn decision ( global_index : u32 , version_index : VersionIndex ) -> Self {
146
+ Self {
147
+ term : Term :: exact ( version_index) ,
148
+ is_decision : true ,
149
+ decision_global_index : global_index,
150
+ decision_version_index : version_index,
151
+ }
152
+ }
153
+
154
+ fn derivations ( term : Term ) -> Self {
155
+ Self {
156
+ term,
157
+ ..Default :: default ( )
158
+ }
159
+ }
140
160
}
141
161
142
162
impl Display for AssignmentsIntersection {
143
163
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
144
- match self {
145
- Self :: Decision ( ( lvl, version_index, _) ) => {
146
- write ! ( f, "Decision: level {}, v = {}" , lvl, version_index. get( ) )
147
- }
148
- Self :: Derivations ( term) => write ! ( f, "Derivations term: {}" , term) ,
164
+ if self . is_decision {
165
+ let lvl = self . decision_global_index ;
166
+ let version = self . decision_version_index . get ( ) ;
167
+ write ! ( f, "Decision: level {lvl}, v = {version}" )
168
+ } else {
169
+ let term = self . term ;
170
+ write ! ( f, "Derivations term: {term}" )
149
171
}
150
172
}
151
173
}
@@ -192,25 +214,26 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
192
214
pub ( crate ) fn add_decision ( & mut self , package_id : PackageId , version_index : VersionIndex ) {
193
215
// Check that add_decision is never used in the wrong context.
194
216
if cfg ! ( debug_assertions) {
195
- match self . package_assignments . get_mut ( & package_id) {
196
- None => panic ! ( "Derivations must already exist" ) ,
197
- Some ( pa) => match & pa. assignments_intersection {
198
- // Cannot be called when a decision has already been taken.
199
- AssignmentsIntersection :: Decision ( _) => panic ! ( "Already existing decision" ) ,
200
- // Cannot be called if the versions is not contained in the terms' intersection.
201
- AssignmentsIntersection :: Derivations ( term) => {
202
- debug_assert ! (
203
- term. contains( version_index) ,
204
- "{} was expected to be contained in {}" ,
205
- version_index. get( ) ,
206
- term,
207
- )
208
- }
209
- } ,
210
- }
217
+ let pa = self
218
+ . package_assignments
219
+ . get_mut ( & package_id)
220
+ . expect ( "Derivations must already exist" ) ;
221
+ // Cannot be called when a decision has already been taken.
222
+ assert ! (
223
+ !pa. assignments_intersection. is_decision,
224
+ "Already existing decision" ,
225
+ ) ;
226
+ // Cannot be called if the versions is not contained in the terms' intersection.
227
+ let term = pa. assignments_intersection . term ;
228
+ assert ! (
229
+ term. contains( version_index) ,
230
+ "{} was expected to be contained in {}" ,
231
+ version_index. get( ) ,
232
+ term,
233
+ ) ;
211
234
assert_eq ! (
212
235
self . changed_this_decision_level,
213
- self . package_assignments. len( )
236
+ self . package_assignments. len( ) ,
214
237
) ;
215
238
}
216
239
let new_idx = self . current_decision_level . 0 as usize ;
@@ -220,11 +243,8 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
220
243
. get_full_mut ( & package_id)
221
244
. expect ( "Derivations must already exist" ) ;
222
245
pa. highest_decision_level = self . current_decision_level ;
223
- pa. assignments_intersection = AssignmentsIntersection :: Decision ( (
224
- self . next_global_index ,
225
- version_index,
226
- Term :: exact ( version_index) ,
227
- ) ) ;
246
+ pa. assignments_intersection =
247
+ AssignmentsIntersection :: decision ( self . next_global_index , version_index) ;
228
248
// Maintain that the beginning of the `package_assignments` Have all decisions in sorted order.
229
249
if new_idx != old_idx {
230
250
self . package_assignments . swap_indices ( new_idx, old_idx) ;
@@ -253,21 +273,19 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
253
273
let idx = occupied. index ( ) ;
254
274
let pa = occupied. get_mut ( ) ;
255
275
pa. highest_decision_level = self . current_decision_level ;
256
- match & mut pa. assignments_intersection {
257
- // Check that add_derivation is never called in the wrong context.
258
- AssignmentsIntersection :: Decision ( _) => {
259
- panic ! ( "add_derivation should not be called after a decision" )
260
- }
261
- AssignmentsIntersection :: Derivations ( t) => {
262
- * t = t. intersection ( dated_derivation. accumulated_intersection ) ;
263
- dated_derivation. accumulated_intersection = * t;
264
- if t. is_positive ( ) {
265
- // we can use `swap_indices` to make `changed_this_decision_level` only go down by 1
266
- // but the copying is slower then the larger search
267
- self . changed_this_decision_level =
268
- std:: cmp:: min ( self . changed_this_decision_level , idx) ;
269
- }
270
- }
276
+ // Check that add_derivation is never called in the wrong context.
277
+ assert ! (
278
+ !pa. assignments_intersection. is_decision,
279
+ "add_derivation should not be called after a decision" ,
280
+ ) ;
281
+ let t = & mut pa. assignments_intersection . term ;
282
+ * t = t. intersection ( dated_derivation. accumulated_intersection ) ;
283
+ dated_derivation. accumulated_intersection = * t;
284
+ if t. is_positive ( ) {
285
+ // we can use `swap_indices` to make `changed_this_decision_level` only go down by 1
286
+ // but the copying is slower then the larger search
287
+ self . changed_this_decision_level =
288
+ std:: cmp:: min ( self . changed_this_decision_level , idx) ;
271
289
}
272
290
pa. dated_derivations . push ( dated_derivation) ;
273
291
}
@@ -281,7 +299,7 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
281
299
smallest_decision_level : self . current_decision_level ,
282
300
highest_decision_level : self . current_decision_level ,
283
301
dated_derivations : SmallVec :: One ( [ dated_derivation] ) ,
284
- assignments_intersection : AssignmentsIntersection :: Derivations ( term) ,
302
+ assignments_intersection : AssignmentsIntersection :: derivations ( term) ,
285
303
} ) ;
286
304
}
287
305
}
@@ -327,11 +345,12 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
327
345
. package_assignments
328
346
. iter ( )
329
347
. take ( self . current_decision_level . 0 as usize )
330
- . map ( |( & pid, pa) | match pa. assignments_intersection {
331
- AssignmentsIntersection :: Decision ( ( _, version_index, _) ) => ( pid, version_index) ,
332
- AssignmentsIntersection :: Derivations ( _) => {
333
- panic ! ( "Derivations in the Decision part" )
334
- }
348
+ . map ( |( & pid, pa) | {
349
+ assert ! (
350
+ pa. assignments_intersection. is_decision,
351
+ "Derivations in the Decision part" ,
352
+ ) ;
353
+ ( pid, pa. assignments_intersection . decision_version_index )
335
354
} )
336
355
. collect :: < Map < _ , _ > > ( ) ;
337
356
@@ -374,7 +393,7 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
374
393
375
394
// Reset the assignments intersection.
376
395
pa. assignments_intersection =
377
- AssignmentsIntersection :: Derivations ( last. accumulated_intersection ) ;
396
+ AssignmentsIntersection :: derivations ( last. accumulated_intersection ) ;
378
397
true
379
398
}
380
399
} ) ;
@@ -462,7 +481,7 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
462
481
pub ( crate ) fn term_intersection_for_package ( & self , package_id : PackageId ) -> Option < Term > {
463
482
self . package_assignments
464
483
. get ( & package_id)
465
- . map ( |pa| pa. assignments_intersection . term ( ) )
484
+ . map ( |pa| pa. assignments_intersection . term )
466
485
}
467
486
468
487
/// Figure out if the satisfier and previous satisfier are of different decision levels.
@@ -544,10 +563,11 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
544
563
let accum_term = if let & Some ( cause) = satisfier_cause {
545
564
store[ cause] . get ( satisfier_package_id) . unwrap ( ) . negate ( )
546
565
} else {
547
- match satisfier_pa. assignments_intersection {
548
- AssignmentsIntersection :: Derivations ( _) => panic ! ( "must be a decision" ) ,
549
- AssignmentsIntersection :: Decision ( ( _, _, term) ) => term,
550
- }
566
+ assert ! (
567
+ satisfier_pa. assignments_intersection. is_decision,
568
+ "must be a decision" ,
569
+ ) ;
570
+ satisfier_pa. assignments_intersection . term
551
571
} ;
552
572
553
573
let incompat_term = incompat
@@ -589,49 +609,37 @@ impl<M: Eq + Clone + Debug + Display> PackageAssignments<M> {
589
609
debug_assert_eq ! ( dd. accumulated_intersection. intersection( start_term) , empty) ;
590
610
return ( Some ( dd. cause ) , dd. global_index , dd. decision_level ) ;
591
611
}
592
- // If it wasn't found in the derivations,
593
- // it must be the decision which is last (if called in the right context).
594
- match & self . assignments_intersection {
595
- AssignmentsIntersection :: Decision ( ( global_index , _ , _ ) ) => {
596
- ( None , * global_index , self . highest_decision_level )
597
- }
598
- AssignmentsIntersection :: Derivations ( accumulated_intersection ) => {
599
- let p = package_store . pkg ( package_id ) . unwrap ( ) ;
600
- unreachable ! (
601
- "while processing package {p}: \
602
- accum_term = {accumulated_intersection} has overlap with incompat_term = {start_term}, \
603
- which means the last assignment should have been a decision , \
604
- but instead it was a derivation. This shouldn't be possible! \
605
- (Maybe your Version ordering is broken?)"
606
- )
607
- }
612
+ // If it wasn't found in the derivations, it must be the decision which is last (if called in the right context).
613
+ let AssignmentsIntersection {
614
+ term ,
615
+ is_decision ,
616
+ decision_global_index ,
617
+ ..
618
+ } = self . assignments_intersection ;
619
+ if !is_decision {
620
+ let p = package_store . pkg ( package_id ) . unwrap ( ) ;
621
+ unreachable ! (
622
+ "while processing package {p}: \
623
+ accum_term = {term} has overlap with incompat_term = {start_term} , \
624
+ which means the last assignment should have been a decision, \
625
+ but instead it was a derivation. This shouldn't be possible! \
626
+ (Maybe your Version ordering is broken?)"
627
+ )
608
628
}
629
+ ( None , decision_global_index, self . highest_decision_level )
609
630
}
610
631
}
611
632
612
633
impl AssignmentsIntersection {
613
- /// Returns the term intersection of all assignments (decision included).
614
- fn term ( & self ) -> Term {
615
- match * self {
616
- Self :: Decision ( ( _, _, term) ) => term,
617
- Self :: Derivations ( term) => term,
618
- }
619
- }
620
-
621
634
/// A package is a potential pick if there isn't an already
622
635
/// selected version (no "decision")
623
636
/// and if it contains at least one positive derivation term
624
637
/// in the partial solution.
625
638
fn potential_package_filter ( & self , package_id : PackageId ) -> Option < ( PackageId , VersionSet ) > {
626
- match self {
627
- Self :: Decision ( _) => None ,
628
- Self :: Derivations ( term_intersection) => {
629
- if term_intersection. is_positive ( ) {
630
- Some ( ( package_id, term_intersection. unwrap_positive ( ) ) )
631
- } else {
632
- None
633
- }
634
- }
639
+ if !self . is_decision && self . term . is_positive ( ) {
640
+ Some ( ( package_id, self . term . unwrap_positive ( ) ) )
641
+ } else {
642
+ None
635
643
}
636
644
}
637
645
}
0 commit comments