Skip to content

Commit 0de7f2e

Browse files
committed
Auto merge of #13913 - Urgau:check-cfg-lints-sub-config, r=epage
Add special `check-cfg` lint config for the `unexpected_cfgs` lint ### What does this PR try to resolve? This PR adds a special `check-cfg` lint config for the `unexpected_cfgs` lint, as it was decided by T-cargo (in today's meeting). The goal of this lint config is to provide a simple and cost-less alternative to the build-script `cargo::rustc-check-cfg` instruction. ```toml [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(foo, values("bar"))'] } ``` ### How should we test and review this PR? I recommand reviewing commit by commit; and looking at all the new tests added in `check_cfg.rs`, I tried making them as exhaustive as I could, many of them are very similar to their non-config counterpart. ### Additional information I didn't add *(actually removed from the 1st version of this PR)* the possibility to omit the `level` field if `check-cfg` is specified, #13913 (comment). Regarding the implementation, I tried making it is as straight forward as possible, nothing over-engineered or complex. r? `@epage` (or `@weihanglo` maybe)
2 parents 2b88044 + 5e9ac4b commit 0de7f2e

File tree

7 files changed

+386
-37
lines changed

7 files changed

+386
-37
lines changed

crates/cargo-util-schemas/src/manifest/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,13 @@ impl TomlLint {
15031503
Self::Config(config) => config.priority,
15041504
}
15051505
}
1506+
1507+
pub fn config(&self) -> Option<&toml::Table> {
1508+
match self {
1509+
Self::Level(_) => None,
1510+
Self::Config(config) => Some(&config.config),
1511+
}
1512+
}
15061513
}
15071514

15081515
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -1511,6 +1518,8 @@ pub struct TomlLintConfig {
15111518
pub level: TomlLintLevel,
15121519
#[serde(default)]
15131520
pub priority: i8,
1521+
#[serde(flatten)]
1522+
pub config: toml::Table,
15141523
}
15151524

15161525
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq)]

