fix(install): Suggest an alternative version on MSRV failure

The next step would be to also automatically install an MSRV compatible
version if compatible with the version req (#10903).
This improved error message will still be useful if the MSRV compatible
version is outside of the version req.

I did this as the first step
- Helps people now, not needing to wait on `-Zmsrv-policy` to be stabilized
- Has fewer questions on how it should be done (or if it should be)
This commit is contained in:
Ed Page 2023-10-09 20:22:54 -05:00
parent 2976e2ac66
commit 9b32be7f89
2 changed files with 39 additions and 1 deletions

View File

@ -559,8 +559,45 @@ where
if !msrv_req.matches(current) {
let name = summary.name();
let ver = summary.version();
let extra = if dep.source_id().is_registry() {
// Match any version, not just the selected
let msrv_dep =
Dependency::parse(dep.package_name(), None, dep.source_id())?;
let msrv_deps = loop {
match source.query_vec(&msrv_dep, QueryKind::Exact)? {
Poll::Ready(deps) => break deps,
Poll::Pending => source.block_until_ready()?,
}
};
if let Some(alt) = msrv_deps
.iter()
.filter(|summary| {
summary
.rust_version()
.map(|msrv| msrv.caret_req().matches(current))
.unwrap_or(true)
})
.max_by_key(|s| s.package_id())
{
if let Some(rust_version) = alt.rust_version() {
format!(
"\n`{name} {}` supports rustc {rust_version}",
alt.version()
)
} else {
format!(
"\n`{name} {}` has an unspecified minimum rustc version",
alt.version()
)
}
} else {
String::new()
}
} else {
String::new()
};
bail!("\
cannot install package `{name} {ver}`, it requires rustc {msrv} or newer, while the currently active rustc version is {current}"
cannot install package `{name} {ver}`, it requires rustc {msrv} or newer, while the currently active rustc version is {current}{extra}"
)
}
}

View File

@ -2479,6 +2479,7 @@ fn install_incompat_msrv() {
.with_stderr("\
[UPDATING] `dummy-registry` index
[ERROR] cannot install package `foo 0.2.0`, it requires rustc 1.9876.0 or newer, while the currently active rustc version is [..]
`foo 0.1.0` supports rustc 1.30
")
.with_status(101).run();
}