Skip to content

Commit 5aee235

Browse files
committed
Implement 11036 cargo changes
1 parent f59db31 commit 5aee235

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

src/cargo/ops/cargo_install.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
22
use std::path::{Path, PathBuf};
33
use std::sync::Arc;
4-
use std::{env, fs};
4+
use std::{env, fmt, fs};
55

66
use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, UnitOutput};
77
use crate::core::{Dependency, Edition, Package, PackageId, SourceId, Target, Workspace};
@@ -14,6 +14,7 @@ use crate::util::errors::CargoResult;
1414
use crate::util::{Filesystem, GlobalContext, Rustc};
1515
use crate::{drop_println, ops};
1616

17+
use annotate_snippets::Level;
1718
use anyhow::{Context as _, bail};
1819
use cargo_util::paths;
1920
use cargo_util_schemas::core::PartialVersion;
@@ -39,6 +40,42 @@ impl Drop for Transaction {
3940
}
4041
}
4142

43+
enum RustupToolchainSource {
44+
Default,
45+
Environment,
46+
CommandLine,
47+
OverrideDB,
48+
ToolchainFile,
49+
Other(String),
50+
}
51+
52+
#[allow(dead_code)]
53+
impl RustupToolchainSource {
54+
fn is_implicit_override(&self) -> bool {
55+
match self {
56+
Self::Default => false,
57+
Self::Environment => true,
58+
Self::CommandLine => false,
59+
Self::OverrideDB => true,
60+
Self::ToolchainFile => true,
61+
Self::Other(_) => true,
62+
}
63+
}
64+
}
65+
66+
impl fmt::Display for RustupToolchainSource {
67+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68+
f.write_str(match self {
69+
Self::Default => "default",
70+
Self::Environment => "environment variable",
71+
Self::CommandLine => "command line",
72+
Self::OverrideDB => "rustup directory override",
73+
Self::ToolchainFile => "rustup toolchain file",
74+
Self::Other(other) => other,
75+
})
76+
}
77+
}
78+
4279
struct InstallablePackage<'gctx> {
4380
gctx: &'gctx GlobalContext,
4481
opts: ops::CompileOptions,
@@ -316,6 +353,28 @@ impl<'gctx> InstallablePackage<'gctx> {
316353
fn install_one(mut self, dry_run: bool) -> CargoResult<bool> {
317354
self.gctx.shell().status("Installing", &self.pkg)?;
318355

356+
if let Some(source) = get_rustup_toolchain_source()
357+
&& source.is_implicit_override()
358+
{
359+
#[expect(clippy::disallowed_methods, reason = "consistency with rustup")]
360+
let maybe_toolchain = env::var("RUSTUP_TOOLCHAIN")
361+
.ok()
362+
.map(|toolchain| format!(" with `{toolchain}`"))
363+
.unwrap_or_default();
364+
let report = &[Level::WARNING
365+
.secondary_title(format!(
366+
"default toolchain implicitly overridden{maybe_toolchain} by {source}"
367+
))
368+
.element(Level::HELP.message(format!(
369+
"use `cargo +stable install` if you meant to use the stable toolchain"
370+
)))
371+
.element(Level::NOTE.message(format!(
372+
"rustup selects the toolchain based on the parent environment and not the \
373+
environment of the package being installed"
374+
)))];
375+
self.gctx.shell().print_report(report, false)?;
376+
}
377+
319378
// Normalize to absolute path for consistency throughout.
320379
// See: https://github.com/rust-lang/cargo/issues/16023
321380
let dst = self.root.join("bin").into_path_unlocked();
@@ -611,6 +670,20 @@ impl<'gctx> InstallablePackage<'gctx> {
611670
}
612671
}
613672

673+
fn get_rustup_toolchain_source() -> Option<RustupToolchainSource> {
674+
#[expect(clippy::disallowed_methods, reason = "consistency with rustup")]
675+
let source = std::env::var("RUSTUP_TOOLCHAIN_SOURCE").ok()?;
676+
let source = match source.as_str() {
677+
"default" => RustupToolchainSource::Default,
678+
"env" => RustupToolchainSource::Environment,
679+
"cli" => RustupToolchainSource::CommandLine,
680+
"path-override" => RustupToolchainSource::OverrideDB,
681+
"toolchain-file" => RustupToolchainSource::ToolchainFile,
682+
other => RustupToolchainSource::Other(other.to_owned()),
683+
};
684+
Some(source)
685+
}
686+
614687
fn make_warning_about_missing_features(binaries: &[&Target]) -> String {
615688
let max_targets_listed = 7;
616689
let target_features_message = binaries

tests/testsuite/rustup.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ fn real_rustc_wrapper(bin_dir: &Path, message: &str) -> PathBuf {
5959
// The toolchain rustc needs to call the real rustc. In order to do that,
6060
// it needs to restore or clear the RUSTUP environment variables so that
6161
// if rustup is installed, it will call the correct rustc.
62+
let rustup_toolchain_source_setup = match std::env::var_os("RUSTUP_TOOLCHAIN_SOURCE") {
63+
Some(t) => format!(
64+
".env(\"RUSTUP_TOOLCHAIN_SOURCE\", \"{}\")",
65+
t.into_string().unwrap()
66+
),
67+
None => String::new(),
68+
};
6269
let rustup_toolchain_setup = match std::env::var_os("RUSTUP_TOOLCHAIN") {
6370
Some(t) => format!(
6471
".env(\"RUSTUP_TOOLCHAIN\", \"{}\")",
@@ -82,6 +89,7 @@ fn real_rustc_wrapper(bin_dir: &Path, message: &str) -> PathBuf {
8289
eprintln!("{message}");
8390
let r = std::process::Command::new(env!("CARGO_RUSTUP_TEST_real_rustc"))
8491
.args(std::env::args_os().skip(1))
92+
{rustup_toolchain_source_setup}
8593
{rustup_toolchain_setup}
8694
{rustup_home_setup}
8795
.status();
@@ -390,6 +398,10 @@ fn cargo_install_with_toolchain_source_env() {
390398
[DOWNLOADING] crates ...
391399
[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
392400
[INSTALLING] foo v0.0.1
401+
[WARNING] default toolchain implicitly overridden with `test-toolchain` by environment variable
402+
|
403+
= [HELP] use `cargo +stable install` if you meant to use the stable toolchain
404+
= [NOTE] rustup selects the toolchain based on the parent environment and not the environment of the package being installed
393405
[COMPILING] foo v0.0.1
394406
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
395407
[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
@@ -410,6 +422,10 @@ fn cargo_install_with_toolchain_source_path_override() {
410422
[DOWNLOADING] crates ...
411423
[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
412424
[INSTALLING] foo v0.0.1
425+
[WARNING] default toolchain implicitly overridden with `test-toolchain` by rustup directory override
426+
|
427+
= [HELP] use `cargo +stable install` if you meant to use the stable toolchain
428+
= [NOTE] rustup selects the toolchain based on the parent environment and not the environment of the package being installed
413429
[COMPILING] foo v0.0.1
414430
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
415431
[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
@@ -430,6 +446,10 @@ fn cargo_install_with_toolchain_source_toolchain_file() {
430446
[DOWNLOADING] crates ...
431447
[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
432448
[INSTALLING] foo v0.0.1
449+
[WARNING] default toolchain implicitly overridden with `test-toolchain` by rustup toolchain file
450+
|
451+
= [HELP] use `cargo +stable install` if you meant to use the stable toolchain
452+
= [NOTE] rustup selects the toolchain based on the parent environment and not the environment of the package being installed
433453
[COMPILING] foo v0.0.1
434454
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
435455
[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
@@ -450,6 +470,10 @@ fn cargo_install_with_toolchain_source_unrecognized() {
450470
[DOWNLOADING] crates ...
451471
[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
452472
[INSTALLING] foo v0.0.1
473+
[WARNING] default toolchain implicitly overridden with `test-toolchain` by unrecognized source
474+
|
475+
= [HELP] use `cargo +stable install` if you meant to use the stable toolchain
476+
= [NOTE] rustup selects the toolchain based on the parent environment and not the environment of the package being installed
453477
[COMPILING] foo v0.0.1
454478
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
455479
[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]

0 commit comments

Comments
 (0)