Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update unexpected_cfgs lint for Cargo new check-cfg config #125219

Merged
merged 6 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 32 additions & 18 deletions compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ fn check_cfg_expected_note(
note
}

enum EscapeQuotes {
Yes,
No,
}

fn to_check_cfg_arg(name: Symbol, value: Option<Symbol>, quotes: EscapeQuotes) -> String {
if let Some(value) = value {
let value = str::escape_debug(value.as_str()).to_string();
let values = match quotes {
EscapeQuotes::Yes => format!("\\\"{}\\\"", value.replace("\"", "\\\\\\\\\"")),
EscapeQuotes::No => format!("\"{value}\""),
Urgau marked this conversation as resolved.
Show resolved Hide resolved
};
format!("cfg({name}, values({values}))")
} else {
format!("cfg({name})")
}
}

pub(super) fn unexpected_cfg_name(
sess: &Session,
diag: &mut Diag<'_, ()>,
Expand Down Expand Up @@ -155,20 +173,18 @@ pub(super) fn unexpected_cfg_name(
}
}

let inst = if let Some((value, _value_span)) = value {
let pre = if is_from_cargo { "\\" } else { "" };
format!("cfg({name}, values({pre}\"{value}{pre}\"))")
} else {
format!("cfg({name})")
};
let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes);

if is_from_cargo {
if !is_feature_cfg {
diag.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo::rustc-check-cfg={inst}\");` to the top of the `build.rs`"));
diag.help(format!("consider using a Cargo feature instead"));
diag.help(format!("or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:\n [lints.rust]\n unexpected_cfgs = {{ level = \"warn\", check-cfg = ['{}'] }}", inst(EscapeQuotes::No)));
diag.help(format!("or consider adding `println!(\"cargo::rustc-check-cfg={}\");` to the top of the `build.rs`", inst(EscapeQuotes::Yes)));
}
diag.note("see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration");
diag.note("see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration");
} else {
diag.help(format!("to expect this configuration use `--check-cfg={inst}`"));
let inst = inst(EscapeQuotes::No);
diag.help(format!("to expect this configuration use `--check-cfg={inst}`",));
diag.note("see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration");
}
}
Expand Down Expand Up @@ -251,12 +267,7 @@ pub(super) fn unexpected_cfg_value(
// do it if they want, but should not encourage them.
let is_cfg_a_well_know_name = sess.psess.check_config.well_known_names.contains(&name);

let inst = if let Some((value, _value_span)) = value {
let pre = if is_from_cargo { "\\" } else { "" };
format!("cfg({name}, values({pre}\"{value}{pre}\"))")
} else {
format!("cfg({name})")
};
let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes);

