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