Skip to content

Commit aeaf3f7

Browse files
epagelinyihai
authored andcommitted
fix(resolver): Prefer MSRV, rather than ignore incompatible
This is another experiment for rust-lang#9930. Comparing preferring over exclusively using MSRV compatible: Benefits - Better error messages - `--ignore-rust-version` is implicitly sticky Downsides - Can't backtrack for MSRV compatible version - Still requires workspace-wide MSRV (compared to our desired end state of declaring MSRV as yet another dependency) This builds on rust-lang#12930
1 parent 18d3397 commit aeaf3f7

File tree

4 files changed

+20
-41
lines changed

4 files changed

+20
-41
lines changed

src/cargo/core/resolver/version_prefs.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ impl VersionPreferences {
5858
///
5959
/// Sort order:
6060
/// 1. Preferred packages
61-
/// 2. `first_version`, falling back to [`VersionPreferences::version_ordering`] when `None`
61+
/// 2. [`VersionPreferences::max_rust_version`]
62+
/// 3. `first_version`, falling back to [`VersionPreferences::version_ordering`] when `None`
6263
///
6364
/// Filtering:
64-
/// - [`VersionPreferences::max_rust_version`]
6565
/// - `first_version`
6666
pub fn sort_summaries(
6767
&self,
@@ -76,9 +76,6 @@ impl VersionPreferences {
7676
.map(|deps| deps.iter().any(|d| d.matches_id(*pkg_id)))
7777
.unwrap_or(false)
7878
};
79-
if self.max_rust_version.is_some() {
80-
summaries.retain(|s| s.rust_version() <= self.max_rust_version.as_ref());
81-
}
8279
summaries.sort_unstable_by(|a, b| {
8380
let prefer_a = should_prefer(&a.package_id());
8481
let prefer_b = should_prefer(&b.package_id());
@@ -87,6 +84,15 @@ impl VersionPreferences {
8784
return previous_cmp;
8885
}
8986

87+
if self.max_rust_version.is_some() {
88+
let msrv_a = a.rust_version() <= self.max_rust_version.as_ref();
89+
let msrv_b = b.rust_version() <= self.max_rust_version.as_ref();
90+
let msrv_cmp = msrv_a.cmp(&msrv_b).reverse();
91+
if msrv_cmp != Ordering::Equal {
92+
return msrv_cmp;
93+
}
94+
}
95+
9096
let cmp = a.version().cmp(b.version());
9197
match first_version.unwrap_or(self.version_ordering) {
9298
VersionOrdering::MaximumVersionsFirst => cmp.reverse(),
@@ -236,14 +242,14 @@ mod test {
236242
vp.sort_summaries(&mut summaries, None);
237243
assert_eq!(
238244
describe(&summaries),
239-
"foo/1.2.3, foo/1.1.0, foo/1.0.9".to_string()
245+
"foo/1.2.3, foo/1.1.0, foo/1.0.9, foo/1.2.4".to_string()
240246
);
241247

242248
vp.version_ordering(VersionOrdering::MinimumVersionsFirst);
243249
vp.sort_summaries(&mut summaries, None);
244250
assert_eq!(
245251
describe(&summaries),
246-
"foo/1.0.9, foo/1.1.0, foo/1.2.3".to_string()
252+
"foo/1.0.9, foo/1.1.0, foo/1.2.3, foo/1.2.4".to_string()
247253
);
248254
}
249255
}

tests/testsuite/cargo_add/rust_version_ignore/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn case() {
2626
.current_dir(cwd)
2727
.masquerade_as_nightly_cargo(&["msrv-policy"])
2828
.assert()
29-
.code(101)
29+
.code(0)
3030
.stdout_matches_path(curr_dir!().join("stdout.log"))
3131
.stderr_matches_path(curr_dir!().join("stderr.log"));
3232

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
11
Updating `dummy-registry` index
22
Adding rust-version-user v0.2.1 to dependencies.
3-
error: failed to select a version for the requirement `rust-version-user = "^0.2.1"`
4-
candidate versions found which didn't match: 0.2.1, 0.1.0
5-
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
6-
required by package `cargo-list-test-fixture v0.0.0 ([ROOT]/case)`
7-
perhaps a crate was updated and forgotten to be re-vendored?

tests/testsuite/rust_version.rs

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -245,37 +245,13 @@ fn dependency_rust_version_newer_than_package() {
245245
.file("src/main.rs", "fn main(){}")
246246
.build();
247247

248-
p.cargo("check --ignore-rust-version")
248+
p.cargo("check")
249249
.arg("-Zmsrv-policy")
250250
.masquerade_as_nightly_cargo(&["msrv-policy"])
251-
// This shouldn't fail
252-
.with_status(101)
253-
.with_stderr(
254-
"\
255-
[UPDATING] `dummy-registry` index
256-
[ERROR] failed to select a version for the requirement `bar = \"^1.0.0\"`
257-
candidate versions found which didn't match: 1.6.0
258-
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
259-
required by package `foo v0.0.1 ([CWD])`
260-
perhaps a crate was updated and forgotten to be re-vendored?
261-
",
262-
)
263251
.run();
264-
p.cargo("check")
252+
p.cargo("check --ignore-rust-version")
265253
.arg("-Zmsrv-policy")
266254
.masquerade_as_nightly_cargo(&["msrv-policy"])
267-
.with_status(101)
268-
// This should have a better error message
269-
.with_stderr(
270-
"\
271-
[UPDATING] `dummy-registry` index
272-
[ERROR] failed to select a version for the requirement `bar = \"^1.0.0\"`
273-
candidate versions found which didn't match: 1.6.0
274-
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
275-
required by package `foo v0.0.1 ([CWD])`
276-
perhaps a crate was updated and forgotten to be re-vendored?
277-
",
278-
)
279255
.run();
280256
}
281257

@@ -369,8 +345,10 @@ fn dependency_rust_version_backtracking() {
369345
"\
370346
[UPDATING] `dummy-registry` index
371347
[DOWNLOADING] crates ...
372-
[DOWNLOADED] no-rust-version v2.1.0 (registry `dummy-registry`)
373-
[CHECKING] no-rust-version v2.1.0
348+
[DOWNLOADED] no-rust-version v2.2.0 (registry `dummy-registry`)
349+
[DOWNLOADED] has-rust-version v1.6.0 (registry `dummy-registry`)
350+
[CHECKING] has-rust-version v1.6.0
351+
[CHECKING] no-rust-version v2.2.0
374352
[CHECKING] [..]
375353
[FINISHED] [..]
376354
",

0 commit comments

Comments
 (0)