From 7ded2689486189d8c140b92ca0bfc2f42c1d68f7 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Mon, 23 Sep 2024 22:47:24 -0400 Subject: [PATCH 1/2] test(cargo-rustc): show the current precedence --- tests/testsuite/rustc.rs | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/testsuite/rustc.rs b/tests/testsuite/rustc.rs index be01f14650e..d3718686a79 100644 --- a/tests/testsuite/rustc.rs +++ b/tests/testsuite/rustc.rs @@ -795,3 +795,67 @@ windows ) .run(); } + +#[cargo_test] +fn precedence() { + // Ensure that the precedence of cargo-rustc is only lower than RUSTFLAGS, + // but higher than most flags set by cargo. + // + // See rust-lang/cargo#14346 + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + edition = "2021" + + [lints.rust] + unexpected_cfgs = "allow" + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("rustc --release -v -- --cfg cargo_rustc -C strip=symbols") + .env("RUSTFLAGS", "--cfg from_rustflags") + .with_stderr_data( + str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc [..]--cfg cargo_rustc -C strip=symbols [..]-C strip=debuginfo [..]--cfg from_rustflags` +[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s + +"#]] + ) + .run(); + + // Ensure the short-live env var to work + p.cargo("clean").run(); + p.cargo("rustc --release -v -- --cfg cargo_rustc -C strip=symbols") + .env("RUSTFLAGS", "--cfg from_rustflags") + .env("__CARGO_RUSTC_ORIG_ARGS_PRIO", "1") + .masquerade_as_nightly_cargo(&["cargo-rustc-precedence"]) + .with_stderr_data( + str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc [..]--cfg cargo_rustc -C strip=symbols [..]-C strip=debuginfo [..]--cfg from_rustflags` +[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s + +"#]] + ) + .run(); + + // Ensure non-nightly to work as before + p.cargo("clean").run(); + p.cargo("rustc --release -v -- --cfg cargo_rustc -C strip=symbols") + .env("RUSTFLAGS", "--cfg from_rustflags") + .with_stderr_data( + str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc [..]--cfg cargo_rustc -C strip=symbols [..]-C strip=debuginfo [..]--cfg from_rustflags` +[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s + +"#]] + ) + .run(); +} From 35bb3dee7e71447da74add6177e752c4741f09ff Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Mon, 23 Sep 2024 23:16:39 -0400 Subject: [PATCH 2/2] fix(cargo-rustc): give trailing flags higher precedence Previously `cargo rustc -- ` got a lower precedence than some of the flags set by cargo internal. This is a bit unintuitive as Cargo generally treats user-provided CLI flags with the highest priority. This commit changes `cargo rustc -- ` to a higher precedence: higher than most of flags set by Cargo, and only lower than `build.rustflags` family. Unsure if this affects people's workflow, so this behavior is only enabled on nightly for collectin feedback. A environment variable `__CARGO_RUSTC_ORIG_ARGS_PRIO=1` is provided for users to opt-out. If everything goes well, the nightly gate will be removed after a few of releases. See discussion on https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/rustflags.20precendence.20of.20.60cargo.20rustc.60 --- src/cargo/core/compiler/mod.rs | 39 ++++++++++++++++++++++++++++++---- tests/testsuite/rustc.rs | 9 ++++---- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 8e9e2ac214d..83c918a0332 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -694,6 +694,11 @@ fn prepare_rustc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResult base.inherit_jobserver(&build_runner.jobserver); build_deps_args(&mut base, build_runner, unit)?; add_cap_lints(build_runner.bcx, unit, &mut base); + if cargo_rustc_higher_args_precedence(build_runner) { + if let Some(args) = build_runner.bcx.extra_args_for(unit) { + base.args(args); + } + } base.args(&unit.rustflags); if build_runner.bcx.gctx.cli_unstable().binary_dep_depinfo { base.arg("-Z").arg("binary-dep-depinfo"); @@ -753,8 +758,11 @@ fn prepare_rustdoc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResu } rustdoc.args(unit.pkg.manifest().lint_rustflags()); - if let Some(args) = build_runner.bcx.extra_args_for(unit) { - rustdoc.args(args); + + if !cargo_rustc_higher_args_precedence(build_runner) { + if let Some(args) = build_runner.bcx.extra_args_for(unit) { + rustdoc.args(args); + } } let metadata = build_runner.metadata_for_doc_units[unit]; @@ -795,6 +803,11 @@ fn prepare_rustdoc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResu rustdoc::add_output_format(build_runner, unit, &mut rustdoc)?; + if cargo_rustc_higher_args_precedence(build_runner) { + if let Some(args) = build_runner.bcx.extra_args_for(unit) { + rustdoc.args(args); + } + } rustdoc.args(&unit.rustdocflags); if !crate_version_flag_already_present(&rustdoc) { @@ -1097,8 +1110,10 @@ fn build_base_args( cmd.args(unit.pkg.manifest().lint_rustflags()); cmd.args(&profile_rustflags); - if let Some(args) = build_runner.bcx.extra_args_for(unit) { - cmd.args(args); + if !cargo_rustc_higher_args_precedence(build_runner) { + if let Some(args) = build_runner.bcx.extra_args_for(unit) { + cmd.args(args); + } } // `-C overflow-checks` is implied by the setting of `-C debug-assertions`, @@ -1969,3 +1984,19 @@ fn scrape_output_path(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoR .outputs(unit) .map(|outputs| outputs[0].path.clone()) } + +/// Provides a way to change the precedence of `cargo rustc -- `. +/// +/// This is intended to be a short-live function. +/// +/// See +fn cargo_rustc_higher_args_precedence(build_runner: &BuildRunner<'_, '_>) -> bool { + build_runner.bcx.gctx.nightly_features_allowed + && build_runner + .bcx + .gctx + .get_env("__CARGO_RUSTC_ORIG_ARGS_PRIO") + .ok() + .as_deref() + != Some("1") +} diff --git a/tests/testsuite/rustc.rs b/tests/testsuite/rustc.rs index d3718686a79..71ca898ae16 100644 --- a/tests/testsuite/rustc.rs +++ b/tests/testsuite/rustc.rs @@ -819,14 +819,13 @@ fn precedence() { p.cargo("rustc --release -v -- --cfg cargo_rustc -C strip=symbols") .env("RUSTFLAGS", "--cfg from_rustflags") - .with_stderr_data( - str![[r#" + .masquerade_as_nightly_cargo(&["cargo-rustc-precedence"]) + .with_stderr_data(str![[r#" [COMPILING] foo v0.0.0 ([ROOT]/foo) -[RUNNING] `rustc [..]--cfg cargo_rustc -C strip=symbols [..]-C strip=debuginfo [..]--cfg from_rustflags` +[RUNNING] `rustc [..]-C strip=debuginfo [..]--cfg cargo_rustc -C strip=symbols --cfg from_rustflags` [FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s -"#]] - ) +"#]]) .run(); // Ensure the short-live env var to work