@@ -397,15 +397,41 @@ fn get_local_toolchain(
397397 // + prefixed rustc is an indicator to fetch the rustc of the toolchain
398398 // specified. This follows the similar pattern used by rustup's binaries
399399 // (e.g., `rustc +stage1`).
400- let rustc = if rustc. starts_with ( '+' ) {
401- let s = String :: from_utf8 (
402- Command :: new ( "rustup" )
403- . args ( & [ "which" , "rustc" , "--toolchain" , & rustc[ 1 ..] ] )
404- . output ( )
400+ let rustc = if let Some ( toolchain) = rustc. strip_prefix ( '+' ) {
401+ let output = Command :: new ( "rustup" )
402+ . args ( & [ "which" , "rustc" , "--toolchain" , & toolchain] )
403+ . output ( )
404+ . context ( "failed to run `rustup which rustc`" ) ?;
405+
406+ // Looks like a commit hash? Try to install it...
407+ if output. status . code ( ) == Some ( 101 ) && toolchain. len ( ) == 40 {
408+ // No such toolchain exists, so let's try to install it with
409+ // rustup-toolchain-install-master.
410+
411+ if !Command :: new ( "rustup-toolchain-install-master" )
412+ . arg ( & toolchain)
413+ . status ( )
405414 . context ( "failed to run `rustup which rustc`" ) ?
406- . stdout ,
407- )
408- . context ( "failed to convert `rustup which rustc` output to utf8" ) ?;
415+ . success ( )
416+ {
417+ anyhow:: bail!(
418+ "commit-like toolchain {} did not install successfully" ,
419+ toolchain
420+ )
421+ }
422+ }
423+
424+ let output = Command :: new ( "rustup" )
425+ . args ( & [ "which" , "rustc" , "--toolchain" , & toolchain] )
426+ . output ( )
427+ . context ( "failed to run `rustup which rustc`" ) ?;
428+
429+ if !output. status . success ( ) {
430+ anyhow:: bail!( "did not manage to obtain toolchain {}" , toolchain) ;
431+ }
432+
433+ let s = String :: from_utf8 ( output. stdout )
434+ . context ( "failed to convert `rustup which rustc` output to utf8" ) ?;
409435
410436 let rustc = PathBuf :: from ( s. trim ( ) ) ;
411437 debug ! ( "found rustc: {:?}" , & rustc) ;
0 commit comments