11use std:: collections:: { BTreeMap , BTreeSet , HashMap , HashSet } ;
22use std:: path:: { Path , PathBuf } ;
33use std:: sync:: Arc ;
4- use std:: { env, fs} ;
4+ use std:: { env, fmt , fs} ;
55
66use crate :: core:: compiler:: { CompileKind , DefaultExecutor , Executor , UnitOutput } ;
77use crate :: core:: { Dependency , Edition , Package , PackageId , SourceId , Target , Workspace } ;
@@ -14,6 +14,7 @@ use crate::util::errors::CargoResult;
1414use crate :: util:: { Filesystem , GlobalContext , Rustc } ;
1515use crate :: { drop_println, ops} ;
1616
17+ use annotate_snippets:: Level ;
1718use anyhow:: { Context as _, bail} ;
1819use cargo_util:: paths;
1920use cargo_util_schemas:: core:: PartialVersion ;
@@ -39,6 +40,26 @@ impl Drop for Transaction {
3940 }
4041}
4142
43+ enum RustupToolchainSource {
44+ Default ,
45+ Environment ,
46+ CommandLine ,
47+ OverrideDB ,
48+ ToolchainFile ,
49+ }
50+
51+ impl fmt:: Display for RustupToolchainSource {
52+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
53+ f. write_str ( match self {
54+ Self :: Default => "default" ,
55+ Self :: Environment => "env" ,
56+ Self :: CommandLine => "cli" ,
57+ Self :: OverrideDB => "path-override" ,
58+ Self :: ToolchainFile => "toolchain-file" ,
59+ } )
60+ }
61+ }
62+
4263struct InstallablePackage < ' gctx > {
4364 gctx : & ' gctx GlobalContext ,
4465 opts : ops:: CompileOptions ,
@@ -316,6 +337,28 @@ impl<'gctx> InstallablePackage<'gctx> {
316337 fn install_one ( mut self , dry_run : bool ) -> CargoResult < bool > {
317338 self . gctx . shell ( ) . status ( "Installing" , & self . pkg ) ?;
318339
340+ if let Some ( source) = self . get_rustup_toolchain_source ( )
341+ && !matches ! (
342+ source,
343+ RustupToolchainSource :: Default | RustupToolchainSource :: CommandLine
344+ )
345+ {
346+ let maybe_toolchain = self
347+ . gctx
348+ . get_env ( "RUSTUP_TOOLCHAIN" )
349+ . ok ( )
350+ . map ( |toolchain| format ! ( " `{toolchain}`" ) )
351+ . unwrap_or_default ( ) ;
352+ let report = & [ Level :: WARNING
353+ . primary_title ( format ! (
354+ "using non-default toolchain{maybe_toolchain} overridden by {source}"
355+ ) )
356+ . element ( Level :: HELP . message ( format ! (
357+ "Use `cargo +stable install` if you meant to use the stable toolchain."
358+ ) ) ) ] ;
359+ self . gctx . shell ( ) . print_report ( report, false ) ?;
360+ }
361+
319362 let dst = self . root . join ( "bin" ) . into_path_unlocked ( ) ;
320363
321364 let mut td_opt = None ;
@@ -585,6 +628,20 @@ impl<'gctx> InstallablePackage<'gctx> {
585628 }
586629 }
587630
631+ fn get_rustup_toolchain_source ( & self ) -> Option < RustupToolchainSource > {
632+ self . gctx
633+ . get_env ( "RUSTUP_TOOLCHAIN_SOURCE" )
634+ . ok ( )
635+ . and_then ( |val| match val {
636+ "default" => Some ( RustupToolchainSource :: Default ) ,
637+ "env" => Some ( RustupToolchainSource :: Environment ) ,
638+ "cli" => Some ( RustupToolchainSource :: CommandLine ) ,
639+ "path-override" => Some ( RustupToolchainSource :: OverrideDB ) ,
640+ "toolchain-file" => Some ( RustupToolchainSource :: ToolchainFile ) ,
641+ _ => None ,
642+ } )
643+ }
644+
588645 fn check_yanked_install ( & self ) -> CargoResult < ( ) > {
589646 if self . ws . ignore_lock ( ) || !self . ws . root ( ) . join ( "Cargo.lock" ) . exists ( ) {
590647 return Ok ( ( ) ) ;
0 commit comments