Skip to content

Commit 70c59ef

Browse files
committed
We have more then one conflict that matches, so pick one with the max back-jumping.
1 parent 0f1791b commit 70c59ef

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

src/cargo/core/resolver/conflict_cache.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,21 @@ enum ConflictStoreTrie {
1818

1919
impl ConflictStoreTrie {
2020
/// Finds any known set of conflicts, if any,
21-
/// which are activated in `cx` and pass the `filter` specified?
21+
/// which are activated in `cx` and contain `PackageId` specified.
22+
/// If more then one are activated, then it will return
23+
/// one that will allow for the most jump-back.
2224
fn find_conflicting(
2325
&self,
2426
cx: &Context,
2527
must_contain: Option<PackageId>,
26-
) -> Option<&ConflictMap> {
28+
) -> Option<(&ConflictMap, usize)> {
2729
match self {
2830
ConflictStoreTrie::Leaf(c) => {
2931
if must_contain.is_none() {
3032
// `is_conflicting` checks that all the elements are active,
3133
// but we have checked each one by the recursion of this function.
3234
debug_assert!(cx.is_conflicting(None, c).is_some());
33-
Some(c)
35+
Some((c, 0))
3436
} else {
3537
// We did not find `must_contain`, so we need to keep looking.
3638
None
@@ -43,11 +45,22 @@ impl ConflictStoreTrie {
4345
.unwrap_or_else(|| m.range(..))
4446
{
4547
// If the key is active, then we need to check all of the corresponding subtrie.
46-
if cx.is_active(pid).is_some() {
47-
if let Some(o) =
48+
if let Some(age_this) = cx.is_active(pid) {
49+
if let Some((o, age_o)) =
4850
store.find_conflicting(cx, must_contain.filter(|&f| f != pid))
4951
{
50-
assert!(out.replace(o).is_none());
52+
let age = if must_contain == Some(pid) {
53+
// all the results will include `must_contain`
54+
// so the age of must_contain is not relevant to find the best result.
55+
age_o
56+
} else {
57+
std::cmp::max(age_this, age_o)
58+
};
59+
let out_age = out.get_or_insert((o, age)).1;
60+
if out_age > age {
61+
// we found one that can jump-back further so replace the out.
62+
out = Some((o, age));
63+
}
5164
}
5265
}
5366
// Else, if it is not active then there is no way any of the corresponding
@@ -138,7 +151,9 @@ impl ConflictCache {
138151
}
139152
}
140153
/// Finds any known set of conflicts, if any,
141-
/// which are activated in `cx` and pass the `filter` specified?
154+
/// which are activated in `cx` and contain `PackageId` specified.
155+
/// If more then one are activated, then it will return
156+
/// one that will allow for the most jump-back.
142157
pub fn find_conflicting(
143158
&self,
144159
cx: &Context,
@@ -148,7 +163,8 @@ impl ConflictCache {
148163
let out = self
149164
.con_from_dep
150165
.get(dep)?
151-
.find_conflicting(cx, must_contain);
166+
.find_conflicting(cx, must_contain)
167+
.map(|(c, _)| c);
152168
if cfg!(debug_assertions) {
153169
if let Some(f) = must_contain {
154170
if let Some(c) = &out {

0 commit comments

Comments
 (0)