Skip to content

Commit 76816ea

Browse files
committed
fix(errors)!: improve error messages for RustupError::ToolchainNotInstalled
1 parent 4b52f5c commit 76816ea

File tree

4 files changed

+48
-14
lines changed

4 files changed

+48
-14
lines changed

src/config.rs

+7-11
Original file line numberDiff line numberDiff line change
@@ -672,17 +672,13 @@ impl<'a> Cfg<'a> {
672672

673673
// XXX: this awkwardness deals with settings file being locked already
674674
let toolchain_name = toolchain_name.resolve(&default_host_triple)?;
675-
match Toolchain::new(self, (&toolchain_name).into()) {
676-
Err(RustupError::ToolchainNotInstalled { .. }) => {
677-
if matches!(toolchain_name, ToolchainName::Custom(_)) {
678-
bail!(
679-
"custom toolchain specified in override file '{}' is not installed",
680-
toolchain_file.display()
681-
)
682-
}
683-
}
684-
Ok(_) => {}
685-
Err(e) => Err(e)?,
675+
if !Toolchain::exists(self, &(&toolchain_name).into())?
676+
&& matches!(toolchain_name, ToolchainName::Custom(_))
677+
{
678+
bail!(
679+
"custom toolchain specified in override file '{}' is not installed",
680+
toolchain_file.display()
681+
)
686682
}
687683
}
688684

src/errors.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,16 @@ pub enum RustupError {
9898
#[error(
9999
"toolchain '{name}' is not installed{}",
100100
if let ToolchainName::Official(t) = name {
101-
format!("\nhelp: run `rustup toolchain install {t}` to install it")
101+
let t = if *is_active { "" } else { &format!(" {t}") };
102+
format!("\nhelp: run `rustup toolchain install{t}` to install it")
102103
} else {
103104
String::new()
104105
},
105106
)]
106-
ToolchainNotInstalled { name: ToolchainName },
107+
ToolchainNotInstalled {
108+
name: ToolchainName,
109+
is_active: bool,
110+
},
107111
#[error("path '{0}' not found")]
108112
PathToolchainNotInstalled(PathBasedToolchainName),
109113
#[error(

src/toolchain.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ impl<'a> Toolchain<'a> {
5353
Ok(tc) => Ok(tc),
5454
Err(RustupError::ToolchainNotInstalled {
5555
name: ToolchainName::Official(desc),
56+
..
5657
}) if install_if_missing => {
5758
Ok(
5859
DistributableToolchain::install(cfg, &desc, &[], &[], cfg.get_profile()?, true)
@@ -107,7 +108,10 @@ impl<'a> Toolchain<'a> {
107108
let path = cfg.toolchain_path(&name);
108109
if !Toolchain::exists(cfg, &name)? {
109110
return Err(match name {
110-
LocalToolchainName::Named(name) => RustupError::ToolchainNotInstalled { name },
111+
LocalToolchainName::Named(name) => {
112+
let is_active = matches!(cfg.active_toolchain(), Ok(Some((t, _))) if t == name);
113+
RustupError::ToolchainNotInstalled { name, is_active }
114+
}
111115
LocalToolchainName::Path(name) => RustupError::PathToolchainNotInstalled(name),
112116
});
113117
}

tests/suite/cli_exact.rs

+30
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustup::for_host;
55
use rustup::test::{
66
CROSS_ARCH1, CROSS_ARCH2, CliTestContext, MULTI_ARCH1, Scenario, this_host_triple,
77
};
8+
use rustup::utils::raw;
89

910
#[tokio::test]
1011
async fn update_once() {
@@ -699,6 +700,35 @@ help: run `rustup toolchain install nightly-{0}` to install it
699700
.await;
700701
}
701702

703+
// issue #4212
704+
#[tokio::test]
705+
async fn show_suggestion_for_missing_toolchain_with_components() {
706+
let cx = CliTestContext::new(Scenario::SimpleV2).await;
707+
708+
let cwd = cx.config.current_dir();
709+
let toolchain_file = cwd.join("rust-toolchain.toml");
710+
raw::write_file(
711+
&toolchain_file,
712+
r#"
713+
[toolchain]
714+
channel = "stable"
715+
components = [ "rust-src" ]
716+
"#,
717+
)
718+
.unwrap();
719+
cx.config
720+
.expect_err_env(
721+
&["cargo", "fmt"],
722+
&[("RUSTUP_AUTO_INSTALL", "0")],
723+
for_host!(
724+
r"error: toolchain 'stable-{0}' is not installed
725+
help: run `rustup toolchain install` to install it
726+
"
727+
),
728+
)
729+
.await;
730+
}
731+
702732
// issue #927
703733
#[tokio::test]
704734
async fn undefined_linked_toolchain() {

0 commit comments

Comments
 (0)