@@ -23,7 +23,8 @@ use crate::notifications::*;
2323use crate :: process;
2424use crate :: settings:: { Settings , SettingsFile , DEFAULT_METADATA_VERSION } ;
2525use crate :: toolchain:: {
26- LocalToolchainName , PathBasedToolchain , ResolvableToolchainName , ToolchainName ,
26+ LocalToolchainName , PathBasedToolchain , ResolvableLocalToolchainName , ResolvableToolchainName ,
27+ ToolchainName ,
2728} ;
2829use crate :: toolchain_old:: {
2930 InstalledToolchain , OwnedCustomToolchain , OwnedDistributableToolchain , OwnedInstalled ,
@@ -177,7 +178,7 @@ pub(crate) struct Cfg {
177178 pub download_dir : PathBuf ,
178179 pub temp_cfg : temp:: Cfg ,
179180 pub toolchain_override : Option < ResolvableToolchainName > ,
180- pub env_override : Option < String > ,
181+ pub env_override : Option < LocalToolchainName > ,
181182 pub dist_root_url : String ,
182183 pub notify_handler : Arc < dyn Fn ( Notification < ' _ > ) > ,
183184}
@@ -209,11 +210,17 @@ impl Cfg {
209210 let update_hash_dir = rustup_dir. join ( "update-hashes" ) ;
210211 let download_dir = rustup_dir. join ( "downloads" ) ;
211212
213+ // Figure out get_default_host_triple before Config is populated
214+ let default_host_triple = settings_file. with ( |s| Ok ( get_default_host_triple ( s) ) ) ?;
212215 // Environment override
213216 let env_override = process ( )
214217 . var ( "RUSTUP_TOOLCHAIN" )
215218 . ok ( )
216- . and_then ( utils:: if_not_empty) ;
219+ . and_then ( utils:: if_not_empty)
220+ . map ( |s| ResolvableLocalToolchainName :: try_from ( s) )
221+ . transpose ( ) ?
222+ . map ( |t| t. resolve ( & default_host_triple) )
223+ . transpose ( ) ?;
217224
218225 let dist_root_server = match process ( ) . var ( "RUSTUP_DIST_SERVER" ) {
219226 Ok ( ref s) if !s. is_empty ( ) => s. clone ( ) ,
@@ -458,10 +465,7 @@ impl Cfg {
458465 // custom, distributable, and absolute path toolchains otherwise
459466 // rustup's export of a RUSTUP_TOOLCHAIN when running a process will
460467 // error when a nested rustup invocation occurs
461- override_ = Some ( (
462- LocalToolchainName :: try_from ( name) ?. to_string ( ) . into ( ) ,
463- OverrideReason :: Environment ,
464- ) ) ;
468+ override_ = Some ( ( name. to_string ( ) . into ( ) , OverrideReason :: Environment ) ) ;
465469 }
466470
467471 // Then walk up the directory tree from 'path' looking for either the
@@ -574,25 +578,29 @@ impl Cfg {
574578 // internal only safe struct
575579 let override_file = Cfg :: parse_override_file ( contents, parse_mode)
576580 . with_context ( add_file_context) ?;
577- if let Some ( toolchain_name ) = & override_file. toolchain . channel {
578- let toolchain_name =
579- ResolvableToolchainName :: try_from ( & toolchain_name as & str ) ? ;
581+ if let Some ( toolchain_name_str ) = & override_file. toolchain . channel {
582+ let toolchain_name = ResolvableToolchainName :: try_from ( toolchain_name_str ) ? ;
583+ let default_host_triple = get_default_host_triple ( settings ) ;
580584 // Do not permit architecture/os selection in channels as
581585 // these are host specific and toolchain files are portable.
582586 if let ResolvableToolchainName :: Official ( ref name) = toolchain_name {
583587 if name. has_triple ( ) {
584- return Err ( anyhow ! ( format!( "target triple in channel name '{name}'" ) ) ) ;
588+ // Permit fully qualified names IFF the toolchain is installed. TODO(robertc): consider
589+ // disabling this and backing out https://github.com/rust-lang/rustup/pull/2141 (but provide
590+ // the base name in the error to help users)
591+ let resolved_name = & ToolchainName :: try_from ( toolchain_name_str) ?;
592+ let ts = self . list_toolchains ( ) ?;
593+ eprintln ! ( "{resolved_name:?} {ts:?}" ) ;
594+ if !self . list_toolchains ( ) ?. iter ( ) . any ( |s| s == resolved_name) {
595+ return Err ( anyhow ! ( format!(
596+ "target triple in channel name '{name}'"
597+ ) ) ) ;
598+ }
585599 }
586600 }
587601
588602 // XXX: this awkwardness deals with settings file being locked already
589- let toolchain_name = toolchain_name. resolve (
590- & settings
591- . default_host_triple
592- . as_ref ( )
593- . map ( |s| dist:: TargetTriple :: new ( s) )
594- . unwrap_or_else ( dist:: TargetTriple :: from_host_or_build) ,
595- ) ?;
603+ let toolchain_name = toolchain_name. resolve ( & default_host_triple) ?;
596604 let toolchain = Toolchain :: from_name ( self , & ( & toolchain_name) . into ( ) ) ;
597605 if !toolchain. exists ( ) && matches ! ( toolchain_name, ToolchainName :: Custom ( _) ) {
598606 bail ! (
@@ -759,23 +767,19 @@ impl Cfg {
759767 /// List all the installed toolchains: that is paths in the toolchain dir
760768 /// that are:
761769 /// - not files
762- /// - named with a valid toolchain name
770+ /// - named with a valid resolved toolchain name
771+ /// Currently no notification of incorrect names or entry type is done.
763772 #[ cfg_attr( feature = "otel" , tracing:: instrument( skip_all) ) ]
764773 pub ( crate ) fn list_toolchains ( & self ) -> Result < Vec < ToolchainName > > {
765774 if utils:: is_directory ( & self . toolchains_dir ) {
766- let default_host_triple = & self . get_default_host_triple ( ) ?;
767775 let mut toolchains: Vec < _ > = utils:: read_dir ( "toolchains" , & self . toolchains_dir ) ?
768776 // TODO: this discards errors reading the directory, is that
769777 // correct? could we get a short-read and report less toolchains
770778 // than exist?
771779 . filter_map ( io:: Result :: ok)
772780 . filter ( |e| e. file_type ( ) . map ( |f| !f. is_file ( ) ) . unwrap_or ( false ) )
773781 . filter_map ( |e| e. file_name ( ) . into_string ( ) . ok ( ) )
774- . filter_map ( |n| {
775- ResolvableToolchainName :: try_from ( n)
776- . ok ( )
777- . and_then ( |n| n. resolve ( default_host_triple) . ok ( ) )
778- } )
782+ . filter_map ( |n| ToolchainName :: try_from ( & n) . ok ( ) )
779783 . collect ( ) ;
780784
781785 crate :: toolchain:: toolchain_sort ( & mut toolchains) ;
@@ -954,12 +958,7 @@ impl Cfg {
954958 pub ( crate ) fn get_default_host_triple ( & self ) -> Result < dist:: TargetTriple > {
955959 Ok ( self
956960 . settings_file
957- . with ( |s| {
958- Ok ( s. default_host_triple
959- . as_ref ( )
960- . map ( |s| dist:: TargetTriple :: new ( s) ) )
961- } ) ?
962- . unwrap_or_else ( dist:: TargetTriple :: from_host_or_build) )
961+ . with ( |s| Ok ( get_default_host_triple ( s) ) ) ?)
963962 }
964963
965964 pub ( crate ) fn toolchain_path ( & self , toolchain : & LocalToolchainName ) -> PathBuf {
@@ -970,6 +969,13 @@ impl Cfg {
970969 }
971970}
972971
972+ fn get_default_host_triple ( s : & Settings ) -> dist:: TargetTriple {
973+ s. default_host_triple
974+ . as_ref ( )
975+ . map ( |s| dist:: TargetTriple :: new ( s) )
976+ . unwrap_or_else ( dist:: TargetTriple :: from_host_or_build)
977+ }
978+
973979/// Specifies how a `rust-toolchain`/`rust-toolchain.toml` configuration file should be parsed.
974980enum ParseMode {
975981 /// Only permit TOML format in a configuration file.
0 commit comments