Skip to content

Commit 4109e11

Browse files
committed
Use specific check-cfg args if provided for each unit
1 parent 936cac1 commit 4109e11

File tree

3 files changed

+150
-28
lines changed

3 files changed

+150
-28
lines changed

src/cargo/core/compiler/build_context/target_info.rs

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,45 @@ pub enum ExpectedValues<T> {
7676
}
7777

7878
impl CheckCfg {
79+
pub fn new(
80+
gctx: &GlobalContext,
81+
rustc: &Rustc,
82+
extra_args: Option<&[String]>,
83+
) -> CargoResult<CheckCfg> {
84+
let mut process = rustc.workspace_process();
85+
86+
apply_env_config(gctx, &mut process)?;
87+
process
88+
.arg("-")
89+
.arg("--print=check-cfg")
90+
.arg("--check-cfg=cfg()")
91+
.arg("-Zunstable-options")
92+
.env_remove("RUSTC_LOG");
93+
94+
if let Some(extra_args) = extra_args {
95+
process.args(extra_args);
96+
}
97+
98+
// Removes `FD_CLOEXEC` set by `jobserver::Client` to pass jobserver
99+
// as environment variables specify.
100+
if let Some(client) = gctx.jobserver_from_env() {
101+
process.inherit_jobserver(client);
102+
}
103+
104+
let (output, _error) = rustc
105+
.cached_output(&process, 0)
106+
.with_context(|| "failed to run `rustc` to learn about check-cfg information")?;
107+
108+
let lines = output.lines();
109+
let mut check_cfg = CheckCfg::default();
110+
check_cfg.exhaustive = true;
111+
112+
Ok(lines.fold(check_cfg, |mut check_cfg, line| {
113+
check_cfg.process_line(line);
114+
check_cfg
115+
}))
116+
}
117+
79118
fn process_line(&mut self, line: &str) {
80119
if line == "any()=any()" || line == "any()" {
81120
self.exhaustive = false;
@@ -945,7 +984,7 @@ pub struct RustcTargetData<'gctx> {
945984
/// Information about the target platform that we're building for.
946985
target_info: HashMap<CompileTarget, TargetInfo>,
947986

948-
/// `--print=cfg`
987+
/// `--print=check-cfg`
949988
check_cfg: Option<CheckCfg>,
950989
}
951990

@@ -994,32 +1033,7 @@ impl<'gctx> RustcTargetData<'gctx> {
9941033
};
9951034

9961035
let check_cfg = if gctx.cli_unstable().check_target_cfgs {
997-
let mut process = rustc.workspace_process();
998-
999-
apply_env_config(gctx, &mut process)?;
1000-
process
1001-
.arg("-")
1002-
.arg("--print=check-cfg")
1003-
.arg("--check-cfg=cfg()")
1004-
.arg("-Zunstable-options")
1005-
.env_remove("RUSTC_LOG");
1006-
1007-
// Removes `FD_CLOEXEC` set by `jobserver::Client` to pass jobserver
1008-
// as environment variables specify.
1009-
if let Some(client) = gctx.jobserver_from_env() {
1010-
process.inherit_jobserver(client);
1011-
}
1012-
1013-
let (output, _error) = rustc
1014-
.cached_output(&process, 0)
1015-
.with_context(|| "failed to run `rustc` to learn about check-cfg information")?;
1016-
1017-
let lines = output.lines();
1018-
1019-
Some(lines.fold(CheckCfg::default(), |mut check_cfg, line| {
1020-
check_cfg.process_line(line);
1021-
check_cfg
1022-
}))
1036+
Some(CheckCfg::new(gctx, &rustc, None)?)
10231037
} else {
10241038
None
10251039
};

src/cargo/ops/cargo_compile/mod.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use crate::ops;
5757
use crate::ops::resolve::WorkspaceResolve;
5858
use crate::util::context::GlobalContext;
5959
use crate::util::interning::InternedString;
60-
use crate::util::{CargoResult, StableHasher};
60+
use crate::util::{CargoResult, Rustc, StableHasher};
6161

6262
mod compile_filter;
6363
use cargo_platform::{Cfg, CfgExpr, Platform};
@@ -501,6 +501,14 @@ pub fn create_bcx<'a, 'gctx>(
501501
continue;
502502
}
503503

504+
let specific_check_cfg =
505+
get_specific_check_cfg_for_unit(gctx, &target_data.rustc, unit)?;
506+
let check_cfg = specific_check_cfg.as_ref().unwrap_or(check_cfg);
507+
508+
if !check_cfg.exhaustive {
509+
continue;
510+
}
511+
504512
for dep in unit.pkg.summary().dependencies() {
505513
let Some(platform) = dep.platform() else {
506514
continue;
@@ -587,6 +595,20 @@ where `<compatible-ver>` is the latest version supporting rustc {rustc_version}"
587595
Ok(bcx)
588596
}
589597

598+
fn get_specific_check_cfg_for_unit<'a>(
599+
gctx: &GlobalContext,
600+
rustc: &Rustc,
601+
unit: &Unit,
602+
) -> CargoResult<Option<CheckCfg>> {
603+
let lint_rustflags = unit.pkg.manifest().lint_rustflags();
604+
605+
if lint_rustflags.iter().any(|a| a == "--check-cfg") {
606+
Ok(Some(CheckCfg::new(gctx, rustc, Some(lint_rustflags))?))
607+
} else {
608+
Ok(None)
609+
}
610+
}
611+
590612
fn warn_on_unexpected_cfgs(
591613
gctx: &GlobalContext,
592614
check_cfg: &CheckCfg,

tests/testsuite/cfg.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,92 @@ fn unexpected_cfgs_target() {
585585
.run();
586586
}
587587

588+
#[cargo_test(nightly, reason = "--print=check-cfg is unstable in rustc")]
589+
fn unexpected_cfgs_target_with_lint() {
590+
let p = project()
591+
.file(
592+
"Cargo.toml",
593+
r#"
594+
[package]
595+
name = "a"
596+
version = "0.0.1"
597+
edition = "2015"
598+
authors = []
599+
600+
[target."cfg(foo)".dependencies] # should not warn here
601+
b = { path = 'b' }
602+
603+
[target.'cfg(foo = "foo")'.dependencies] # should not warn here
604+
b = { path = 'b' }
605+
606+
[target."cfg(bar)".dependencies]
607+
b = { path = 'b' }
608+
609+
[lints.rust.unexpected_cfgs]
610+
level = "warn"
611+
check-cfg = ['cfg(foo, values(none(), "foo"))'] # because of this line
612+
"#,
613+
)
614+
.file(
615+
".cargo/config.toml",
616+
r#"
617+
[target."cfg(foo)"] # but it doesn't have an effect here
618+
"#,
619+
)
620+
.file("src/lib.rs", "")
621+
.file("b/Cargo.toml", &basic_manifest("b", "0.0.1"))
622+
.file("b/src/lib.rs", "")
623+
.build();
624+
625+
p.cargo("check -Zcheck-target-cfgs")
626+
.masquerade_as_nightly_cargo(&["requires -Zcheck-target-cfgs"])
627+
.with_stderr_data(str![[r#"
628+
[LOCKING] 1 package to latest compatible version
629+
[WARNING] unexpected `cfg` condition name: `foo` in `[target.'cfg(foo)']`
630+
[WARNING] [ROOT]/foo/Cargo.toml: unexpected `cfg` condition name: `bar` in `[target.'cfg(bar)'.dependencies]`
631+
[CHECKING] a v0.0.1 ([ROOT]/foo)
632+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
633+
634+
"#]])
635+
.run();
636+
}
637+
638+
#[cargo_test(nightly, reason = "--print=check-cfg is unstable in rustc")]
639+
fn unexpected_cfgs_target_cfg_any() {
640+
let p = project()
641+
.file(
642+
"Cargo.toml",
643+
r#"
644+
[package]
645+
name = "a"
646+
version = "0.0.1"
647+
edition = "2015"
648+
authors = []
649+
650+
[target."cfg(foo)".dependencies]
651+
b = { path = 'b' }
652+
653+
[lints.rust.unexpected_cfgs]
654+
level = "deny"
655+
check-cfg = ["cfg(any())"]
656+
"#,
657+
)
658+
.file("src/lib.rs", "")
659+
.file("b/Cargo.toml", &basic_manifest("b", "0.0.1"))
660+
.file("b/src/lib.rs", "")
661+
.build();
662+
663+
p.cargo("check -Zcheck-target-cfgs")
664+
.masquerade_as_nightly_cargo(&["requires -Zcheck-target-cfgs"])
665+
.with_stderr_data(str![[r#"
666+
[LOCKING] 1 package to latest compatible version
667+
[CHECKING] a v0.0.1 ([ROOT]/foo)
668+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
669+
670+
"#]])
671+
.run();
672+
}
673+
588674
#[cargo_test]
589675
fn no_unexpected_cfgs_target() {
590676
let p = project()

0 commit comments

Comments
 (0)