@@ -13,7 +13,7 @@ use dashmap::DashMap;
13
13
use either:: Either ;
14
14
use futures:: { FutureExt , StreamExt } ;
15
15
use itertools:: Itertools ;
16
- use pubgrub:: { Id , Incompatibility , Range , Ranges , State , Term } ;
16
+ use pubgrub:: { Id , IncompId , Incompatibility , Range , Ranges , State } ;
17
17
use rustc_hash:: { FxHashMap , FxHashSet } ;
18
18
use tokio:: sync:: mpsc:: { self , Receiver , Sender } ;
19
19
use tokio:: sync:: oneshot;
@@ -336,17 +336,9 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
336
336
} else {
337
337
// Run unit propagation.
338
338
let result = state. pubgrub . unit_propagation ( state. next ) ;
339
- // End the mutable borrow of `state.pubgrub`.
340
- let result = result. map ( |conflict| {
341
- conflict. map ( |conflict| {
342
- conflict
343
- . map ( |( package, term) | ( package, term. clone ( ) ) )
344
- . collect :: < Vec < _ > > ( )
345
- } )
346
- } ) ;
347
339
match result {
348
340
Err ( err) => {
349
- // If unit propagation failed, the is no solution.
341
+ // If unit propagation failed, there is no solution.
350
342
return Err ( self . convert_no_solution_err (
351
343
err,
352
344
state. fork_urls ,
@@ -357,14 +349,13 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
357
349
& self . capabilities ,
358
350
) ) ;
359
351
}
360
- Ok ( Some ( conflict) ) => {
361
- // Conflict tracking: If the version was rejected due to its dependencies,
362
- // record culprit and affected.
363
- state. record_conflict ( state. next , None , & conflict) ;
352
+ Ok ( conflicts) => {
353
+ for ( affected, incompatibility) in conflicts {
354
+ // Conflict tracking: If there was a conflict, track affected and
355
+ // culprit for all root cause incompatibilities
356
+ state. record_conflict ( affected, None , incompatibility) ;
357
+ }
364
358
}
365
- // There was no conflict, or we've already rejected the last version due to its
366
- // dependencies.
367
- Ok ( None ) => { }
368
359
}
369
360
370
361
// Pre-visit all candidate packages, to allow metadata to be fetched in parallel.
@@ -2412,14 +2403,11 @@ impl ForkState {
2412
2403
( package, version)
2413
2404
} ) ,
2414
2405
) ;
2415
- // End the mutable borrow of `self.pubgrub`
2416
- let conflict: Option < Vec < _ > > =
2417
- conflict. map ( |x| x. map ( |( package, term) | ( package, term. clone ( ) ) ) . collect ( ) ) ;
2418
2406
2419
2407
// Conflict tracking: If the version was rejected due to its dependencies, record culprit
2420
2408
// and affected.
2421
- if let Some ( conflict ) = conflict {
2422
- self . record_conflict ( for_package, Some ( for_version) , & conflict ) ;
2409
+ if let Some ( incompatibility ) = conflict {
2410
+ self . record_conflict ( for_package, Some ( for_version) , incompatibility ) ;
2423
2411
}
2424
2412
Ok ( ( ) )
2425
2413
}
@@ -2428,15 +2416,15 @@ impl ForkState {
2428
2416
& mut self ,
2429
2417
affected : Id < PubGrubPackage > ,
2430
2418
version : Option < & Version > ,
2431
- conflict : & [ ( Id < PubGrubPackage > , Term < Ranges < Version > > ) ] ,
2419
+ incompatibility : IncompId < PubGrubPackage , Ranges < Version > , UnavailableReason > ,
2432
2420
) {
2433
2421
let mut culprit_is_real = false ;
2434
- for ( incompatible, _term) in conflict {
2435
- if * incompatible == affected {
2422
+ for ( incompatible, _term) in self . pubgrub . incompatibility_store [ incompatibility ] . iter ( ) {
2423
+ if incompatible == affected {
2436
2424
continue ;
2437
2425
}
2438
2426
if self . pubgrub . package_store [ affected] . name ( )
2439
- == self . pubgrub . package_store [ * incompatible] . name ( )
2427
+ == self . pubgrub . package_store [ incompatible] . name ( )
2440
2428
{
2441
2429
// Don't track conflicts between a marker package and the main package, when the
2442
2430
// marker is "copying" the obligations from the main package through conflicts.
@@ -2446,21 +2434,21 @@ impl ForkState {
2446
2434
let culprit_count = self
2447
2435
. conflict_tracker
2448
2436
. culprit
2449
- . entry ( * incompatible)
2437
+ . entry ( incompatible)
2450
2438
. or_default ( ) ;
2451
2439
* culprit_count += 1 ;
2452
2440
if * culprit_count == CONFLICT_THRESHOLD {
2453
- self . conflict_tracker . depriotize . push ( * incompatible) ;
2441
+ self . conflict_tracker . depriotize . push ( incompatible) ;
2454
2442
}
2455
2443
}
2456
2444
// Don't track conflicts between a marker package and the main package, when the
2457
2445
// marker is "copying" the obligations from the main package through conflicts.
2458
2446
if culprit_is_real {
2459
2447
if tracing:: enabled!( Level :: DEBUG ) {
2460
- let incompatibility = conflict
2448
+ let incompatibility = self . pubgrub . incompatibility_store [ incompatibility ]
2461
2449
. iter ( )
2462
2450
. map ( |( package, _term) | {
2463
- format ! ( "{:?}" , self . pubgrub. package_store[ * package] . clone( ) , )
2451
+ format ! ( "{:?}" , self . pubgrub. package_store[ package] . clone( ) , )
2464
2452
} )
2465
2453
. join ( ", " ) ;
2466
2454
if let Some ( version) = version {
0 commit comments