@@ -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;
@@ -328,17 +328,9 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
328
328
loop {
329
329
// Run unit propagation.
330
330
let result = state. pubgrub . unit_propagation ( state. next ) ;
331
- // End the mutable borrow of `state.pubgrub`.
332
- let result = result. map ( |conflict| {
333
- conflict. map ( |conflict| {
334
- conflict
335
- . map ( |( package, term) | ( package, term. clone ( ) ) )
336
- . collect :: < Vec < _ > > ( )
337
- } )
338
- } ) ;
339
331
match result {
340
332
Err ( err) => {
341
- // If unit propagation failed, the is no solution.
333
+ // If unit propagation failed, there is no solution.
342
334
return Err ( self . convert_no_solution_err (
343
335
err,
344
336
state. fork_urls ,
@@ -349,14 +341,13 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
349
341
& self . capabilities ,
350
342
) ) ;
351
343
}
352
- Ok ( Some ( conflict) ) => {
353
- // Conflict tracking: If the version was rejected due to its dependencies,
354
- // record culprit and affected.
355
- state. record_conflict ( state. next , None , & conflict) ;
344
+ Ok ( conflicts) => {
345
+ for ( affected, incompatibility) in conflicts {
346
+ // Conflict tracking: If there was a conflict, track affected and
347
+ // culprit for all root cause incompatibilities
348
+ state. record_conflict ( affected, None , incompatibility) ;
349
+ }
356
350
}
357
- // There was no conflict, or we've already rejected the last version due to its
358
- // dependencies.
359
- Ok ( None ) => { }
360
351
}
361
352
362
353
// Pre-visit all candidate packages, to allow metadata to be fetched in parallel.
@@ -2351,14 +2342,11 @@ impl ForkState {
2351
2342
( package, version)
2352
2343
} ) ,
2353
2344
) ;
2354
- // End the mutable borrow of `self.pubgrub`
2355
- let conflict: Option < Vec < _ > > =
2356
- conflict. map ( |x| x. map ( |( package, term) | ( package, term. clone ( ) ) ) . collect ( ) ) ;
2357
2345
2358
2346
// Conflict tracking: If the version was rejected due to its dependencies, record culprit
2359
2347
// and affected.
2360
- if let Some ( conflict ) = conflict {
2361
- self . record_conflict ( for_package, Some ( for_version) , & conflict ) ;
2348
+ if let Some ( incompatibility ) = conflict {
2349
+ self . record_conflict ( for_package, Some ( for_version) , incompatibility ) ;
2362
2350
}
2363
2351
Ok ( ( ) )
2364
2352
}
@@ -2367,15 +2355,15 @@ impl ForkState {
2367
2355
& mut self ,
2368
2356
affected : Id < PubGrubPackage > ,
2369
2357
version : Option < & Version > ,
2370
- conflict : & [ ( Id < PubGrubPackage > , Term < Ranges < Version > > ) ] ,
2358
+ incompatibility : IncompId < PubGrubPackage , Ranges < Version > , UnavailableReason > ,
2371
2359
) {
2372
2360
let mut culprit_is_real = false ;
2373
- for ( incompatible, _term) in conflict {
2374
- if * incompatible == affected {
2361
+ for ( incompatible, _term) in self . pubgrub . incompatibility_store [ incompatibility ] . iter ( ) {
2362
+ if incompatible == affected {
2375
2363
continue ;
2376
2364
}
2377
2365
if self . pubgrub . package_store [ affected] . name ( )
2378
- == self . pubgrub . package_store [ * incompatible] . name ( )
2366
+ == self . pubgrub . package_store [ incompatible] . name ( )
2379
2367
{
2380
2368
// Don't track conflicts between a marker package and the main package, when the
2381
2369
// marker is "copying" the obligations from the main package through conflicts.
@@ -2385,21 +2373,21 @@ impl ForkState {
2385
2373
let culprit_count = self
2386
2374
. conflict_tracker
2387
2375
. culprit
2388
- . entry ( * incompatible)
2376
+ . entry ( incompatible)
2389
2377
. or_default ( ) ;
2390
2378
* culprit_count += 1 ;
2391
2379
if * culprit_count == CONFLICT_THRESHOLD {
2392
- self . conflict_tracker . depriotize . push ( * incompatible) ;
2380
+ self . conflict_tracker . depriotize . push ( incompatible) ;
2393
2381
}
2394
2382
}
2395
2383
// Don't track conflicts between a marker package and the main package, when the
2396
2384
// marker is "copying" the obligations from the main package through conflicts.
2397
2385
if culprit_is_real {
2398
2386
if tracing:: enabled!( Level :: DEBUG ) {
2399
- let incompatibility = conflict
2387
+ let incompatibility = self . pubgrub . incompatibility_store [ incompatibility ]
2400
2388
. iter ( )
2401
2389
. map ( |( package, _term) | {
2402
- format ! ( "{:?}" , self . pubgrub. package_store[ * package] . clone( ) , )
2390
+ format ! ( "{:?}" , self . pubgrub. package_store[ package] . clone( ) , )
2403
2391
} )
2404
2392
. join ( ", " ) ;
2405
2393
if let Some ( version) = version {
0 commit comments