From c68c63645eed75030b717d7ad0f1ba7ce3d99e3d Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 9 Oct 2023 20:22:54 -0500 Subject: [PATCH] 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) --- .../ops/common_for_install_and_uninstall.rs | 39 ++++++++++++++++++- tests/testsuite/install.rs | 1 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/cargo/ops/common_for_install_and_uninstall.rs b/src/cargo/ops/common_for_install_and_uninstall.rs index 7b3ca0534f18..9dc823bbc384 100644 --- a/src/cargo/ops/common_for_install_and_uninstall.rs +++ b/src/cargo/ops/common_for_install_and_uninstall.rs @@ -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}" ) } } diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs index cb1539eb8db4..3f0720faa2ef 100644 --- a/tests/testsuite/install.rs +++ b/tests/testsuite/install.rs @@ -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(); }