src/cargo/core/compiler/build_runner/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> {
246246
let mut args = compiler::extern_args(&self, unit, &mut unstable_opts)?;
247247
args.extend(compiler::lto_args(&self, unit));
248248
args.extend(compiler::features_args(unit));
249-
args.extend(compiler::check_cfg_args(&self, unit));
249+
args.extend(compiler::check_cfg_args(&self, unit)?);
250250

251251
let script_meta = self.find_build_script_metadata(unit);
252252
if let Some(meta) = script_meta {

src/cargo/core/compiler/mod.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use std::io::{BufRead, Write};
6363
use std::path::{Path, PathBuf};
6464
use std::sync::Arc;
6565

66-
use anyhow::{Context as _, Error};
66+
use anyhow::{bail, Context as _, Error};
6767
use lazycell::LazyCell;
6868
use tracing::{debug, trace};
6969

@@ -732,7 +732,7 @@ fn prepare_rustdoc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResu
732732
let doc_dir = build_runner.files().out_dir(unit);
733733
rustdoc.arg("-o").arg(&doc_dir);
734734
rustdoc.args(&features_args(unit));
735-
rustdoc.args(&check_cfg_args(build_runner, unit));
735+
rustdoc.args(&check_cfg_args(build_runner, unit)?);
736736

737737
add_error_format_and_color(build_runner, &mut rustdoc);
738738
add_allow_features(build_runner, &mut rustdoc);
@@ -1125,7 +1125,7 @@ fn build_base_args(
11251125
}
11261126

11271127
cmd.args(&features_args(unit));
1128-
cmd.args(&check_cfg_args(build_runner, unit));
1128+
cmd.args(&check_cfg_args(build_runner, unit)?);
11291129

11301130
let meta = build_runner.files().metadata(unit);
11311131
cmd.arg("-C").arg(&format!("metadata={}", meta));
@@ -1310,7 +1310,7 @@ fn trim_paths_args(
13101310
}
13111311

13121312
/// Generates the `--check-cfg` arguments for the `unit`.
1313-
fn check_cfg_args(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> Vec<OsString> {
1313+
fn check_cfg_args(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResult<Vec<OsString>> {
13141314
if build_runner
13151315
.bcx
13161316
.target_data
@@ -1353,14 +1353,39 @@ fn check_cfg_args(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> Vec<OsStri
13531353
// Cargo and docs.rs than rustc and docs.rs. In particular, all users of docs.rs use
13541354
// Cargo, but not all users of rustc (like Rust-for-Linux) use docs.rs.
13551355

1356-
vec![
1356+
let mut args = vec![
13571357
OsString::from("--check-cfg"),
13581358
OsString::from("cfg(docsrs)"),
13591359
OsString::from("--check-cfg"),
13601360
arg_feature,
1361-
]
1361+
];
1362+
1363+
// Also include the custom arguments specified in `[lints.rust.unexpected_cfgs.check_cfg]`
1364+
if let Ok(Some(lints)) = unit.pkg.manifest().resolved_toml().resolved_lints() {
1365+
if let Some(rust_lints) = lints.get("rust") {
1366+
if let Some(unexpected_cfgs) = rust_lints.get("unexpected_cfgs") {
1367+
if let Some(config) = unexpected_cfgs.config() {
1368+
if let Some(check_cfg) = config.get("check-cfg") {
1369+
if let Ok(check_cfgs) =
1370+
toml::Value::try_into::<Vec<String>>(check_cfg.clone())
1371+
{
1372+
for check_cfg in check_cfgs {
1373+
args.push(OsString::from("--check-cfg"));
1374+
args.push(OsString::from(check_cfg));
1375+
}
1376+
// error about `check-cfg` not being a list-of-string
1377+
} else {
1378+
bail!("`lints.rust.unexpected_cfgs.check-cfg` must be a list of string");
1379+
}
1380+
}
1381+
}
1382+
}
1383+
}
1384+
}
1385+
1386+
Ok(args)
13621387
} else {
1363-
Vec::new()
1388+
Ok(Vec::new())
13641389
}
13651390
}
13661391

src/cargo/util/toml/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2265,7 +2265,7 @@ supported tools: {}",
22652265
if tool == "cargo" && !gctx.cli_unstable().cargo_lints {
22662266
warn_for_cargo_lint_feature(gctx, warnings);
22672267
}
2268-
for name in lints.keys() {
2268+
for (name, config) in lints {
22692269
if let Some((prefix, suffix)) = name.split_once("::") {
22702270
if tool == prefix {
22712271
anyhow::bail!(
@@ -2278,6 +2278,19 @@ supported tools: {}",
22782278
} else {
22792279
anyhow::bail!("`lints.{tool}.{name}` is not a valid lint name")
22802280
}
2281+
} else if let Some(config) = config.config() {
2282+
for config_name in config.keys() {
2283+
// manually report unused manifest key warning since we collect all the "extra"
2284+
// keys and values inside the config table
2285+
//
2286+
// except for `rust.unexpected_cfgs.check-cfg` which is used by rustc/rustdoc
2287+
if !(tool == "rust" && name == "unexpected_cfgs" && config_name == "check-cfg")
2288+
{
2289+
let message =
2290+
format!("unused manifest key: `lints.{tool}.{name}.{config_name}`");
2291+
warnings.push(message);
2292+
}
2293+
}
22812294
}
22822295
}
22832296
}

src/doc/src/reference/build-scripts.md

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -292,32 +292,6 @@ if foo_bar_condition {
292292
}
293293
```
294294

295-
##### Example of local-only `build.rs`/build script
296-
297-
Build scripts can impose costs on downstream users, and crate authors who wish to avoid
298-
this can use "local-only" build scripts, which are active locally but not packaged in the
299-
distributed package. Completly removing the cost from downstream users.
300-
301-
The way to achieved this, is by excluding the `build.rs` in the `Cargo.toml` with the
302-
`exclude` key:
303-
304-
```diff
305-
[package]
306-
name = "foo"
307-
version = "0.1.0"
308-
+ exclude = ["build.rs"]
309-
```
310-
311-
*`build.rs`:*
312-
```rust
313-
fn main() {
314-
// Warning: build.rs is not published to crates.io.
315-
316-
println!("cargo::rerun-if-changed=build.rs");
317-
println!("cargo::rustc-check-cfg=cfg(foo)");
318-
}
319-
```
320-
321295
For a more complete example see in the [build script examples][build-script-examples] page
322296
the [conditional compilation][conditional-compilation-example] example.
323297

0 commit comments

Comments
 (0)