Skip to content

Commit ab47bd4

Browse files
committed
Respect [lints.rust.unexpected_cfgs.check-cfg] lint config
1 parent 12dd992 commit ab47bd4

File tree

4 files changed

+56
-29
lines changed

4 files changed

+56
-29
lines changed

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

+41
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,47 @@ impl TargetInfo {
411411
true
412412
}
413413

414+
/// The [`CheckCfg`] settings with extra arguments passed.
415+
pub fn check_cfg_with_extra_args(
416+
&self,
417+
gctx: &GlobalContext,
418+
rustc: &Rustc,
419+
extra_args: &[String],
420+
) -> CargoResult<CheckCfg> {
421+
let mut process = rustc.workspace_process();
422+
423+
apply_env_config(gctx, &mut process)?;
424+
process
425+
.arg("-")
426+
.arg("--print=check-cfg")
427+
.arg("--check-cfg=cfg()")
428+
.arg("-Zunstable-options")
429+
.args(&self.rustflags)
430+
.args(extra_args)
431+
.env_remove("RUSTC_LOG");
432+
433+
// Removes `FD_CLOEXEC` set by `jobserver::Client` to pass jobserver
434+
// as environment variables specify.
435+
if let Some(client) = gctx.jobserver_from_env() {
436+
process.inherit_jobserver(client);
437+
}
438+
439+
let (output, _error) = rustc
440+
.cached_output(&process, 0)
441+
.with_context(|| "failed to run `rustc` to learn about check-cfg information")?;
442+
443+
let lines = output.lines();
444+
let mut check_cfg = CheckCfg::default();
445+
check_cfg.exhaustive = true;
446+
447+
for line in lines {
448+
check_cfg
449+
.parse_print_check_cfg_line(line)
450+
.with_context(|| format!("unable to parse a line from `--print=check-cfg`"))?;
451+
}
452+
Ok(check_cfg)
453+
}
454+
414455
/// All the target [`Cfg`] settings.
415456
pub fn cfg(&self) -> &[Cfg] {
416457
&self.cfg

src/cargo/util/lints.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -651,13 +651,20 @@ pub fn unexpected_target_cfgs(
651651
return Ok(());
652652
};
653653

654-
if !global_check_cfg.exhaustive {
654+
// If we have extra `--check-cfg` args comming from the lints config, we need to
655+
// refetch the `--print=check-cfg` with those extra args.
656+
let lint_rustflags = pkg.manifest().lint_rustflags();
657+
let check_cfg = if lint_rustflags.iter().any(|a| a == "--check-cfg") {
658+
Some(target_info.check_cfg_with_extra_args(gctx, &rustc, lint_rustflags)?)
659+
} else {
660+
None
661+
};
662+
let check_cfg = check_cfg.as_ref().unwrap_or(&global_check_cfg);
663+
664+
if !check_cfg.exhaustive {
655665
return Ok(());
656666
}
657667

658-
// FIXME: If the `[lints.rust.unexpected_cfgs.check-cfg]` config is set we should
659-
// re-fetch the check-cfg informations with those extra args
660-
661668
for dep in pkg.summary().dependencies() {
662669
let Some(platform) = dep.platform() else {
663670
continue;
@@ -672,7 +679,7 @@ pub fn unexpected_target_cfgs(
672679
Cfg::KeyPair(name, value) => (name, Some(value.to_string())),
673680
};
674681

675-
match global_check_cfg.expecteds.get(name.as_str()) {
682+
match check_cfg.expecteds.get(name.as_str()) {
676683
Some(ExpectedValues::Some(values)) if !values.contains(&value) => {
677684
let level = lint_level.to_diagnostic_level();
678685
if lint_level == LintLevel::Forbid || lint_level == LintLevel::Deny {

src/doc/src/reference/unstable.md

-2
Original file line numberDiff line numberDiff line change
@@ -1919,8 +1919,6 @@ cargo +nightly -Zno-embed-metadata build
19191919

19201920
* Tracking Issue: [#00000](https://github.com/rust-lang/cargo/issues/00000)
19211921

1922-
**WARNING: Incomplete/WIP!**
1923-
19241922
This feature checks for unexpected cfgs in `[target.'cfg(...)']` entries, based
19251923
on `rustc --print=check-cfg`.
19261924

tests/testsuite/cfg.rs

+3-22
Original file line numberDiff line numberDiff line change
@@ -941,26 +941,13 @@ fn unexpected_cfgs_target_with_lint() {
941941

942942
p.cargo("check -Zcargo-lints -Zcheck-target-cfgs")
943943
.masquerade_as_nightly_cargo(&["requires -Zcheck-target-cfgs"])
944-
// FIXME: We should not warn on `cfg(foo = "foo")` but we currently do
945944
.with_stderr_data(str![[r#"
946945
[WARNING] unexpected `cfg` condition name: bar
947946
--> Cargo.toml:14:25
948947
|
949948
14 | [target."cfg(bar)".dependencies]
950949
| ----------
951950
|
952-
[WARNING] unexpected `cfg` condition name: foo for `foo = "foo"`
953-
--> Cargo.toml:11:25
954-
|
955-
11 | [target.'cfg(foo = "foo")'.dependencies] # should not warn here
956-
| ------------------
957-
|
958-
[WARNING] unexpected `cfg` condition name: foo
959-
--> Cargo.toml:8:25
960-
|
961-
8 | [target."cfg(foo)".dependencies] # should not warn here
962-
| ----------
963-
|
964951
[LOCKING] 1 package to latest compatible version
965952
[CHECKING] a v0.0.1 ([ROOT]/foo)
966953
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
@@ -1115,18 +1102,12 @@ fn unexpected_cfgs_target_cfg_any() {
11151102

11161103
p.cargo("check -Zcargo-lints -Zcheck-target-cfgs")
11171104
.masquerade_as_nightly_cargo(&["requires -Zcheck-target-cfgs"])
1118-
// FIXME: We shouldn't be linting `cfg(foo)` because of the `cfg(any())`
11191105
.with_stderr_data(str![[r#"
1120-
[ERROR] unexpected `cfg` condition name: foo
1121-
--> Cargo.toml:8:25
1122-
|
1123-
8 | [target."cfg(foo)".dependencies]
1124-
| ^^^^^^^^^^
1125-
|
1106+
[LOCKING] 1 package to latest compatible version
1107+
[CHECKING] a v0.0.1 ([ROOT]/foo)
1108+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
11261109
11271110
"#]])
1128-
// nor should we error out because of the level="deny"
1129-
.with_status(101)
11301111
.run();
11311112
}
11321113

0 commit comments

Comments
 (0)