Skip to content

Commit 8080c98

Browse files
committed
add the original optimization in for good measure
1 parent c0be9ce commit 8080c98

File tree

1 file changed

+43
-7
lines changed

1 file changed

+43
-7
lines changed

src/cargo/core/resolver/mod.rs

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ fn activate_deps_loop(
288288
&cx,
289289
registry,
290290
&mut past_conflicting_activations,
291+
&parent,
291292
&dep,
292293
&conflicting_activations,
293294
) {
@@ -854,10 +855,11 @@ fn generalize_conflicting(
854855
cx: &Context,
855856
registry: &mut RegistryQueryer<'_>,
856857
past_conflicting_activations: &mut conflict_cache::ConflictCache,
858+
parent: &Summary,
857859
dep: &Dependency,
858860
conflicting_activations: &ConflictMap,
859861
) -> Option<ConflictMap> {
860-
if conflicting_activations.len() != 1 {
862+
if conflicting_activations.is_empty() {
861863
return None;
862864
}
863865
// We need to determine the `ContextAge` that this `conflicting_activations` will jump to, and why.
@@ -869,6 +871,16 @@ fn generalize_conflicting(
869871
let backtrack_critical_reason: ConflictReason =
870872
conflicting_activations[&backtrack_critical_id].clone();
871873

874+
if cx
875+
.parents
876+
.is_path_from_to(&parent.package_id(), &backtrack_critical_id)
877+
{
878+
// We are a descendant of the trigger of the problem.
879+
// The best generalization of this is to let things bubble up
880+
// and let `backtrack_critical_id` figure this out.
881+
return None;
882+
}
883+
872884
// we will need to know the range of versions we can use
873885
let our_candidates = registry
874886
.query(dep)
@@ -905,10 +917,6 @@ fn generalize_conflicting(
905917
None
906918
};
907919

908-
if !(our_activation_key.is_some() || our_link.is_some()) {
909-
return None;
910-
}
911-
912920
let our_candidates: HashSet<PackageId> =
913921
our_candidates.iter().map(|our| our.package_id()).collect();
914922

@@ -920,6 +928,9 @@ fn generalize_conflicting(
920928
})
921929
{
922930
'dep: for critical_parents_dep in critical_parents_deps.iter() {
931+
// A dep is equivalent to one of the things it can resolve to.
932+
// Thus, if all the things it can resolve to have already ben determined
933+
// to be conflicting, then we can just say that we conflict with the parent.
923934
let mut con = conflicting_activations.clone();
924935
con.remove(&backtrack_critical_id);
925936
con.insert(*critical_parent, backtrack_critical_reason.clone());
@@ -928,6 +939,8 @@ fn generalize_conflicting(
928939
.query(critical_parents_dep)
929940
.expect("an already used dep now error!?")
930941
.iter()
942+
.rev()
943+
// the last one to be tried is the least likely to be in the cache, so start with that.
931944
{
932945
if (our_activation_key
933946
.map_or(false, |our| other.package_id().as_activations_key() == our)
@@ -950,9 +963,32 @@ fn generalize_conflicting(
950963
) {
951964
con.extend(conflicting.into_iter());
952965
continue;
953-
} else {
954-
continue 'dep;
955966
}
967+
968+
if let Some(conflicting) = past_conflicting_activations.find(
969+
dep,
970+
&|id| {
971+
if id == other.package_id() {
972+
// we are imagining that we used other instead
973+
Some(backtrack_critical_age)
974+
} else {
975+
cx.is_active(id).filter(|&age|
976+
// we only care about things that are older then critical_age
977+
age < backtrack_critical_age)
978+
}
979+
},
980+
Some(other.package_id()),
981+
) {
982+
con.extend(
983+
conflicting
984+
.iter()
985+
.filter(|(&id, _)| id != other.package_id())
986+
.map(|(&id, r)| (id, r.clone())),
987+
);
988+
continue;
989+
}
990+
991+
continue 'dep;
956992
}
957993

958994
if cfg!(debug_assertions) {

0 commit comments

Comments
 (0)