if is_from_cargo {
if name == sym::feature {
Expand All @@ -266,12 +277,15 @@ pub(super) fn unexpected_cfg_value(
diag.help("consider defining some features in `Cargo.toml`");
}
} else if !is_cfg_a_well_know_name {
diag.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo::rustc-check-cfg={inst}\");` to the top of the `build.rs`"));
diag.help(format!("consider using a Cargo feature instead"));
diag.help(format!("or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:\n [lints.rust]\n unexpected_cfgs = {{ level = \"warn\", check-cfg = ['{}'] }}", inst(EscapeQuotes::No)));
diag.help(format!("or consider adding `println!(\"cargo::rustc-check-cfg={}\");` to the top of the `build.rs`", inst(EscapeQuotes::Yes)));
}
diag.note("see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration");
diag.note("see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration");
} else {
if !is_cfg_a_well_know_name {
diag.help(format!("to expect this configuration use `--check-cfg={inst}`"));
let inst = inst(EscapeQuotes::No);
diag.help(format!("to expect this configuration use `--check-cfg={inst}`",));
}
diag.note("see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration");
}
Expand Down
11 changes: 7 additions & 4 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3339,11 +3339,14 @@ declare_lint! {
///
/// ### Explanation
///
/// This lint is only active when `--check-cfg` arguments are being passed
/// to the compiler and triggers whenever an unexpected condition name or value is used.
/// This lint is only active when [`--check-cfg`][check-cfg] arguments are being
/// passed to the compiler and triggers whenever an unexpected condition name or value is
/// used.
///
/// See the [Checking Conditional Configurations][check-cfg] section for more
/// details.
///
/// The known condition include names or values passed in `--check-cfg`, and some
/// well-knows names and values built into the compiler.
/// [check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html
pub UNEXPECTED_CFGS,
Warn,
"detects unexpected names and values in `#[cfg]` conditions",
Expand Down
3 changes: 2 additions & 1 deletion src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@
- [Profile-guided Optimization](profile-guided-optimization.md)
- [Instrumentation-based Code Coverage](instrument-coverage.md)
- [Linker-plugin-based LTO](linker-plugin-lto.md)
- [Checking conditional configurations](check-cfg.md)
- [Checking Conditional Configurations](check-cfg.md)
- [Cargo Specifics](check-cfg/cargo-specifics.md)
- [Exploit Mitigations](exploit-mitigations.md)
- [Symbol Mangling](symbol-mangling/index.md)
- [v0 Symbol Format](symbol-mangling/v0.md)
Expand Down
73 changes: 73 additions & 0 deletions src/doc/rustc/src/check-cfg/cargo-specifics.md
Urgau marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Cargo Specifics - Checking Conditional Configurations

<!--
This page is currently (as of May 2024) the canonical place for describing the interaction
between Cargo and --check-cfg. It is placed in the rustc book rather than the Cargo book
since check-cfg is primarely a Rust/rustc feature and is therefor consider by T-cargo to
be an implementation detail, at least --check-cfg and the unexpected_cfgs are owned by
rustc, not Cargo.
-->

This document is intented to summarize the principal ways Cargo interacts with
the `unexpected_cfgs` lint and `--check-cfg` flag. It is not intended to provide
individual details, for that refer to the [`--check-cfg` documentation](../check-cfg.md) and
to the [Cargo book](../../cargo/index.html).

## Cargo feature

*See the [`[features]` section in the Cargo book][cargo-features] for more details.*

With the `[features]` table Cargo provides a mechanism to express conditional compilation and
optional dependencies. Cargo *automatically* declares corresponding cfgs for every feature as
expected.

`Cargo.toml`:
```toml
[features]
serde = ["dep:serde"]
my_feature = []
```

[cargo-features]: ../../cargo/reference/features.html

## `check-cfg` in `[lints.rust]` table

<!-- Note that T-Cargo considers `[lints.rust.unexpected_cfgs.check-cfg]` to be an
implementation detail and is therefor not documented in Cargo, we therefor do that ourself -->

*See the [`[lints]` section in the Cargo book][cargo-lints-table] for more details.*

When using a staticlly known custom config (ie. not dependant on a build-script), Cargo provides
the custom lint config `check-cfg` under `[lints.rust.unexpected_cfgs]`.

It can be used to set custom static [`--check-cfg`](../check-cfg.md) args, it is mainly useful when
the list of expected cfgs is known is advance.

`Cargo.toml`:
```toml
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(has_foo)'] }
```

[cargo-lints-table]: ../../cargo/reference/manifest.html#the-lints-section

## `cargo::rustc-check-cfg` for `build.rs`/build-script

*See the [`cargo::rustc-check-cfg` section in the Cargo book][cargo-rustc-check-cfg] for more details.*

When setting a custom config with [`cargo::rustc-cfg`][cargo-rustc-cfg], Cargo provides the
corollary instruction: [`cargo::rustc-check-cfg`][cargo-rustc-check-cfg] to expect custom configs.

`build.rs`:
```rust,ignore (cannot-test-this-because-has_foo-isnt-declared)
fn main() {
println!("cargo::rustc-check-cfg=cfg(has_foo)");
// ^^^^^^^^^^^^^^^^^^^^^^ new with Cargo 1.80
if has_foo() {
println!("cargo::rustc-cfg=has_foo");
}
}
```

[cargo-rustc-cfg]: ../../cargo/reference/build-scripts.html#rustc-cfg
[cargo-rustc-check-cfg]: ../../cargo/reference/build-scripts.html#rustc-check-cfg
20 changes: 14 additions & 6 deletions tests/ui/check-cfg/cargo-feature.none.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LL | #[cfg(feature = "serde")]
|
= note: no expected values for `feature`
= help: consider adding `serde` as a feature in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default

warning: unexpected `cfg` condition value: (none)
Expand All @@ -17,7 +17,7 @@ LL | #[cfg(feature)]
|
= note: no expected values for `feature`
= help: consider defining some features in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration

warning: unexpected `cfg` condition name: `tokio_unstable`
--> $DIR/cargo-feature.rs:22:7
Expand All @@ -26,17 +26,25 @@ LL | #[cfg(tokio_unstable)]
| ^^^^^^^^^^^^^^
|
= help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows`
= help: consider using a Cargo feature instead or adding `println!("cargo::rustc-check-cfg=cfg(tokio_unstable)");` to the top of the `build.rs`
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration
= help: consider using a Cargo feature instead
= help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }
Urgau marked this conversation as resolved.
Show resolved Hide resolved
= help: or consider adding `println!("cargo::rustc-check-cfg=cfg(tokio_unstable)");` to the top of the `build.rs`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration

warning: unexpected `cfg` condition name: `CONFIG_NVME`
--> $DIR/cargo-feature.rs:26:7
|
LL | #[cfg(CONFIG_NVME = "m")]
| ^^^^^^^^^^^^^^^^^
|
= help: consider using a Cargo feature instead or adding `println!("cargo::rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of the `build.rs`
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration
= help: consider using a Cargo feature instead
= help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(CONFIG_NVME, values("m"))'] }
= help: or consider adding `println!("cargo::rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of the `build.rs`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration

warning: 4 warnings emitted

20 changes: 14 additions & 6 deletions tests/ui/check-cfg/cargo-feature.some.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LL | #[cfg(feature = "serde")]
|
= note: expected values for `feature` are: `bitcode`
= help: consider adding `serde` as a feature in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default

warning: unexpected `cfg` condition value: (none)
Expand All @@ -17,7 +17,7 @@ LL | #[cfg(feature)]
|
= note: expected values for `feature` are: `bitcode`
= help: consider defining some features in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration

warning: unexpected `cfg` condition name: `tokio_unstable`
--> $DIR/cargo-feature.rs:22:7
Expand All @@ -26,8 +26,12 @@ LL | #[cfg(tokio_unstable)]
| ^^^^^^^^^^^^^^
|
= help: expected names are: `CONFIG_NVME`, `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows`
= help: consider using a Cargo feature instead or adding `println!("cargo::rustc-check-cfg=cfg(tokio_unstable)");` to the top of the `build.rs`
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration
= help: consider using a Cargo feature instead
= help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }
= help: or consider adding `println!("cargo::rustc-check-cfg=cfg(tokio_unstable)");` to the top of the `build.rs`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration

warning: unexpected `cfg` condition value: `m`
--> $DIR/cargo-feature.rs:26:7
Expand All @@ -38,8 +42,12 @@ LL | #[cfg(CONFIG_NVME = "m")]
| help: there is a expected value with a similar name: `"y"`
|
= note: expected values for `CONFIG_NVME` are: `y`
= help: consider using a Cargo feature instead or adding `println!("cargo::rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of the `build.rs`
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg> for more information about checking conditional configuration
= help: consider using a Cargo feature instead
= help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(CONFIG_NVME, values("m"))'] }
= help: or consider adding `println!("cargo::rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of the `build.rs`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration

warning: 4 warnings emitted

Loading
Loading