@@ -114,6 +114,41 @@ impl Display for OverrideReason {
114
114
}
115
115
}
116
116
117
+ /// Calls Toolchain::new(), but augments the error message with more context
118
+ /// from the OverrideReason if the toolchain isn't installed.
119
+ pub ( crate ) fn new_toolchain_with_reason < ' a > (
120
+ cfg : & ' a Cfg ,
121
+ name : LocalToolchainName ,
122
+ reason : & OverrideReason ,
123
+ ) -> Result < Toolchain < ' a > > {
124
+ match Toolchain :: new ( cfg, name. clone ( ) ) {
125
+ Err ( RustupError :: ToolchainNotInstalled ( _) ) => ( ) ,
126
+ result => {
127
+ return Ok ( result?) ;
128
+ }
129
+ }
130
+
131
+ let reason_err = match reason {
132
+ OverrideReason :: Environment => {
133
+ "the RUSTUP_TOOLCHAIN environment variable specifies an uninstalled toolchain"
134
+ . to_string ( )
135
+ }
136
+ OverrideReason :: CommandLine => {
137
+ "the +toolchain on the command line specifies an uninstalled toolchain" . to_string ( )
138
+ }
139
+ OverrideReason :: OverrideDB ( ref path) => format ! (
140
+ "the directory override for '{}' specifies an uninstalled toolchain" ,
141
+ utils:: canonicalize_path( path, cfg. notify_handler. as_ref( ) ) . display( ) ,
142
+ ) ,
143
+ OverrideReason :: ToolchainFile ( ref path) => format ! (
144
+ "the toolchain file at '{}' specifies an uninstalled toolchain" ,
145
+ utils:: canonicalize_path( path, cfg. notify_handler. as_ref( ) ) . display( ) ,
146
+ ) ,
147
+ } ;
148
+
149
+ Err ( anyhow ! ( reason_err) . context ( format ! ( "override toolchain '{name}' is not installed" ) ) )
150
+ }
151
+
117
152
#[ derive( Default , Debug ) ]
118
153
struct OverrideCfg {
119
154
toolchain : Option < LocalToolchainName > ,
@@ -480,29 +515,6 @@ impl Cfg {
480
515
}
481
516
482
517
if let Some ( ( file, reason) ) = override_ {
483
- // This is hackishly using the error chain to provide a bit of
484
- // extra context about what went wrong. The CLI will display it
485
- // on a line after the proximate error.
486
-
487
- let reason_err = match reason {
488
- OverrideReason :: Environment => {
489
- "the RUSTUP_TOOLCHAIN environment variable specifies an uninstalled toolchain"
490
- . to_string ( )
491
- }
492
- OverrideReason :: CommandLine => {
493
- "the +toolchain on the command line specifies an uninstalled toolchain"
494
- . to_string ( )
495
- }
496
- OverrideReason :: OverrideDB ( ref path) => format ! (
497
- "the directory override for '{}' specifies an uninstalled toolchain" ,
498
- utils:: canonicalize_path( path, self . notify_handler. as_ref( ) ) . display( ) ,
499
- ) ,
500
- OverrideReason :: ToolchainFile ( ref path) => format ! (
501
- "the toolchain file at '{}' specifies an uninstalled toolchain" ,
502
- utils:: canonicalize_path( path, self . notify_handler. as_ref( ) ) . display( ) ,
503
- ) ,
504
- } ;
505
-
506
518
let override_cfg = OverrideCfg :: from_file ( self , file) ?;
507
519
// Overridden toolchains can be literally any string, but only
508
520
// distributable toolchains will be auto-installed by the wrapping
@@ -511,14 +523,7 @@ impl Cfg {
511
523
match & override_cfg. toolchain {
512
524
Some ( t @ LocalToolchainName :: Named ( ToolchainName :: Custom ( _) ) )
513
525
| Some ( t @ LocalToolchainName :: Path ( _) ) => {
514
- if let Err ( RustupError :: ToolchainNotInstalled ( _) ) =
515
- Toolchain :: new ( self , t. to_owned ( ) )
516
- {
517
- // Strip the confusing NotADirectory error and only mention that the
518
- // override toolchain is not installed.
519
- return Err ( anyhow ! ( reason_err) )
520
- . with_context ( || format ! ( "override toolchain '{t}' is not installed" ) ) ;
521
- }
526
+ new_toolchain_with_reason ( self , t. clone ( ) , & reason) ?;
522
527
}
523
528
// Either official (can auto install) or no toolchain specified
524
529
_ => { }
0 commit comments