Skip to content

Commit a731253

Browse files
committed
Respect [lints.rust.unexpected_cfgs.check-cfg] lint config
1 parent 0376a97 commit a731253

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
@@ -1918,8 +1918,6 @@ whether documentations are required to re-generate. This can be combined with
19181918

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

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

tests/testsuite/cfg.rs

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

784784
p.cargo("check -Zcargo-lints -Zcheck-target-cfgs")
785785
.masquerade_as_nightly_cargo(&["requires -Zcheck-target-cfgs"])
786-
// FIXME: We should not warn on `cfg(foo = "foo")` but we currently do
787786
.with_stderr_data(str![[r#"
788787
[WARNING] unexpected `cfg` condition name: bar
789788
--> Cargo.toml:14:25
790789
|
791790
14 | [target."cfg(bar)".dependencies]
792791
| ----------
793792
|
794-
[WARNING] unexpected `cfg` condition name: foo for `foo = "foo"`
795-
--> Cargo.toml:11:25
796-
|
797-
11 | [target.'cfg(foo = "foo")'.dependencies] # should not warn here
798-
| ------------------
799-
|
800-
[WARNING] unexpected `cfg` condition name: foo
801-
--> Cargo.toml:8:25
802-
|
803-
8 | [target."cfg(foo)".dependencies] # should not warn here
804-
| ----------
805-
|
806793
[LOCKING] 1 package to latest compatible version
807794
[CHECKING] a v0.0.1 ([ROOT]/foo)
808795
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
@@ -957,18 +944,12 @@ fn unexpected_cfgs_target_cfg_any() {
957944

958945
p.cargo("check -Zcargo-lints -Zcheck-target-cfgs")
959946
.masquerade_as_nightly_cargo(&["requires -Zcheck-target-cfgs"])
960-
// FIXME: We shouldn't be linting `cfg(foo)` because of the `cfg(any())`
961947
.with_stderr_data(str![[r#"
962-
[ERROR] unexpected `cfg` condition name: foo
963-
--> Cargo.toml:8:25
964-
|
965-
8 | [target."cfg(foo)".dependencies]
966-
| ^^^^^^^^^^
967-
|
948+
[LOCKING] 1 package to latest compatible version
949+
[CHECKING] a v0.0.1 ([ROOT]/foo)
950+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
968951
969952
"#]])
970-
// nor should we error out because of the level="deny"
971-
.with_status(101)
972953
.run();
973954
}
974955

0 commit comments

Comments
 (0)