@@ -62,7 +62,7 @@ use crate::util::errors::CargoResult;
62
62
use crate :: util:: profile;
63
63
64
64
use self :: context:: { Activations , Context } ;
65
- use self :: types:: { Candidate , Conflict , ConflictReason , DepsFrame , GraphNode } ;
65
+ use self :: types:: { Candidate , ConflictMap , ConflictReason , DepsFrame , GraphNode } ;
66
66
use self :: types:: { RcVecIter , RegistryQueryer , RemainingDeps , ResolverProgress } ;
67
67
68
68
pub use self :: encode:: { EncodableDependency , EncodablePackageId , EncodableResolve } ;
@@ -247,7 +247,7 @@ fn activate_deps_loop(
247
247
//
248
248
// This is a map of package ID to a reason why that packaged caused a
249
249
// conflict for us.
250
- let mut conflicting_activations = Conflict :: new ( ) ;
250
+ let mut conflicting_activations = ConflictMap :: new ( ) ;
251
251
252
252
// When backtracking we don't fully update `conflicting_activations`
253
253
// especially for the cases that we didn't make a backtrack frame in the
@@ -590,28 +590,28 @@ fn activate(
590
590
candidate : Candidate ,
591
591
method : & Method < ' _ > ,
592
592
) -> ActivateResult < Option < ( DepsFrame , Duration ) > > {
593
+ let candidate_pid = candidate. summary . package_id ( ) ;
593
594
if let Some ( ( parent, dep) ) = parent {
594
- cx. resolve_graph . push ( GraphNode :: Link (
595
- parent. package_id ( ) ,
596
- candidate. summary . package_id ( ) ,
597
- dep. clone ( ) ,
598
- ) ) ;
595
+ let parent_pid = parent. package_id ( ) ;
596
+ cx. resolve_graph
597
+ . push ( GraphNode :: Link ( parent_pid, candidate_pid, dep. clone ( ) ) ) ;
599
598
Rc :: make_mut (
600
- cx . parents
601
- . link ( candidate . summary . package_id ( ) , parent . package_id ( ) ) ,
599
+ // add a edge from candidate to parent in the parents graph
600
+ cx . parents . link ( candidate_pid , parent_pid ) ,
602
601
)
602
+ // and associate dep with that edge
603
603
. push ( dep. clone ( ) ) ;
604
604
let cs: Vec < PackageId > = cx
605
605
. public_dependency
606
- . get ( & candidate . summary . package_id ( ) )
606
+ . get ( & candidate_pid )
607
607
. iter ( )
608
608
. flat_map ( |x| x. values ( ) )
609
609
. filter_map ( |x| if x. 1 { Some ( & x. 0 ) } else { None } )
610
- . chain ( Some ( candidate . summary . package_id ( ) ) . iter ( ) )
610
+ . chain ( & Some ( candidate_pid ) )
611
611
. cloned ( )
612
612
. collect ( ) ;
613
613
for c in cs {
614
- let mut stack = vec ! [ ( parent . package_id ( ) , dep. is_public( ) ) ] ;
614
+ let mut stack = vec ! [ ( parent_pid , dep. is_public( ) ) ] ;
615
615
while let Some ( ( p, public) ) = stack. pop ( ) {
616
616
match cx. public_dependency . entry ( p) . or_default ( ) . entry ( c. name ( ) ) {
617
617
im_rc:: hashmap:: Entry :: Occupied ( mut o) => {
@@ -641,22 +641,22 @@ fn activate(
641
641
let candidate = match candidate. replace {
642
642
Some ( replace) => {
643
643
cx. resolve_replacements
644
- . push ( ( candidate . summary . package_id ( ) , replace. package_id ( ) ) ) ;
644
+ . push ( ( candidate_pid , replace. package_id ( ) ) ) ;
645
645
if cx. flag_activated ( & replace, method) ? && activated {
646
646
return Ok ( None ) ;
647
647
}
648
648
trace ! (
649
649
"activating {} (replacing {})" ,
650
650
replace. package_id( ) ,
651
- candidate . summary . package_id ( )
651
+ candidate_pid
652
652
) ;
653
653
replace
654
654
}
655
655
None => {
656
656
if activated {
657
657
return Ok ( None ) ;
658
658
}
659
- trace ! ( "activating {}" , candidate . summary . package_id ( ) ) ;
659
+ trace ! ( "activating {}" , candidate_pid ) ;
660
660
candidate. summary
661
661
}
662
662
} ;
@@ -680,7 +680,7 @@ struct BacktrackFrame {
680
680
parent : Summary ,
681
681
dep : Dependency ,
682
682
features : Rc < Vec < InternedString > > ,
683
- conflicting_activations : Conflict ,
683
+ conflicting_activations : ConflictMap ,
684
684
}
685
685
686
686
/// A helper "iterator" used to extract candidates within a current `Context` of
@@ -727,7 +727,7 @@ impl RemainingCandidates {
727
727
/// original list for the reason listed.
728
728
fn next (
729
729
& mut self ,
730
- conflicting_prev_active : & mut Conflict ,
730
+ conflicting_prev_active : & mut ConflictMap ,
731
731
cx : & Context ,
732
732
dep : & Dependency ,
733
733
parent : PackageId ,
@@ -769,13 +769,18 @@ impl RemainingCandidates {
769
769
continue ;
770
770
}
771
771
}
772
+ // We may still have to reject do to a public dependency conflict. If one of any of our
773
+ // ancestors that can see us already knows about a different crate with this name then
774
+ // we have to reject this candidate. Additionally this candidate may already have been
775
+ // activated and have public dependants of its own,
776
+ // all of witch also need to be checked the same way.
772
777
for & t in cx
773
778
. public_dependency
774
779
. get ( & b. summary . package_id ( ) )
775
780
. iter ( )
776
781
. flat_map ( |x| x. values ( ) )
777
782
. filter_map ( |x| if x. 1 { Some ( & x. 0 ) } else { None } )
778
- . chain ( Some ( b. summary . package_id ( ) ) . iter ( ) )
783
+ . chain ( & Some ( b. summary . package_id ( ) ) )
779
784
{
780
785
let mut stack = vec ! [ ( parent, dep. is_public( ) ) ] ;
781
786
while let Some ( ( p, public) ) = stack. pop ( ) {
@@ -845,7 +850,7 @@ fn find_candidate(
845
850
backtrack_stack : & mut Vec < BacktrackFrame > ,
846
851
parent : & Summary ,
847
852
backtracked : bool ,
848
- conflicting_activations : & Conflict ,
853
+ conflicting_activations : & ConflictMap ,
849
854
) -> Option < ( Candidate , bool , BacktrackFrame ) > {
850
855
while let Some ( mut frame) = backtrack_stack. pop ( ) {
851
856
let next = frame. remaining_candidates . next (
@@ -860,13 +865,19 @@ fn find_candidate(
860
865
} ;
861
866
// When we're calling this method we know that `parent` failed to
862
867
// activate. That means that some dependency failed to get resolved for
863
- // whatever reason, and all of those reasons (plus maybe some extras)
864
- // are listed in `conflicting_activations`.
868
+ // whatever reason. Normally, that means that all of those reasons
869
+ // (plus maybe some extras) are listed in `conflicting_activations`.
865
870
//
866
871
// This means that if all members of `conflicting_activations` are still
867
872
// active in this back up we know that we're guaranteed to not actually
868
873
// make any progress. As a result if we hit this condition we can
869
874
// completely skip this backtrack frame and move on to the next.
875
+ //
876
+ // The abnormal situations are things that do not put all of the reasons in `conflicting_activations`:
877
+ // If we backtracked we do not know how our `conflicting_activations` related to
878
+ // the cause of that backtrack, so we do not update it.
879
+ // If we had a PublicDependency conflict, then we do not yet have a compact way to
880
+ // represent all the parts of the problem, so `conflicting_activations` is incomplete.
870
881
if !backtracked
871
882
&& !conflicting_activations
872
883
. values ( )
0 commit comments