@@ -137,7 +137,7 @@ pub fn resolve(
137
137
let cx = activate_deps_loop ( cx, & mut registry, summaries, config) ?;
138
138
139
139
let mut cksums = HashMap :: new ( ) ;
140
- for summary in cx. activations . values ( ) {
140
+ for ( summary, _ ) in cx. activations . values ( ) {
141
141
let cksum = summary. checksum ( ) . map ( |s| s. to_string ( ) ) ;
142
142
cksums. insert ( summary. package_id ( ) , cksum) ;
143
143
}
@@ -302,6 +302,7 @@ fn activate_deps_loop(
302
302
}
303
303
304
304
match find_candidate (
305
+ & cx,
305
306
& mut backtrack_stack,
306
307
& parent,
307
308
backtracked,
@@ -493,6 +494,7 @@ fn activate_deps_loop(
493
494
let activate_for_error_message = has_past_conflicting_dep && !has_another && {
494
495
just_here_for_the_error_messages || {
495
496
find_candidate (
497
+ & cx,
496
498
& mut backtrack_stack. clone ( ) ,
497
499
& parent,
498
500
backtracked,
@@ -777,7 +779,7 @@ impl RemainingCandidates {
777
779
//
778
780
// Here we throw out our candidate if it's *compatible*, yet not
779
781
// equal, to all previously activated versions.
780
- if let Some ( a ) = cx. activations . get ( & b_id. as_activations_key ( ) ) {
782
+ if let Some ( ( a , _ ) ) = cx. activations . get ( & b_id. as_activations_key ( ) ) {
781
783
if * a != b. summary {
782
784
conflicting_prev_active
783
785
. entry ( a. package_id ( ) )
@@ -850,11 +852,33 @@ impl RemainingCandidates {
850
852
/// Read <https://github.com/rust-lang/cargo/pull/4834>
851
853
/// For several more detailed explanations of the logic here.
852
854
fn find_candidate (
855
+ cx : & Context ,
853
856
backtrack_stack : & mut Vec < BacktrackFrame > ,
854
857
parent : & Summary ,
855
858
backtracked : bool ,
856
859
conflicting_activations : & ConflictMap ,
857
860
) -> Option < ( Candidate , bool , BacktrackFrame ) > {
861
+ // When we're calling this method we know that `parent` failed to
862
+ // activate. That means that some dependency failed to get resolved for
863
+ // whatever reason. Normally, that means that all of those reasons
864
+ // (plus maybe some extras) are listed in `conflicting_activations`.
865
+ //
866
+ // The abnormal situations are things that do not put all of the reasons in `conflicting_activations`:
867
+ // If we backtracked we do not know how our `conflicting_activations` related to
868
+ // the cause of that backtrack, so we do not update it.
869
+ // If we had a PublicDependency conflict, then we do not yet have a compact way to
870
+ // represent all the parts of the problem, so `conflicting_activations` is incomplete.
871
+ let age = if !backtracked
872
+ && !conflicting_activations
873
+ . values ( )
874
+ . any ( |c| * c == ConflictReason :: PublicDependency )
875
+ {
876
+ // we dont have abnormal situations. So we can ask `cx` for how far back we need to go.
877
+ cx. is_conflicting ( Some ( parent. package_id ( ) ) , conflicting_activations)
878
+ } else {
879
+ None
880
+ } ;
881
+
858
882
while let Some ( mut frame) = backtrack_stack. pop ( ) {
859
883
let next = frame. remaining_candidates . next (
860
884
& mut frame. conflicting_activations ,
@@ -866,37 +890,37 @@ fn find_candidate(
866
890
Some ( pair) => pair,
867
891
None => continue ,
868
892
} ;
869
- // When we're calling this method we know that `parent` failed to
870
- // activate. That means that some dependency failed to get resolved for
871
- // whatever reason. Normally, that means that all of those reasons
872
- // (plus maybe some extras) are listed in `conflicting_activations`.
873
- //
874
- // This means that if all members of `conflicting_activations` are still
893
+
894
+ // If all members of `conflicting_activations` are still
875
895
// active in this back up we know that we're guaranteed to not actually
876
896
// make any progress. As a result if we hit this condition we can
877
897
// completely skip this backtrack frame and move on to the next.
878
- //
879
- // The abnormal situations are things that do not put all of the reasons in `conflicting_activations`:
880
- // If we backtracked we do not know how our `conflicting_activations` related to
881
- // the cause of that backtrack, so we do not update it.
882
- // If we had a PublicDependency conflict, then we do not yet have a compact way to
883
- // represent all the parts of the problem, so `conflicting_activations` is incomplete.
884
- if !backtracked
885
- && !conflicting_activations
886
- . values ( )
887
- . any ( |c| * c == ConflictReason :: PublicDependency )
888
- && frame
889
- . context
890
- . is_conflicting ( Some ( parent. package_id ( ) ) , conflicting_activations)
891
- {
892
- trace ! (
893
- "{} = \" {}\" skip as not solving {}: {:?}" ,
894
- frame. dep. package_name( ) ,
895
- frame. dep. version_req( ) ,
896
- parent. package_id( ) ,
897
- conflicting_activations
898
- ) ;
899
- continue ;
898
+ if let Some ( age) = age {
899
+ if frame. context . activations . len ( ) > age {
900
+ trace ! (
901
+ "{} = \" {}\" skip as not solving {}: {:?}" ,
902
+ frame. dep. package_name( ) ,
903
+ frame. dep. version_req( ) ,
904
+ parent. package_id( ) ,
905
+ conflicting_activations
906
+ ) ;
907
+ // above we use `cx` to determine that this is still going to be conflicting.
908
+ // but lets just double check.
909
+ debug_assert ! (
910
+ frame
911
+ . context
912
+ . is_conflicting( Some ( parent. package_id( ) ) , conflicting_activations)
913
+ == Some ( age)
914
+ ) ;
915
+ continue ;
916
+ } else {
917
+ // above we use `cx` to determine that this is not going to be conflicting.
918
+ // but lets just double check.
919
+ debug_assert ! ( frame
920
+ . context
921
+ . is_conflicting( Some ( parent. package_id( ) ) , conflicting_activations)
922
+ . is_none( ) ) ;
923
+ }
900
924
}
901
925
902
926
return Some ( ( candidate, has_another, frame) ) ;
@@ -905,8 +929,10 @@ fn find_candidate(
905
929
}
906
930
907
931
fn check_cycles ( resolve : & Resolve , activations : & Activations ) -> CargoResult < ( ) > {
908
- let summaries: HashMap < PackageId , & Summary > =
909
- activations. values ( ) . map ( |s| ( s. package_id ( ) , s) ) . collect ( ) ;
932
+ let summaries: HashMap < PackageId , & Summary > = activations
933
+ . values ( )
934
+ . map ( |( s, _) | ( s. package_id ( ) , s) )
935
+ . collect ( ) ;
910
936
911
937
// Sort packages to produce user friendly deterministic errors.
912
938
let mut all_packages: Vec < _ > = resolve. iter ( ) . collect ( ) ;
0 commit comments