diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index 091e41734e..b35bd6b817 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -858,13 +858,13 @@ async fn default_( cfg.set_default(Some(&toolchain_name.into()))?; } MaybeResolvableToolchainName::Some(ResolvableToolchainName::Official(toolchain)) => { - let desc = toolchain.resolve(&cfg.default_host_tuple()?)?; + let desc = toolchain.clone().resolve(&cfg.default_host_tuple()?)?; let status = cfg .ensure_installed(&desc, vec![], vec![], None, force_non_host, true) .await? .status; - cfg.set_default(Some(&desc.clone().into()))?; + cfg.set_default(Some(&toolchain.into()))?; writeln!(cfg.process.stdout().lock())?; @@ -1063,7 +1063,7 @@ async fn update( force_non_host, )?; } - let desc = name.resolve(&cfg.default_host_tuple()?)?; + let desc = name.clone().resolve(&cfg.default_host_tuple()?)?; let components = opts.component.iter().map(|s| &**s).collect::>(); let targets = opts.target.iter().map(|s| &**s).collect::>(); @@ -1104,7 +1104,7 @@ async fn update( } if cfg.get_default()?.is_none() && matches!(status, UpdateStatus::Installed) { - cfg.set_default(Some(&desc.into()))?; + cfg.set_default(Some(&name.into()))?; } } exit_code &= self_update_mode.update(should_self_update, &dl_cfg).await?; diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index ef1e0a950c..38d1e6ec46 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -70,7 +70,6 @@ use crate::{ process::Process, toolchain::{ DistributableToolchain, MaybeOfficialToolchainName, ResolvableToolchainName, Toolchain, - ToolchainName, }, utils::{self, ExitCode}, }; @@ -107,7 +106,7 @@ pub(crate) struct InstallOpts<'a> { } impl InstallOpts<'_> { - fn install(self, cfg: &mut Cfg<'_>) -> Result> { + fn install(self, cfg: &mut Cfg<'_>) -> Result> { let Self { default_host_tuple, default_toolchain, @@ -165,18 +164,14 @@ impl InstallOpts<'_> { MaybeOfficialToolchainName::None => unreachable!(), MaybeOfficialToolchainName::Some(n) => n, }; - Some(toolchain_name.resolve(&cfg.default_host_tuple()?)?) + Some(toolchain_name) } - None => match cfg.get_default()? { + None => match cfg.get_default_resolvable()? { // Default is installable - Some(ToolchainName::Official(t)) => Some(t), + Some(ResolvableToolchainName::Official(t)) => Some(t), // Default is custom, presumably from a prior install. Do nothing. - Some(ToolchainName::Custom(_)) => None, - None => Some( - "stable" - .parse::()? - .resolve(&cfg.default_host_tuple()?)?, - ), + Some(ResolvableToolchainName::Custom(_)) => None, + None => Some(PartialToolchainDesc::from_str("stable")?), }, }) } else { @@ -1022,7 +1017,8 @@ async fn maybe_install_rust(opts: InstallOpts<'_>, cfg: &mut Cfg<'_>) -> Result< let (components, targets) = (opts.components, opts.targets); let toolchain = opts.install(cfg)?; - if let Some(desc) = &toolchain { + if let Some(partial_desc) = toolchain { + let desc = &partial_desc.clone().resolve(&cfg.default_host_tuple()?)?; let options = DistOptions::new(components, targets, desc, cfg.get_profile()?, true, cfg)?; let status = if Toolchain::exists(cfg, &desc.into())? { warn!("Updating existing toolchain, profile choice will be ignored"); @@ -1041,7 +1037,7 @@ async fn maybe_install_rust(opts: InstallOpts<'_>, cfg: &mut Cfg<'_>) -> Result< check_proxy_sanity(cfg.process, components, desc)?; - cfg.set_default(Some(&desc.clone().into()))?; + cfg.set_default(Some(&partial_desc.into()))?; writeln!(cfg.process.stdout().lock())?; common::show_channel_update(cfg, PackageUpdate::Toolchain(desc.clone()), Ok(status))?; } @@ -1521,11 +1517,7 @@ mod tests { }; assert_eq!( - "stable" - .parse::() - .unwrap() - .resolve(&cfg.default_host_tuple().unwrap()) - .unwrap(), + "stable".parse::().unwrap(), opts.install(&mut cfg) .unwrap() // result .unwrap() // option diff --git a/src/config.rs b/src/config.rs index 7797e7ab59..dd54e1c0fe 100644 --- a/src/config.rs +++ b/src/config.rs @@ -380,7 +380,7 @@ impl<'a> Cfg<'a> { Ok(cfg) } - pub(crate) fn set_default(&self, toolchain: Option<&ToolchainName>) -> Result<()> { + pub(crate) fn set_default(&self, toolchain: Option<&ResolvableToolchainName>) -> Result<()> { self.settings_file.with_mut(|s| { s.default_toolchain = toolchain.map(|t| t.to_string()); Ok(()) @@ -891,6 +891,16 @@ impl<'a> Cfg<'a> { /// If none is configured, returns None /// If a bad toolchain name is configured, errors. pub(crate) fn get_default(&self) -> Result> { + let Some(toolchain) = self.get_default_resolvable()? else { + return Ok(None); + }; + Ok(Some(toolchain.resolve(&self.default_host_tuple()?)?)) + } + + /// Gets the configured default toolchain. + /// If none is configured, returns None + /// If a bad toolchain name is configured, errors. + pub(crate) fn get_default_resolvable(&self) -> Result> { let user_opt = self.settings_file.with(|s| Ok(s.default_toolchain.clone())); let toolchain_maybe_str = if let Some(fallback_settings) = &self.fallback_settings { match user_opt { @@ -900,11 +910,10 @@ impl<'a> Cfg<'a> { } else { user_opt }?; - toolchain_maybe_str - .map(ResolvableToolchainName::try_from) - .transpose()? - .map(|t| t.resolve(&self.default_host_tuple()?)) - .transpose() + let Some(toolchain) = toolchain_maybe_str else { + return Ok(None); + }; + Ok(Some(ResolvableToolchainName::try_from(toolchain)?)) } /// List all the installed toolchains: that is paths in the toolchain dir diff --git a/src/toolchain/names.rs b/src/toolchain/names.rs index 37d92b9912..e80c503d8b 100644 --- a/src/toolchain/names.rs +++ b/src/toolchain/names.rs @@ -304,6 +304,17 @@ impl ResolvableLocalToolchainName { } } +from_variant!( + PartialToolchainDesc, + ResolvableToolchainName, + ResolvableToolchainName::Official +); +from_variant!( + CustomToolchainName, + ResolvableToolchainName, + ResolvableToolchainName::Custom +); + try_from_str!(ResolvableLocalToolchainName); impl Display for ResolvableLocalToolchainName {