From f2a0489381fc1d50d55a1eff456faa48cd847f0b Mon Sep 17 00:00:00 2001 From: rami3l Date: Fri, 5 Jun 2026 20:23:49 +0200 Subject: [PATCH 1/3] test(cli/rustup-mode): test auto-installation on to-be-deprecated subcommand --- tests/suite/cli_misc.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/suite/cli_misc.rs b/tests/suite/cli_misc.rs index b27a0834d3..31a7a18448 100644 --- a/tests/suite/cli_misc.rs +++ b/tests/suite/cli_misc.rs @@ -1795,3 +1795,27 @@ info: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install d "#]]) .is_ok(); } + +#[tokio::test] +async fn warn_auto_install_on_rustup_deprecated() { + let cx = CliTestContext::new(Scenario::SimpleV2).await; + cx.config + .expect_with_env( + ["rustup", "component", "list"], + [("RUSTUP_TOOLCHAIN", "stable"), ("RUSTUP_AUTO_INSTALL", "1")], + ) + .await + .with_stdout(snapbox::str![[r#" +... +rustc-[HOST_TUPLE] (installed) +... +"#]]) + .with_stderr(snapbox::str![[r#" +... +warn: the missing active toolchain `stable-[HOST_TUPLE]` has been auto-installed +warn: this might cause rustup commands to take longer time to finish than expected +info: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable` + +"#]]) + .is_ok(); +} From 00152211217e75ea901f6aa553678e3d563b06c8 Mon Sep 17 00:00:00 2001 From: rami3l Date: Fri, 5 Jun 2026 19:11:20 +0200 Subject: [PATCH 2/3] refactor(config): accept `Cfg` in `EnsureInstalled::warn_auto_install()` --- src/config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/config.rs b/src/config.rs index 42da8d1983..2ab3508e67 100644 --- a/src/config.rs +++ b/src/config.rs @@ -142,10 +142,10 @@ impl EnsureInstalled { } impl EnsureInstalled { - fn warn_auto_install(&self, process: &Process) { + fn warn_auto_install(&self, cfg: &Cfg<'_>) { // If we're already in a recursion, or we haven't just installed the active toolchain, then // don't print the warning. - let recursions = process.var("RUST_RECURSION_COUNT"); + let recursions = cfg.process.var("RUST_RECURSION_COUNT"); if recursions.is_ok_and(|it| it != "0") || !matches!(self.status, UpdateStatus::Installed) { return; } @@ -562,7 +562,7 @@ impl<'a> Cfg<'a> { match self.ensure_active_toolchain(true, false).await { Ok(r) => { let (tc, source) = r; - tc.warn_auto_install(self.process); + tc.warn_auto_install(self); Ok(Some((tc.inner, source))) } Err(e) => match e.downcast_ref::() { @@ -768,7 +768,7 @@ impl<'a> Cfg<'a> { let install_if_missing = self.should_auto_install()?; let EnsureInstalled { inner: tc, status } = Toolchain::from_local(tc, install_if_missing, self).await?; - EnsureInstalled::new(tc.name(), status).warn_auto_install(self.process); + EnsureInstalled::new(tc.name(), status).warn_auto_install(self); Ok((tc, source)) } None => { From 69a3107dd1129ea83c3e6cab2ad17dbc6becd682 Mon Sep 17 00:00:00 2001 From: rami3l Date: Fri, 5 Jun 2026 19:11:20 +0200 Subject: [PATCH 3/3] feat(cli/rustup-mode): warn about auto-installation in some subcommands --- src/cli/rustup_mode.rs | 41 ++++++++++++++++++++++++++++++++++++++--- src/config.rs | 14 ++++++++++---- tests/suite/cli_misc.rs | 4 ++-- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index 08ac9e0454..6a8075c91a 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -301,6 +301,36 @@ fn update_toolchain_value_parser(s: &str) -> Result { }) } +impl RustupSubcmd { + fn allow_auto_install(&self) -> bool { + match self { + // These subcommands execute or rely on the active toolchain, so auto-installing it when + // missing may be reasonable depending on the user's decision. + #[cfg(not(windows))] + RustupSubcmd::Man { .. } => true, + RustupSubcmd::Doc { .. } | RustupSubcmd::Run { .. } => true, + + // These subcommands don't require the active toolchain, so auto-installing it should be + // disabled to avoid surprises. + RustupSubcmd::Check { .. } + | RustupSubcmd::Completions { .. } + | RustupSubcmd::Component { .. } + | RustupSubcmd::Default { .. } + | RustupSubcmd::DumpTestament + | RustupSubcmd::Install { .. } + | RustupSubcmd::Override { .. } + | RustupSubcmd::Self_ { .. } + | RustupSubcmd::Set { .. } + | RustupSubcmd::Show { .. } + | RustupSubcmd::Target { .. } + | RustupSubcmd::Toolchain { .. } + | RustupSubcmd::Uninstall { .. } + | RustupSubcmd::Update { .. } + | RustupSubcmd::Which { .. } => false, + } + } +} + #[derive(Debug, Subcommand)] enum ShowSubcmd { /// Show the active toolchain @@ -631,15 +661,20 @@ pub async fn main( update_console_filter(process, &console_filter, matches.quiet, matches.verbose); - let cfg = &mut Cfg::from_env(current_dir, matches.quiet, true, process)?; - cfg.toolchain_override = matches.plus_toolchain; - let Some(subcmd) = matches.subcmd else { let help = Rustup::command().render_long_help(); writeln!(process.stderr().lock(), "{}", help.ansi())?; return Ok(ExitCode::FAILURE); }; + let cfg = &mut Cfg::from_env( + current_dir, + matches.quiet, + subcmd.allow_auto_install(), + process, + )?; + cfg.toolchain_override = matches.plus_toolchain; + match subcmd { RustupSubcmd::DumpTestament => common::dump_testament(process), RustupSubcmd::Install { opts } => update(cfg, opts, true).await, diff --git a/src/config.rs b/src/config.rs index 2ab3508e67..1659468332 100644 --- a/src/config.rs +++ b/src/config.rs @@ -154,6 +154,16 @@ impl EnsureInstalled { "the missing active toolchain `{}` has been auto-installed", self.inner, ); + + if !cfg.allow_auto_install { + // NOTE: Special behavior for rustup v1.29 + warn!( + "this is deprecated for most `rustup` commands and may not work in a future release" + ); + warn!("see for more info"); + return; + } + warn!("this might cause rustup commands to take longer time to finish than expected"); info!("you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable`"); } @@ -423,10 +433,6 @@ impl<'a> Cfg<'a> { } pub(crate) fn should_auto_install(&self) -> Result { - if !self.allow_auto_install { - return Ok(false); - } - if let Ok(mode) = self.process.var("RUSTUP_AUTO_INSTALL") { Ok(mode != "0") } else { diff --git a/tests/suite/cli_misc.rs b/tests/suite/cli_misc.rs index 31a7a18448..8d021588a9 100644 --- a/tests/suite/cli_misc.rs +++ b/tests/suite/cli_misc.rs @@ -1813,8 +1813,8 @@ rustc-[HOST_TUPLE] (installed) .with_stderr(snapbox::str![[r#" ... warn: the missing active toolchain `stable-[HOST_TUPLE]` has been auto-installed -warn: this might cause rustup commands to take longer time to finish than expected -info: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable` +warn: this is deprecated for most `rustup` commands and may not work in a future release +warn: see for more info "#]]) .is_ok();