Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(msrv): Report all incompatible packages, not just a random one #13514

Merged
merged 2 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 33 additions & 26 deletions src/cargo/ops/cargo_compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,8 @@ pub fn create_bcx<'a, 'gctx>(
current_version.patch,
);

let mut incompatible = Vec::new();
let mut local_incompatible = false;
for unit in unit_graph.keys() {
let Some(version) = unit.pkg.rust_version() else {
continue;
Expand All @@ -497,35 +499,40 @@ pub fn create_bcx<'a, 'gctx>(
continue;
}

let guidance = if ws.is_ephemeral() {
local_incompatible |= unit.is_local();
incompatible.push((unit, version));
}
if !incompatible.is_empty() {
use std::fmt::Write as _;

let plural = if incompatible.len() == 1 { "" } else { "s" };
let mut message = format!(
"rustc {current_version} is not supported by the following package{plural}:\n"
);
incompatible.sort_by_key(|(unit, _)| (unit.pkg.name(), unit.pkg.version()));
for (unit, msrv) in incompatible {
let name = &unit.pkg.name();
let version = &unit.pkg.version();
writeln!(&mut message, " {name}@{version} requires rustc {msrv}").unwrap();
}
if ws.is_ephemeral() {
if ws.ignore_lock() {
"Try re-running cargo install with `--locked`".to_string()
} else {
String::new()
writeln!(
&mut message,
"Try re-running `cargo install` with `--locked`"
)
.unwrap();
}
} else if !unit.is_local() {
format!(
"Either upgrade to rustc {} or newer, or use\n\
cargo update {}@{} --precise ver\n\
where `ver` is the latest version of `{}` supporting rustc {}",
version,
unit.pkg.name(),
unit.pkg.version(),
unit.pkg.name(),
current_version,
} else if !local_incompatible {
writeln!(
&mut message,
"Either upgrade rustc or select compatible dependency versions with
`cargo update <name>@<current-ver> --precise <compatible-ver>`
where `<compatible-ver>` is the latest version supporting rustc {current_version}",
)
} else {
String::new()
};

anyhow::bail!(
"package `{}` cannot be built because it requires rustc {} or newer, \
while the currently active rustc version is {}\n{}",
unit.pkg,
version,
current_version,
guidance,
);
.unwrap();
}
return Err(anyhow::Error::msg(message));
}
}

Expand Down
75 changes: 65 additions & 10 deletions tests/testsuite/rust_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,11 @@ fn rust_version_too_high() {
p.cargo("check")
.with_status(101)
.with_stderr(
"error: package `foo v0.0.1 ([..])` cannot be built because it requires \
rustc 1.9876.0 or newer, while the currently active rustc version is [..]\n\n",
"\
[ERROR] rustc [..] is not supported by the following package:
foo@0.0.1 requires rustc 1.9876.0

",
)
.run();
p.cargo("check --ignore-rust-version").run();
Expand Down Expand Up @@ -212,14 +215,66 @@ fn dependency_rust_version_newer_than_rustc() {
p.cargo("check")
.with_status(101)
.with_stderr(
" Updating `[..]` index\n \
Downloading crates ...\n \
Downloaded bar v0.0.1 (registry `[..]`)\n\
error: package `bar v0.0.1` cannot be built because it requires \
rustc 1.2345.0 or newer, while the currently active rustc version is [..]\n\
Either upgrade to rustc 1.2345.0 or newer, or use\n\
cargo update bar@0.0.1 --precise ver\n\
where `ver` is the latest version of `bar` supporting rustc [..]",
"\
[UPDATING] `[..]` index
[DOWNLOADING] crates ...
[DOWNLOADED] bar v0.0.1 (registry `[..]`)
[ERROR] rustc [..] is not supported by the following package:
bar@0.0.1 requires rustc 1.2345.0
Either upgrade rustc or select compatible dependency versions with
`cargo update <name>@<current-ver> --precise <compatible-ver>`
where `<compatible-ver>` is the latest version supporting rustc [..]

",
)
.run();
p.cargo("check --ignore-rust-version").run();
}

#[cargo_test]
fn dependency_tree_rust_version_newer_than_rustc() {
Package::new("baz", "0.0.1")
.dep("bar", "0.0.1")
.rust_version("1.2345.0")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: choose a larger version. I believe Rust will last over 300 years!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just kidding 🤪

.file("src/lib.rs", "fn other_stuff() {}")
.publish();
Package::new("bar", "0.0.1")
.rust_version("1.2345.0")
.file("src/lib.rs", "fn other_stuff() {}")
.publish();

let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
edition = "2015"
authors = []
[dependencies]
baz = "0.0.1"
"#,
)
.file("src/main.rs", "fn main(){}")
.build();

p.cargo("check")
.with_status(101)
.with_stderr(
"\
[UPDATING] `[..]` index
[DOWNLOADING] crates ...
[DOWNLOADED] baz v0.0.1 (registry `[..]`)
[DOWNLOADED] bar v0.0.1 (registry `[..]`)
[ERROR] rustc [..] is not supported by the following packages:
bar@0.0.1 requires rustc 1.2345.0
baz@0.0.1 requires rustc 1.2345.0
Either upgrade rustc or select compatible dependency versions with
`cargo update <name>@<current-ver> --precise <compatible-ver>`
where `<compatible-ver>` is the latest version supporting rustc [..]

",
)
.run();
p.cargo("check --ignore-rust-version").run();
Expand Down