@@ -54,9 +54,9 @@ use std::time::{Duration, Instant};
54
54
55
55
use semver;
56
56
57
- use core:: { Dependency , PackageId , Registry , Summary } ;
58
- use core:: PackageIdSpec ;
59
57
use core:: interning:: InternedString ;
58
+ use core:: PackageIdSpec ;
59
+ use core:: { Dependency , PackageId , Registry , Summary } ;
60
60
use util:: config:: Config ;
61
61
use util:: errors:: { CargoError , CargoResult } ;
62
62
use util:: profile;
@@ -70,9 +70,9 @@ pub use self::encode::{Metadata, WorkspaceResolve};
70
70
pub use self :: resolve:: { Deps , DepsNotReplaced , Resolve } ;
71
71
pub use self :: types:: Method ;
72
72
73
+ mod conflict_cache;
73
74
mod context;
74
75
mod encode;
75
- mod conflict_cache;
76
76
mod resolve;
77
77
mod types;
78
78
@@ -293,9 +293,9 @@ fn activate_deps_loop(
293
293
let mut backtracked = false ;
294
294
295
295
loop {
296
- let next = remaining_candidates. next ( & cx, & dep) ;
296
+ let next = remaining_candidates. next ( & mut conflicting_activations , & cx, & dep) ;
297
297
298
- let ( candidate, has_another) = next. or_else ( |conflicting | {
298
+ let ( candidate, has_another) = next. ok_or ( ( ) ) . or_else ( |_ | {
299
299
// If we get here then our `remaining_candidates` was just
300
300
// exhausted, so `dep` failed to activate.
301
301
//
@@ -304,10 +304,6 @@ fn activate_deps_loop(
304
304
// candidates whatsoever then it's time to bail entirely.
305
305
trace ! ( "{}[{}]>{} -- no candidates" , parent. name( ) , cur, dep. name( ) ) ;
306
306
307
- // Add all the reasons to our frame's list of conflicting
308
- // activations, as we may use this to start backtracking later.
309
- conflicting_activations. extend ( conflicting) ;
310
-
311
307
// Use our list of `conflicting_activations` to add to our
312
308
// global list of past conflicting activations, effectively
313
309
// globally poisoning `dep` if `conflicting_activations` ever
@@ -402,13 +398,7 @@ fn activate_deps_loop(
402
398
dep. name( ) ,
403
399
candidate. summary. version( )
404
400
) ;
405
- let res = activate (
406
- & mut cx,
407
- registry,
408
- Some ( ( & parent, & dep) ) ,
409
- candidate,
410
- & method,
411
- ) ;
401
+ let res = activate ( & mut cx, registry, Some ( ( & parent, & dep) ) , candidate, & method) ;
412
402
413
403
let successfully_activated = match res {
414
404
// Success! We've now activated our `candidate` in our context
@@ -522,8 +512,6 @@ fn activate_deps_loop(
522
512
// we'll want to present an error message for sure.
523
513
let activate_for_error_message = has_past_conflicting_dep && !has_another && {
524
514
just_here_for_the_error_messages || {
525
- conflicting_activations
526
- . extend ( remaining_candidates. conflicting_prev_active . clone ( ) ) ;
527
515
find_candidate (
528
516
& mut backtrack_stack. clone ( ) ,
529
517
& parent,
@@ -692,13 +680,10 @@ struct BacktrackFrame {
692
680
/// is defined within a `Context`.
693
681
///
694
682
/// Candidates passed to `new` may not be returned from `next` as they could be
695
- /// filtered out, and if iteration stops a map of all packages which caused
696
- /// filtered out candidates to be filtered out will be returned.
683
+ /// filtered out, and as they are filtered the causes will be added to `conflicting_prev_active`.
697
684
#[ derive( Clone ) ]
698
685
struct RemainingCandidates {
699
686
remaining : RcVecIter < Candidate > ,
700
- // note: change to RcList or something if clone is to expensive
701
- conflicting_prev_active : HashMap < PackageId , ConflictReason > ,
702
687
// This is a inlined peekable generator
703
688
has_another : Option < Candidate > ,
704
689
}
@@ -707,7 +692,6 @@ impl RemainingCandidates {
707
692
fn new ( candidates : & Rc < Vec < Candidate > > ) -> RemainingCandidates {
708
693
RemainingCandidates {
709
694
remaining : RcVecIter :: new ( Rc :: clone ( candidates) ) ,
710
- conflicting_prev_active : HashMap :: new ( ) ,
711
695
has_another : None ,
712
696
}
713
697
}
@@ -730,9 +714,10 @@ impl RemainingCandidates {
730
714
/// original list for the reason listed.
731
715
fn next (
732
716
& mut self ,
717
+ conflicting_prev_active : & mut HashMap < PackageId , ConflictReason > ,
733
718
cx : & Context ,
734
719
dep : & Dependency ,
735
- ) -> Result < ( Candidate , bool ) , HashMap < PackageId , ConflictReason > > {
720
+ ) -> Option < ( Candidate , bool ) > {
736
721
let prev_active = cx. prev_active ( dep) ;
737
722
738
723
for ( _, b) in self . remaining . by_ref ( ) {
@@ -743,9 +728,9 @@ impl RemainingCandidates {
743
728
if let Some ( link) = b. summary . links ( ) {
744
729
if let Some ( a) = cx. links . get ( & link) {
745
730
if a != b. summary . package_id ( ) {
746
- self . conflicting_prev_active
731
+ conflicting_prev_active
747
732
. entry ( a. clone ( ) )
748
- . or_insert_with ( || ConflictReason :: Links ( link. to_string ( ) ) ) ;
733
+ . or_insert ( ConflictReason :: Links ( link) ) ;
749
734
continue ;
750
735
}
751
736
}
@@ -764,7 +749,7 @@ impl RemainingCandidates {
764
749
. find ( |a| compatible ( a. version ( ) , b. summary . version ( ) ) )
765
750
{
766
751
if * a != b. summary {
767
- self . conflicting_prev_active
752
+ conflicting_prev_active
768
753
. entry ( a. package_id ( ) . clone ( ) )
769
754
. or_insert ( ConflictReason :: Semver ) ;
770
755
continue ;
@@ -777,21 +762,14 @@ impl RemainingCandidates {
777
762
// get returned later, and if we replaced something then that was
778
763
// actually the candidate to try first so we return that.
779
764
if let Some ( r) = mem:: replace ( & mut self . has_another , Some ( b) ) {
780
- return Ok ( ( r, true ) ) ;
765
+ return Some ( ( r, true ) ) ;
781
766
}
782
767
}
783
768
784
769
// Alright we've entirely exhausted our list of candidates. If we've got
785
770
// something stashed away return that here (also indicating that there's
786
- // nothing else). If nothing is stashed away we return the list of all
787
- // conflicting activations, if any.
788
- //
789
- // TODO: can the `conflicting_prev_active` clone be avoided here? should
790
- // panic if this is called twice and an error is already returned
791
- self . has_another
792
- . take ( )
793
- . map ( |r| ( r, false ) )
794
- . ok_or_else ( || self . conflicting_prev_active . clone ( ) )
771
+ // nothing else).
772
+ self . has_another . take ( ) . map ( |r| ( r, false ) )
795
773
}
796
774
}
797
775
@@ -831,12 +809,14 @@ fn find_candidate(
831
809
conflicting_activations : & HashMap < PackageId , ConflictReason > ,
832
810
) -> Option < ( Candidate , bool , BacktrackFrame ) > {
833
811
while let Some ( mut frame) = backtrack_stack. pop ( ) {
834
- let next = frame
835
- . remaining_candidates
836
- . next ( & frame. context_backup , & frame. dep ) ;
812
+ let next = frame. remaining_candidates . next (
813
+ & mut frame. conflicting_activations ,
814
+ & frame. context_backup ,
815
+ & frame. dep ,
816
+ ) ;
837
817
let ( candidate, has_another) = match next {
838
- Ok ( pair) => pair,
839
- Err ( _ ) => continue ,
818
+ Some ( pair) => pair,
819
+ None => continue ,
840
820
} ;
841
821
// When we're calling this method we know that `parent` failed to
842
822
// activate. That means that some dependency failed to get resolved for
0 commit comments