From 27069084104676c3f668f6402f60c6585b1ee8e4 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sat, 20 Jun 2026 21:53:18 +0800 Subject: [PATCH 01/15] refactor(self-update)!: extract Windows registry cleanup from `do_remove_from_path()` BREAKING CHANGE: Windows registry cleanup is no longer performed by `do_remove_from_path()`. Co-authored-by: baka-gourd <36119339+baka-gourd@users.noreply.github.com> --- src/cli/self_update.rs | 3 +++ src/cli/self_update/windows.rs | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index facfbde9e8..d353f8cb7c 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -1159,6 +1159,9 @@ fn clean_cargo_home(no_modify_path: bool, process: &Process) -> Result<()> { utils::remove_file("rustup_bin", &rustup_path)?; + #[cfg(windows)] + do_remove_from_programs()?; + let cargo_bin_display = cargo_bin.display(); info!("removing empty cargo bin directory `{cargo_bin_display}`"); diff --git a/src/cli/self_update/windows.rs b/src/cli/self_update/windows.rs index 1dd7e13671..ec4fe089f1 100644 --- a/src/cli/self_update/windows.rs +++ b/src/cli/self_update/windows.rs @@ -567,8 +567,7 @@ where pub(crate) fn do_remove_from_path(process: &Process) -> Result<()> { let new_path = _with_path_cargo_home_bin(_remove_from_path, process)?; - _apply_new_path(new_path)?; - do_remove_from_programs() + _apply_new_path(new_path) } const RUSTUP_UNINSTALL_ENTRY: &str = r"Software\Microsoft\Windows\CurrentVersion\Uninstall\Rustup"; From 6a57f02faa063f79d7e52038e5ad5bfe2f1d5036 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sat, 20 Jun 2026 21:57:09 +0800 Subject: [PATCH 02/15] refactor(self-update)!: extract add registry from `do_add_to_path()` BREAKING CHANGE: `do_add_to_path()` will not add Windows registry --- src/cli/self_update.rs | 5 ++++- src/cli/self_update/windows.rs | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index d353f8cb7c..1f4d780957 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -92,7 +92,7 @@ pub use windows::complete_windows_uninstall; #[cfg(all(windows, feature = "test"))] pub use windows::{RegistryGuard, RegistryValueId, USER_PATH, get_path}; #[cfg(windows)] -use windows::{do_add_to_path, do_remove_from_path}; +use windows::{do_add_to_path, do_add_to_programs, do_remove_from_path, do_remove_from_programs}; #[cfg(windows)] pub(crate) use windows::{run_update, self_replace}; @@ -1010,6 +1010,9 @@ async fn maybe_install_rust(opts: InstallOpts<'_>, cfg: &mut Cfg<'_>) -> Result< do_add_to_path(cfg.process)?; } + #[cfg(windows)] + do_add_to_programs(cfg.process)?; + // If RUSTUP_HOME is not set, make sure it exists if cfg.process.var_os("RUSTUP_HOME").is_none() { let home = cfg diff --git a/src/cli/self_update/windows.rs b/src/cli/self_update/windows.rs index ec4fe089f1..8b1eb6726c 100644 --- a/src/cli/self_update/windows.rs +++ b/src/cli/self_update/windows.rs @@ -449,8 +449,7 @@ pub(crate) fn wait_for_parent() -> Result<()> { pub(crate) fn do_add_to_path(process: &Process) -> Result<()> { let new_path = _with_path_cargo_home_bin(_add_to_path, process)?; - _apply_new_path(new_path)?; - do_add_to_programs(process) + _apply_new_path(new_path) } fn _apply_new_path(new_path: Option) -> Result<()> { From 9cb3e92484f7ca35d78fdf2e396bebe8183789b2 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:10:02 +0800 Subject: [PATCH 03/15] feat(self-update): route registry helpers through UUID subkeys --- src/cli/self_update.rs | 8 +- src/cli/self_update/unix.rs | 2 +- src/cli/self_update/windows.rs | 138 +++++++++++++++++++++++---------- src/test.rs | 4 +- 4 files changed, 107 insertions(+), 45 deletions(-) diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index 1f4d780957..502e6e35ee 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -90,7 +90,7 @@ mod windows; #[cfg(windows)] pub use windows::complete_windows_uninstall; #[cfg(all(windows, feature = "test"))] -pub use windows::{RegistryGuard, RegistryValueId, USER_PATH, get_path}; +pub use windows::{RUSTUP_TEST_REGISTRY_UUID, RegistryGuard, RegistryValueId, USER_PATH, get_path}; #[cfg(windows)] use windows::{do_add_to_path, do_add_to_programs, do_remove_from_path, do_remove_from_programs}; #[cfg(windows)] @@ -324,7 +324,7 @@ impl SelfUpdateMode { let setup_path = prepare_update(dl_cfg).await?; if let Some(setup_path) = &setup_path { - return run_update(setup_path); + return run_update(setup_path, dl_cfg.process); } else { // Try again in case we emitted "tool `{}` is already installed" last time. install_proxies(dl_cfg.process)?; @@ -1163,7 +1163,7 @@ fn clean_cargo_home(no_modify_path: bool, process: &Process) -> Result<()> { utils::remove_file("rustup_bin", &rustup_path)?; #[cfg(windows)] - do_remove_from_programs()?; + do_remove_from_programs(process)?; let cargo_bin_display = cargo_bin.display(); info!("removing empty cargo bin directory `{cargo_bin_display}`"); @@ -1290,7 +1290,7 @@ pub(crate) async fn update(cfg: &Cfg<'_>) -> Result { PackageUpdate::Rustup, Ok(UpdateStatus::Updated(version)), ); - return run_update(&setup_path); + return run_update(&setup_path, cfg.process); } None => { let _ = common::show_channel_update( diff --git a/src/cli/self_update/unix.rs b/src/cli/self_update/unix.rs index 7edcd68b78..c68b231556 100644 --- a/src/cli/self_update/unix.rs +++ b/src/cli/self_update/unix.rs @@ -120,7 +120,7 @@ pub(crate) fn do_write_env_files(process: &Process) -> Result<()> { /// Tell the upgrader to replace the rustup bins, then delete /// itself. -pub(crate) fn run_update(setup_path: &Path) -> Result { +pub(crate) fn run_update(setup_path: &Path, _process: &Process) -> Result { let status = Command::new(setup_path) .arg("--self-replace") .status() diff --git a/src/cli/self_update/windows.rs b/src/cli/self_update/windows.rs index 8b1eb6726c..8856347678 100644 --- a/src/cli/self_update/windows.rs +++ b/src/cli/self_update/windows.rs @@ -5,8 +5,6 @@ use std::io::Write; use std::os::windows::ffi::OsStrExt; use std::path::Path; use std::process::Command; -#[cfg(any(test, feature = "test"))] -use std::sync::{LockResult, Mutex, MutexGuard}; use anyhow::{Context, Result, anyhow}; use tracing::{info, warn}; @@ -449,10 +447,10 @@ pub(crate) fn wait_for_parent() -> Result<()> { pub(crate) fn do_add_to_path(process: &Process) -> Result<()> { let new_path = _with_path_cargo_home_bin(_add_to_path, process)?; - _apply_new_path(new_path) + _apply_new_path(new_path, process) } -fn _apply_new_path(new_path: Option) -> Result<()> { +fn _apply_new_path(new_path: Option, process: &Process) -> Result<()> { use std::ptr; use windows_sys::Win32::Foundation::{LPARAM, WPARAM}; use windows_sys::Win32::UI::WindowsAndMessaging::{ @@ -464,7 +462,7 @@ fn _apply_new_path(new_path: Option) -> Result<()> { None => return Ok(()), // No need to set the path }; - let environment = CURRENT_USER.create("Environment")?; + let environment = CURRENT_USER.create(registry_sub_key_path("Environment", process))?; if new_path.is_empty() { environment.remove_value("PATH")?; @@ -492,9 +490,9 @@ fn _apply_new_path(new_path: Option) -> Result<()> { // Get the windows PATH variable out of the registry as a String. If // this returns None then the PATH variable is not a string and we // should not mess with it. -fn get_windows_path_var() -> Result> { +fn get_windows_path_var(process: &Process) -> Result> { let environment = CURRENT_USER - .create("Environment") + .create(registry_sub_key_path("Environment", process)) .context("Failed opening Environment key")?; let reg_value = environment.get_hstring("PATH"); @@ -558,7 +556,7 @@ fn _with_path_cargo_home_bin(f: F, process: &Process) -> Result Option, { - let windows_path = get_windows_path_var()?; + let windows_path = get_windows_path_var(process)?; let mut path_str = process.cargo_home()?; path_str.push("bin"); Ok(windows_path.and_then(|old_path| f(old_path, HSTRING::from(path_str.as_path())))) @@ -566,19 +564,19 @@ where pub(crate) fn do_remove_from_path(process: &Process) -> Result<()> { let new_path = _with_path_cargo_home_bin(_remove_from_path, process)?; - _apply_new_path(new_path) + _apply_new_path(new_path, process) } const RUSTUP_UNINSTALL_ENTRY: &str = r"Software\Microsoft\Windows\CurrentVersion\Uninstall\Rustup"; -fn rustup_uninstall_reg_key() -> Result { +fn rustup_uninstall_reg_key(process: &Process) -> Result { CURRENT_USER - .create(RUSTUP_UNINSTALL_ENTRY) + .create(registry_sub_key_path(RUSTUP_UNINSTALL_ENTRY, process)) .context("Failed creating uninstall key") } -pub(crate) fn do_update_programs_display_version(version: &str) -> Result<()> { - rustup_uninstall_reg_key()? +pub(crate) fn do_update_programs_display_version(version: &str, process: &Process) -> Result<()> { + rustup_uninstall_reg_key(process)? .set_string("DisplayVersion", version) .context("Failed to set `DisplayVersion`") } @@ -586,7 +584,7 @@ pub(crate) fn do_update_programs_display_version(version: &str) -> Result<()> { pub(crate) fn do_add_to_programs(process: &Process) -> Result<()> { use std::path::PathBuf; - let key = rustup_uninstall_reg_key()?; + let key = rustup_uninstall_reg_key(process)?; // Don't overwrite registry if Rustup is already installed let prev = key.get_hstring("UninstallString"); @@ -608,20 +606,20 @@ pub(crate) fn do_add_to_programs(process: &Process) -> Result<()> { .context("Failed to set `UninstallString`")?; key.set_string("DisplayName", "Rustup: the Rust toolchain installer") .context("Failed to set `DisplayName`")?; - do_update_programs_display_version(env!("CARGO_PKG_VERSION"))?; + do_update_programs_display_version(env!("CARGO_PKG_VERSION"), process)?; Ok(()) } -pub(crate) fn do_remove_from_programs() -> Result<()> { - match CURRENT_USER.remove_tree(RUSTUP_UNINSTALL_ENTRY) { +pub(crate) fn do_remove_from_programs(process: &Process) -> Result<()> { + match CURRENT_USER.remove_tree(registry_sub_key_path(RUSTUP_UNINSTALL_ENTRY, process)) { Ok(()) => Ok(()), Err(e) if e.code() == HRESULT::from_win32(ERROR_FILE_NOT_FOUND) => Ok(()), Err(e) => Err(anyhow!(e)), } } -pub(crate) fn run_update(setup_path: &Path) -> Result { +pub(crate) fn run_update(setup_path: &Path, process: &Process) -> Result { Command::new(setup_path) .arg("--self-replace") .spawn() @@ -631,7 +629,7 @@ pub(crate) fn run_update(setup_path: &Path) -> Result { warn!("failed to get the new rustup version in order to update `DisplayVersion`"); return Ok(utils::ExitCode(1)); }; - do_update_programs_display_version(&version)?; + do_update_programs_display_version(&version, process)?; Ok(utils::ExitCode(0)) } @@ -753,38 +751,93 @@ pub(crate) fn spawn_uninstall_gc(no_modify_path: bool, process: &Process) -> Res // so we use env var here, notifying it if we need to remove $CARGO_HOME/bin from $PATH const GC_MODIFY_PATH: &str = "RUSTUP_GC_MODIFY_PATH"; +/// Environment variable carrying the per-test registry UUID. #[cfg(any(test, feature = "test"))] -pub fn get_path() -> Result> { - USER_PATH.get() -} +pub const RUSTUP_TEST_REGISTRY_UUID: &str = "RUSTUP_TEST_REGISTRY_UUID"; +/// Maps a real registry sub-key onto a per-test `RustupTest-{uuid}` subtree. #[cfg(any(test, feature = "test"))] -pub struct RegistryGuard<'a> { - _locked: LockResult>, - id: &'static RegistryValueId, - prev: Option, +fn map_sub_key(sub_key: &str, uuid: &str) -> String { + let root = format!(r"Software\Microsoft\Windows\CurrentVersion\Uninstall\RustupTest-{uuid}"); + if sub_key == RUSTUP_UNINSTALL_ENTRY { + format!(r"{root}\Programs") + } else if sub_key == "Environment" { + format!(r"{root}\Environment") + } else { + format!(r"{root}\{sub_key}") + } } +/// Resolves a registry sub-key, redirecting into the per-test subtree when the +/// process carries a [`RUSTUP_TEST_REGISTRY_UUID`]. In production builds this is +/// the identity function. #[cfg(any(test, feature = "test"))] -impl RegistryGuard<'_> { - pub fn new(id: &'static RegistryValueId) -> Result { - Ok(Self { - _locked: REGISTRY_LOCK.lock(), - id, - prev: id.get()?, - }) +fn registry_sub_key_path(sub_key: &str, process: &Process) -> String { + match process.var_opt(RUSTUP_TEST_REGISTRY_UUID) { + Ok(Some(uuid)) if !uuid.is_empty() => map_sub_key(sub_key, &uuid), + _ => sub_key.to_owned(), } } +#[cfg(not(any(test, feature = "test")))] +fn registry_sub_key_path(sub_key: &str, _process: &Process) -> String { + sub_key.to_owned() +} + #[cfg(any(test, feature = "test"))] -impl Drop for RegistryGuard<'_> { - fn drop(&mut self) { - self.id.set(self.prev.as_ref()).unwrap(); +pub fn get_path(uuid: Option<&str>) -> Result> { + USER_PATH.get(uuid) +} + +#[cfg(any(test, feature = "test"))] +fn random_uuid() -> String { + format!("{:032x}", rand::random::()) +} + +/// Guards a set of registry values for the duration of a test. +#[cfg(any(test, feature = "test"))] +pub struct RegistryGuard { + uuid: String, + saved: Vec<(&'static RegistryValueId, Option)>, +} + +#[cfg(any(test, feature = "test"))] +impl RegistryGuard { + pub fn new(ids: impl IntoIterator) -> Result { + let uuid = random_uuid(); + let mut seen = std::collections::HashSet::new(); + let mut saved = Vec::new(); + for id in ids { + if seen.insert((id.sub_key, id.value_name)) { + saved.push((id, id.get(Some(&uuid))?)); + } + } + Ok(Self { uuid, saved }) + } + + pub fn uuid(&self) -> &str { + &self.uuid } } #[cfg(any(test, feature = "test"))] -static REGISTRY_LOCK: Mutex<()> = Mutex::new(()); +impl Drop for RegistryGuard { + fn drop(&mut self) { + for (id, prev) in self.saved.iter().rev() { + let _ = id.set(prev.as_ref(), Some(&self.uuid)); + } + + let root = format!( + r"Software\Microsoft\Windows\CurrentVersion\Uninstall\RustupTest-{}", + self.uuid + ); + match CURRENT_USER.remove_tree(&root) { + Ok(()) => {} + Err(e) if e.code() == HRESULT::from_win32(ERROR_FILE_NOT_FOUND) => {} + Err(_) => {} + } + } +} #[cfg(any(test, feature = "test"))] pub const USER_PATH: RegistryValueId = RegistryValueId { @@ -800,8 +853,15 @@ pub struct RegistryValueId { #[cfg(any(test, feature = "test"))] impl RegistryValueId { - pub fn get(&self) -> Result> { - let sub_key = CURRENT_USER.create(self.sub_key)?; + fn resolved_sub_key(&self, uuid: Option<&str>) -> windows_registry::Result { + match uuid { + Some(uuid) => CURRENT_USER.create(map_sub_key(self.sub_key, uuid)), + None => CURRENT_USER.create(self.sub_key), + } + } + + pub fn get(&self, uuid: Option<&str>) -> Result> { + let sub_key = self.resolved_sub_key(uuid)?; match sub_key.get_value(self.value_name) { Ok(val) => Ok(Some(val)), Err(e) if e.code() == HRESULT::from_win32(ERROR_FILE_NOT_FOUND) => Ok(None), diff --git a/src/test.rs b/src/test.rs index 2fb547f504..a8139ca50e 100644 --- a/src/test.rs +++ b/src/test.rs @@ -24,7 +24,9 @@ use crate::dist::TargetTuple; use crate::process::TestProcess; #[cfg(windows)] -pub use crate::cli::self_update::{RegistryGuard, RegistryValueId, USER_PATH, get_path}; +pub use crate::cli::self_update::{ + RUSTUP_TEST_REGISTRY_UUID, RegistryGuard, RegistryValueId, USER_PATH, get_path, +}; mod clitools; pub use clitools::{ From 8ad57f30a7e829026dea0586f9e6a27573697ded Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:10:26 +0800 Subject: [PATCH 04/15] test: forward registry UUID from Config --- src/test/clitools.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/test/clitools.rs b/src/test/clitools.rs index 1311322696..e398c1c786 100644 --- a/src/test/clitools.rs +++ b/src/test/clitools.rs @@ -62,6 +62,9 @@ pub struct Config { pub workdir: RefCell, /// This is the test root for keeping stuff together pub test_root_dir: PathBuf, + /// Per-test Windows registry UUID. + #[cfg(windows)] + pub test_registry_uuid: Option, } /// Helper type to simplify assertions of a command's output. @@ -249,6 +252,11 @@ impl Config { self.workdir.borrow().clone() } + #[cfg(windows)] + pub fn set_registry_uuid(&mut self, uuid: &str) { + self.test_registry_uuid = Some(uuid.to_owned()); + } + pub fn cmd(&self, name: &str, args: I) -> Command where I: IntoIterator, @@ -328,6 +336,11 @@ impl Config { if let Some(root) = self.rustup_update_root.as_ref() { cmd.env("RUSTUP_UPDATE_ROOT", root); } + + #[cfg(windows)] + if let Some(uuid) = self.test_registry_uuid.as_ref() { + cmd.env(crate::cli::self_update::RUSTUP_TEST_REGISTRY_UUID, uuid); + } } /// Returns an [`Assert`] object to check the output of running the command @@ -832,6 +845,8 @@ async fn setup_test_state(test_dist_dir: TempDir) -> (TempDir, Config) { rustup_update_root: None, workdir: RefCell::new(workdir), test_root_dir: test_dir.path().to_path_buf(), + #[cfg(windows)] + test_registry_uuid: None, }; let build_path = built_exe_dir.join(format!("rustup-init{EXE_SUFFIX}")); From 7063b96fcb1ab4d30e623625f01f3ad7fd7d5408 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:10:43 +0800 Subject: [PATCH 05/15] test: retain registry guard in CLI context --- src/test/clitools.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/test/clitools.rs b/src/test/clitools.rs index e398c1c786..524480411f 100644 --- a/src/test/clitools.rs +++ b/src/test/clitools.rs @@ -966,6 +966,8 @@ impl SelfUpdateTestContext { pub struct CliTestContext { pub config: Config, _test_dir: TempDir, + #[cfg(windows)] + _registry_guard: Option, } impl CliTestContext { @@ -984,7 +986,22 @@ impl CliTestContext { config.distdir = Some(config.test_dist_dir.path().to_path_buf()); } - Self { config, _test_dir } + Self { + config, + _test_dir, + #[cfg(windows)] + _registry_guard: None, + } + } + + #[cfg(windows)] + pub fn guard_registry( + &mut self, + ids: impl IntoIterator, + ) { + let guard = crate::cli::self_update::RegistryGuard::new(ids).unwrap(); + self.config.set_registry_uuid(guard.uuid()); + self._registry_guard = Some(guard); } /// Move the dist server to the specified scenario and restore it From bf0702e86e3c82cedcdb6b89e74d2001612f80e3 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:11:12 +0800 Subject: [PATCH 06/15] test(self-update): add UUID registry test helpers --- src/cli/self_update/windows.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/cli/self_update/windows.rs b/src/cli/self_update/windows.rs index 8856347678..e7d3a7c175 100644 --- a/src/cli/self_update/windows.rs +++ b/src/cli/self_update/windows.rs @@ -869,8 +869,8 @@ impl RegistryValueId { } } - pub fn set(&self, new: Option<&Value>) -> Result<()> { - let sub_key = CURRENT_USER.create(self.sub_key)?; + pub fn set(&self, new: Option<&Value>, uuid: Option<&str>) -> Result<()> { + let sub_key = self.resolved_sub_key(uuid)?; match new { Some(new) => Ok(sub_key.set_value(self.value_name, new)?), None => Ok(sub_key.remove_value(self.value_name)?), @@ -880,6 +880,7 @@ impl RegistryValueId { #[cfg(test)] mod tests { + use std::collections::HashMap; use std::os::windows::ffi::OsStringExt; use windows_registry::Type; @@ -887,6 +888,33 @@ mod tests { use super::*; use crate::process::TestProcess; + fn test_process(guard: &RegistryGuard) -> TestProcess { + let vars: HashMap = [ + ("HOME".to_string(), "/unused".to_string()), + ( + RUSTUP_TEST_REGISTRY_UUID.to_string(), + guard.uuid().to_string(), + ), + ] + .into_iter() + .collect(); + TestProcess::with_vars(vars) + } + + fn test_environment_key(guard: &RegistryGuard) -> Key { + CURRENT_USER + .create(map_sub_key("Environment", guard.uuid())) + .unwrap() + } + + fn clear_path(environment: &Key) { + match environment.remove_value("PATH") { + Ok(()) => {} + Err(e) if e.code() == HRESULT::from_win32(ERROR_FILE_NOT_FOUND) => {} + Err(e) => panic!("failed to clear PATH: {e}"), + } + } + #[test] fn windows_install_does_not_add_path_twice() { assert_eq!( From ed25597a7b022a938dda013593670cf4015ff50d Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:11:27 +0800 Subject: [PATCH 07/15] test(self-update): migrate registry unit tests to UUID guards --- src/cli/self_update/windows.rs | 47 +++++++++++++++++++--------------- src/env_var.rs | 4 +-- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/cli/self_update/windows.rs b/src/cli/self_update/windows.rs index e7d3a7c175..c84d01b23b 100644 --- a/src/cli/self_update/windows.rs +++ b/src/cli/self_update/windows.rs @@ -951,16 +951,20 @@ mod tests { #[test] fn windows_path_regkey_type() { // per issue #261, setting PATH should use REG_EXPAND_SZ. - let _guard = RegistryGuard::new(&USER_PATH); - let environment = CURRENT_USER.create("Environment").unwrap(); - environment.remove_value("PATH").unwrap(); + let guard = RegistryGuard::new([&USER_PATH]).unwrap(); + let tp = test_process(&guard); + let environment = test_environment_key(&guard); + clear_path(&environment); { // Can't compare the Results as Eq isn't derived; thanks error-chain. #![allow(clippy::unit_cmp)] - assert_eq!((), _apply_new_path(Some(HSTRING::from("foo"))).unwrap()); + assert_eq!( + (), + _apply_new_path(Some(HSTRING::from("foo")), &tp.process).unwrap() + ); } - let environment = CURRENT_USER.create("Environment").unwrap(); + let environment = test_environment_key(&guard); let path = environment.get_value("PATH").unwrap(); let path_hstring = environment.get_hstring("PATH").unwrap(); assert_eq!(path.ty(), Type::ExpandString); @@ -971,8 +975,9 @@ mod tests { fn windows_path_delete_key_when_empty() { // during uninstall the PATH key may end up empty; if so we should // delete it. - let _guard = RegistryGuard::new(&USER_PATH); - let environment = CURRENT_USER.create("Environment").unwrap(); + let guard = RegistryGuard::new([&USER_PATH]).unwrap(); + let tp = test_process(&guard); + let environment = test_environment_key(&guard); environment .set_expand_hstring("PATH", &HSTRING::from("foo")) .unwrap(); @@ -980,7 +985,10 @@ mod tests { { // Can't compare the Results as Eq isn't derived; thanks error-chain. #![allow(clippy::unit_cmp)] - assert_eq!((), _apply_new_path(Some(HSTRING::new())).unwrap()); + assert_eq!( + (), + _apply_new_path(Some(HSTRING::new()), &tp.process).unwrap() + ); } let reg_value = environment.get_value("PATH"); match reg_value { @@ -992,16 +1000,11 @@ mod tests { #[test] fn windows_doesnt_mess_with_a_non_string_path() { + let guard = RegistryGuard::new([&USER_PATH]).unwrap(); // This writes an error, so we want a sink for it. - let tp = TestProcess::with_vars( - [("HOME".to_string(), "/unused".to_string())] - .iter() - .cloned() - .collect(), - ); + let tp = test_process(&guard); - let _guard = RegistryGuard::new(&USER_PATH); - let environment = CURRENT_USER.create("Environment").unwrap(); + let environment = test_environment_key(&guard); environment .set_bytes("PATH", Type::Bytes, &[0x12, 0x34]) .unwrap(); @@ -1021,11 +1024,15 @@ mod tests { #[test] fn windows_treat_missing_path_as_empty() { // during install the PATH key may be missing; treat it as empty - let _guard = RegistryGuard::new(&USER_PATH); - let environment = CURRENT_USER.create("Environment").unwrap(); - environment.remove_value("PATH").unwrap(); + let guard = RegistryGuard::new([&USER_PATH]).unwrap(); + let tp = test_process(&guard); + let environment = test_environment_key(&guard); + clear_path(&environment); - assert_eq!(Some(HSTRING::new()), get_windows_path_var().unwrap()); + assert_eq!( + Some(HSTRING::new()), + get_windows_path_var(&tp.process).unwrap() + ); } #[test] diff --git a/src/env_var.rs b/src/env_var.rs index 45b19c6389..dcf06669ac 100644 --- a/src/env_var.rs +++ b/src/env_var.rs @@ -68,7 +68,7 @@ mod tests { ); let tp = TestProcess::with_vars(vars); #[cfg(windows)] - let _path_guard = RegistryGuard::new(&USER_PATH).unwrap(); + let _path_guard = RegistryGuard::new([&USER_PATH]).unwrap(); let mut path_entries = vec![]; let mut cmd = Command::new("test"); @@ -116,7 +116,7 @@ mod tests { ); let tp = TestProcess::with_vars(vars); #[cfg(windows)] - let _path_guard = RegistryGuard::new(&USER_PATH).unwrap(); + let _path_guard = RegistryGuard::new([&USER_PATH]).unwrap(); #[track_caller] fn check(tp: &TestProcess, path_entries: Vec, append: &str, expected: &[&str]) { From 01f0817de939cc9e51f53ca49fb2f430328900e8 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:11:41 +0800 Subject: [PATCH 08/15] test(installer): use context registry guard interactively --- tests/suite/cli_inst_interactive.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/suite/cli_inst_interactive.rs b/tests/suite/cli_inst_interactive.rs index 9b75e951c4..d3d2da227c 100644 --- a/tests/suite/cli_inst_interactive.rs +++ b/tests/suite/cli_inst_interactive.rs @@ -4,9 +4,9 @@ use std::env::consts::EXE_SUFFIX; use std::io::Write; use std::process::Stdio; -use rustup::test::{Assert, CliTestContext, Config, SanitizedOutput, Scenario, this_host_tuple}; #[cfg(windows)] -use rustup::test::{RegistryGuard, USER_PATH}; +use rustup::test::USER_PATH; +use rustup::test::{Assert, CliTestContext, Config, SanitizedOutput, Scenario, this_host_tuple}; use rustup::utils::raw; fn run_input(config: &Config, args: &[&str], input: &str) -> Assert { @@ -43,9 +43,10 @@ fn run_input_with_env(config: &Config, args: &[&str], input: &str, env: &[(&str, #[tokio::test] async fn update() { - let cx = CliTestContext::new(Scenario::SimpleV2).await; + #[cfg_attr(not(windows), allow(unused_mut))] + let mut cx = CliTestContext::new(Scenario::SimpleV2).await; #[cfg(windows)] - let _path_guard = RegistryGuard::new(&USER_PATH).unwrap(); + cx.guard_registry([&USER_PATH]); run_input(&cx.config, &["rustup-init"], "\n\n"); run_input(&cx.config, &["rustup-init"], "\n\n").is_ok(); @@ -99,9 +100,10 @@ Rust is installed now. Great! #[tokio::test] async fn smoke_case_install_with_path_install() { - let cx = CliTestContext::new(Scenario::SimpleV2).await; + #[cfg_attr(not(windows), allow(unused_mut))] + let mut cx = CliTestContext::new(Scenario::SimpleV2).await; #[cfg(windows)] - let _path_guard = RegistryGuard::new(&USER_PATH).unwrap(); + cx.guard_registry([&USER_PATH]); run_input(&cx.config, &["rustup-init"], "\n\n") .is_ok() From c0367a0710317dba23b7c3451bc5c5e2556b9e82 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:12:06 +0800 Subject: [PATCH 09/15] test(paths): isolate Windows PATH smoke checks --- tests/suite/cli_paths.rs | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/tests/suite/cli_paths.rs b/tests/suite/cli_paths.rs index 65b6170aab..b1632b84d1 100644 --- a/tests/suite/cli_paths.rs +++ b/tests/suite/cli_paths.rs @@ -469,6 +469,9 @@ error: could not amend shell profile[..] #[cfg(windows)] mod windows { + use retry::delay::{Fibonacci, jitter}; + use retry::{OperationResult, retry}; + use super::INIT_NONE; use rustup::test::{CliTestContext, Scenario}; use rustup::test::{RegistryGuard, USER_PATH, get_path}; @@ -478,37 +481,46 @@ mod windows { #[tokio::test] /// Smoke test for end-to-end code connectivity of the installer path mgmt on windows. async fn install_uninstall_affect_path() { - let cx = CliTestContext::new(Scenario::Empty).await; - let _guard = RegistryGuard::new(&USER_PATH).unwrap(); + let mut cx = CliTestContext::new(Scenario::Empty).await; + let guard = RegistryGuard::new([&USER_PATH]).unwrap(); + cx.config.set_registry_uuid(guard.uuid()); + let uuid = guard.uuid().to_string(); let cfg_path = cx.config.cargodir.join("bin").display().to_string(); - let get_path_ = || { - HSTRING::try_from(get_path().unwrap().unwrap()) - .unwrap() - .to_string() + let read_path = |uuid: &str| -> Option { + retry( + Fibonacci::from_millis(1).map(jitter).take(21), + || match get_path(Some(uuid)).unwrap() { + Some(v) => OperationResult::Ok(HSTRING::try_from(v).unwrap().to_string()), + None => OperationResult::Retry(()), + }, + ) + .ok() }; cx.config.expect(&INIT_NONE).await.is_ok(); + let after_install = read_path(&uuid).unwrap_or_default(); assert!( - get_path_().contains(cfg_path.trim_matches('"')), - "`{}` not in `{}`", - cfg_path, - get_path_() + after_install.contains(cfg_path.trim_matches('"')), + "`{cfg_path}` not in `{after_install}`", ); cx.config .expect(&["rustup", "self", "uninstall", "-y"]) .await .is_ok(); - assert!(!get_path_().contains(&cfg_path)); + let after_uninstall = read_path(&uuid).unwrap_or_default(); + assert!(!after_uninstall.contains(&cfg_path)); } #[tokio::test] async fn uninstall_keeps_path_when_cargo_bin_is_non_empty() { - let cx = CliTestContext::new(Scenario::Empty).await; - let _guard = RegistryGuard::new(&USER_PATH).unwrap(); + let mut cx = CliTestContext::new(Scenario::Empty).await; + let guard = RegistryGuard::new([&USER_PATH]).unwrap(); + cx.config.set_registry_uuid(guard.uuid()); + let uuid = guard.uuid().to_string(); let cfg_path = cx.config.cargodir.join("bin").display().to_string(); let get_path_ = || { - HSTRING::try_from(get_path().unwrap().unwrap()) + HSTRING::try_from(get_path(Some(&uuid)).unwrap().unwrap()) .unwrap() .to_string() }; From e76010063db10a4be31e4bb1e649d22219b0fe46 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:12:27 +0800 Subject: [PATCH 10/15] test(paths): use UUID subtree for remaining Windows PATH cases --- tests/suite/cli_paths.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/suite/cli_paths.rs b/tests/suite/cli_paths.rs index b1632b84d1..93a8d43cd1 100644 --- a/tests/suite/cli_paths.rs +++ b/tests/suite/cli_paths.rs @@ -541,11 +541,13 @@ mod windows { #[tokio::test] async fn uninstall_doesnt_affect_path_with_no_modify_path() { - let cx = CliTestContext::new(Scenario::Empty).await; - let _guard = RegistryGuard::new(&USER_PATH).unwrap(); + let mut cx = CliTestContext::new(Scenario::Empty).await; + let guard = RegistryGuard::new([&USER_PATH]).unwrap(); + cx.config.set_registry_uuid(guard.uuid()); + let uuid = guard.uuid().to_string(); let cfg_path = cx.config.cargodir.join("bin").display().to_string(); let get_path_ = || { - HSTRING::try_from(get_path().unwrap().unwrap()) + HSTRING::try_from(get_path(Some(&uuid)).unwrap().unwrap()) .unwrap() .to_string() }; @@ -568,10 +570,12 @@ mod windows { async fn install_uninstall_affect_path_with_non_unicode() { use std::os::windows::ffi::OsStrExt; - use windows_registry::{CURRENT_USER, Type}; + use windows_registry::Type; - let cx = CliTestContext::new(Scenario::Empty).await; - let _guard = RegistryGuard::new(&USER_PATH).unwrap(); + let mut cx = CliTestContext::new(Scenario::Empty).await; + let guard = RegistryGuard::new([&USER_PATH]).unwrap(); + cx.config.set_registry_uuid(guard.uuid()); + let uuid = guard.uuid().to_string(); // Set up a non unicode PATH let mut reg_value = Value::from([ 0x00, 0xD8, // leading surrogate @@ -579,11 +583,7 @@ mod windows { 0x00, 0x00, // null ]); reg_value.set_ty(Type::ExpandString); - CURRENT_USER - .create("Environment") - .unwrap() - .set_value("PATH", ®_value) - .unwrap(); + USER_PATH.set(Some(®_value), Some(&uuid)).unwrap(); // compute expected path after installation let mut expected = Value::from( @@ -601,12 +601,12 @@ mod windows { expected.set_ty(Type::ExpandString); cx.config.expect(&INIT_NONE).await.is_ok(); - assert_eq!(get_path().unwrap().unwrap(), expected); + assert_eq!(get_path(Some(&uuid)).unwrap().unwrap(), expected); cx.config .expect(&["rustup", "self", "uninstall", "-y"]) .await .is_ok(); - assert_eq!(get_path().unwrap().unwrap(), reg_value); + assert_eq!(get_path(Some(&uuid)).unwrap().unwrap(), reg_value); } } From 737781ea000cb401d45d3e9a726364f861268b7b Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:12:51 +0800 Subject: [PATCH 11/15] test(self-update): guard installed setup helpers --- tests/suite/cli_self_upd.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/suite/cli_self_upd.rs b/tests/suite/cli_self_upd.rs index 4f95a9466b..c07d08f624 100644 --- a/tests/suite/cli_self_upd.rs +++ b/tests/suite/cli_self_upd.rs @@ -28,7 +28,10 @@ const TEST_VERSION: &str = "1.1.1"; /// Empty dist server, rustup installed with no toolchain async fn setup_empty_installed() -> CliTestContext { - let cx = CliTestContext::new(Scenario::Empty).await; + #[cfg_attr(not(windows), allow(unused_mut))] + let mut cx = CliTestContext::new(Scenario::Empty).await; + #[cfg(windows)] + cx.guard_registry([&USER_PATH, &USER_RUSTUP_VERSION]); cx.config .expect([ "rustup-init", @@ -44,7 +47,10 @@ async fn setup_empty_installed() -> CliTestContext { /// SimpleV3 dist server, rustup installed with default toolchain async fn setup_installed() -> CliTestContext { - let cx = CliTestContext::new(Scenario::SimpleV2).await; + #[cfg_attr(not(windows), allow(unused_mut))] + let mut cx = CliTestContext::new(Scenario::SimpleV2).await; + #[cfg(windows)] + cx.guard_registry([&USER_PATH, &USER_RUSTUP_VERSION]); cx.config .expect(["rustup-init", "-y", "--no-modify-path"]) .await From df6f8da1d726b6cad451c71f67e3a109c5239fc2 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:13:12 +0800 Subject: [PATCH 12/15] test(self-update): guard install smoke registry writes --- tests/suite/cli_self_upd.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/suite/cli_self_upd.rs b/tests/suite/cli_self_upd.rs index c07d08f624..ad8489a849 100644 --- a/tests/suite/cli_self_upd.rs +++ b/tests/suite/cli_self_upd.rs @@ -63,9 +63,10 @@ async fn setup_installed() -> CliTestContext { /// status of the proxies. #[tokio::test] async fn install_bins_to_cargo_home() { - let cx = CliTestContext::new(Scenario::SimpleV2).await; + #[cfg_attr(not(windows), allow(unused_mut))] + let mut cx = CliTestContext::new(Scenario::SimpleV2).await; #[cfg(windows)] - let _path_guard = RegistryGuard::new(&USER_PATH).unwrap(); + cx.guard_registry([&USER_PATH]); cx.config .expect(["rustup-init", "-y"]) @@ -107,9 +108,10 @@ info: default toolchain set to stable-[HOST_TUPLE] /// Ensure that proxies are relative symlinks. #[tokio::test] async fn proxies_are_relative_symlinks() { - let cx = CliTestContext::new(Scenario::SimpleV2).await; + #[cfg_attr(not(windows), allow(unused_mut))] + let mut cx = CliTestContext::new(Scenario::SimpleV2).await; #[cfg(windows)] - let _path_guard = RegistryGuard::new(&USER_PATH).unwrap(); + cx.guard_registry([&USER_PATH]); cx.config .expect(["rustup-init", "-y"]) @@ -147,9 +149,10 @@ info: default toolchain set to stable-[HOST_TUPLE] #[tokio::test] async fn install_twice() { - let cx = CliTestContext::new(Scenario::SimpleV2).await; + #[cfg_attr(not(windows), allow(unused_mut))] + let mut cx = CliTestContext::new(Scenario::SimpleV2).await; #[cfg(windows)] - let _path_guard = RegistryGuard::new(&USER_PATH).unwrap(); + cx.guard_registry([&USER_PATH]); cx.config.expect(["rustup-init", "-y"]).await.is_ok(); cx.config.expect(["rustup-init", "-y"]).await.is_ok(); From e5fe6c1544706b15ca7c36067006307ec836b930 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:13:28 +0800 Subject: [PATCH 13/15] test(self-update): isolate Programs display version check --- tests/suite/cli_self_upd.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/suite/cli_self_upd.rs b/tests/suite/cli_self_upd.rs index ad8489a849..0786c7be90 100644 --- a/tests/suite/cli_self_upd.rs +++ b/tests/suite/cli_self_upd.rs @@ -481,19 +481,23 @@ async fn update_overwrites_programs_display_version() { const PLACEHOLDER_VERSION: &str = "9.999.99"; let version = env!("CARGO_PKG_VERSION"); - let cx = SelfUpdateTestContext::new(TEST_VERSION).await; - let _guard = RegistryGuard::new(&USER_RUSTUP_VERSION).unwrap(); + let mut cx = SelfUpdateTestContext::new(TEST_VERSION).await; + let guard = RegistryGuard::new([&USER_PATH, &USER_RUSTUP_VERSION]).unwrap(); + cx.config.set_registry_uuid(guard.uuid()); cx.config .expect(["rustup-init", "-y", "--no-modify-path"]) .await .is_ok(); USER_RUSTUP_VERSION - .set(Some(&Value::from(PLACEHOLDER_VERSION))) + .set(Some(&Value::from(PLACEHOLDER_VERSION)), Some(guard.uuid())) .unwrap(); cx.config.expect(["rustup", "self", "update"]).await.is_ok(); assert_eq!( - USER_RUSTUP_VERSION.get().unwrap().unwrap(), + USER_RUSTUP_VERSION + .get(Some(guard.uuid())) + .unwrap() + .unwrap(), Value::from(version) ); } From c4635ae774b7b913eff696be8e66d4468b74395b Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:47:47 +0800 Subject: [PATCH 14/15] style(test): access uuid field directly --- src/cli/self_update/windows.rs | 10 +++------- src/test/clitools.rs | 2 +- tests/suite/cli_paths.rs | 16 ++++++++-------- tests/suite/cli_self_upd.rs | 6 +++--- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/cli/self_update/windows.rs b/src/cli/self_update/windows.rs index c84d01b23b..fe02e4f782 100644 --- a/src/cli/self_update/windows.rs +++ b/src/cli/self_update/windows.rs @@ -797,7 +797,7 @@ fn random_uuid() -> String { /// Guards a set of registry values for the duration of a test. #[cfg(any(test, feature = "test"))] pub struct RegistryGuard { - uuid: String, + pub uuid: String, saved: Vec<(&'static RegistryValueId, Option)>, } @@ -814,10 +814,6 @@ impl RegistryGuard { } Ok(Self { uuid, saved }) } - - pub fn uuid(&self) -> &str { - &self.uuid - } } #[cfg(any(test, feature = "test"))] @@ -893,7 +889,7 @@ mod tests { ("HOME".to_string(), "/unused".to_string()), ( RUSTUP_TEST_REGISTRY_UUID.to_string(), - guard.uuid().to_string(), + guard.uuid.to_string(), ), ] .into_iter() @@ -903,7 +899,7 @@ mod tests { fn test_environment_key(guard: &RegistryGuard) -> Key { CURRENT_USER - .create(map_sub_key("Environment", guard.uuid())) + .create(map_sub_key("Environment", guard.uuid.as_str())) .unwrap() } diff --git a/src/test/clitools.rs b/src/test/clitools.rs index 524480411f..e29ce58063 100644 --- a/src/test/clitools.rs +++ b/src/test/clitools.rs @@ -1000,7 +1000,7 @@ impl CliTestContext { ids: impl IntoIterator, ) { let guard = crate::cli::self_update::RegistryGuard::new(ids).unwrap(); - self.config.set_registry_uuid(guard.uuid()); + self.config.set_registry_uuid(&guard.uuid); self._registry_guard = Some(guard); } diff --git a/tests/suite/cli_paths.rs b/tests/suite/cli_paths.rs index 93a8d43cd1..cd568410cb 100644 --- a/tests/suite/cli_paths.rs +++ b/tests/suite/cli_paths.rs @@ -483,8 +483,8 @@ mod windows { async fn install_uninstall_affect_path() { let mut cx = CliTestContext::new(Scenario::Empty).await; let guard = RegistryGuard::new([&USER_PATH]).unwrap(); - cx.config.set_registry_uuid(guard.uuid()); - let uuid = guard.uuid().to_string(); + cx.config.set_registry_uuid(&guard.uuid); + let uuid = guard.uuid.to_string(); let cfg_path = cx.config.cargodir.join("bin").display().to_string(); let read_path = |uuid: &str| -> Option { retry( @@ -516,8 +516,8 @@ mod windows { async fn uninstall_keeps_path_when_cargo_bin_is_non_empty() { let mut cx = CliTestContext::new(Scenario::Empty).await; let guard = RegistryGuard::new([&USER_PATH]).unwrap(); - cx.config.set_registry_uuid(guard.uuid()); - let uuid = guard.uuid().to_string(); + cx.config.set_registry_uuid(&guard.uuid); + let uuid = guard.uuid.to_string(); let cfg_path = cx.config.cargodir.join("bin").display().to_string(); let get_path_ = || { HSTRING::try_from(get_path(Some(&uuid)).unwrap().unwrap()) @@ -543,8 +543,8 @@ mod windows { async fn uninstall_doesnt_affect_path_with_no_modify_path() { let mut cx = CliTestContext::new(Scenario::Empty).await; let guard = RegistryGuard::new([&USER_PATH]).unwrap(); - cx.config.set_registry_uuid(guard.uuid()); - let uuid = guard.uuid().to_string(); + cx.config.set_registry_uuid(&guard.uuid); + let uuid = guard.uuid.to_string(); let cfg_path = cx.config.cargodir.join("bin").display().to_string(); let get_path_ = || { HSTRING::try_from(get_path(Some(&uuid)).unwrap().unwrap()) @@ -574,8 +574,8 @@ mod windows { let mut cx = CliTestContext::new(Scenario::Empty).await; let guard = RegistryGuard::new([&USER_PATH]).unwrap(); - cx.config.set_registry_uuid(guard.uuid()); - let uuid = guard.uuid().to_string(); + cx.config.set_registry_uuid(&guard.uuid); + let uuid = guard.uuid.to_string(); // Set up a non unicode PATH let mut reg_value = Value::from([ 0x00, 0xD8, // leading surrogate diff --git a/tests/suite/cli_self_upd.rs b/tests/suite/cli_self_upd.rs index 0786c7be90..10ebe1b530 100644 --- a/tests/suite/cli_self_upd.rs +++ b/tests/suite/cli_self_upd.rs @@ -483,19 +483,19 @@ async fn update_overwrites_programs_display_version() { let mut cx = SelfUpdateTestContext::new(TEST_VERSION).await; let guard = RegistryGuard::new([&USER_PATH, &USER_RUSTUP_VERSION]).unwrap(); - cx.config.set_registry_uuid(guard.uuid()); + cx.config.set_registry_uuid(&guard.uuid); cx.config .expect(["rustup-init", "-y", "--no-modify-path"]) .await .is_ok(); USER_RUSTUP_VERSION - .set(Some(&Value::from(PLACEHOLDER_VERSION)), Some(guard.uuid())) + .set(Some(&Value::from(PLACEHOLDER_VERSION)), Some(&guard.uuid)) .unwrap(); cx.config.expect(["rustup", "self", "update"]).await.is_ok(); assert_eq!( USER_RUSTUP_VERSION - .get(Some(guard.uuid())) + .get(Some(&guard.uuid)) .unwrap() .unwrap(), Value::from(version) From 9be439921a25858588eb9c4efad06487610da051 Mon Sep 17 00:00:00 2001 From: baka-gourd <36119339+baka-gourd@users.noreply.github.com> Date: Sun, 21 Jun 2026 22:05:12 +0800 Subject: [PATCH 15/15] style: format code --- tests/suite/cli_self_upd.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/suite/cli_self_upd.rs b/tests/suite/cli_self_upd.rs index 10ebe1b530..38de8d3df8 100644 --- a/tests/suite/cli_self_upd.rs +++ b/tests/suite/cli_self_upd.rs @@ -494,10 +494,7 @@ async fn update_overwrites_programs_display_version() { .unwrap(); cx.config.expect(["rustup", "self", "update"]).await.is_ok(); assert_eq!( - USER_RUSTUP_VERSION - .get(Some(&guard.uuid)) - .unwrap() - .unwrap(), + USER_RUSTUP_VERSION.get(Some(&guard.uuid)).unwrap().unwrap(), Value::from(version) ); }