#[cfg]: suggest alternative target_ name when the value does not match

This commit is contained in:
Sasha Pourcelot
2026-04-02 18:04:34 +00:00
parent e84576addd
commit 1d79216182
5 changed files with 110 additions and 13 deletions
@@ -316,9 +316,27 @@ pub(super) fn unexpected_cfg_value(
let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
let is_from_external_macro = name_span.in_external_macro(sess.source_map());
// Show the full list if all possible values for a given name, but don't do it
// for names as the possibilities could be very long
let code_sugg = if !possibilities.is_empty() {
let code_sugg = if let Some((value, _)) = value
&& sess.psess.check_config.well_known_names.contains(&name)
&& let valid_names = possible_well_known_names_for_cfg_value(sess, value)
&& !valid_names.is_empty()
{
// Suggest changing the name to something for which `value` is an expected value.
let max_suggestions = 3;
let suggestions = valid_names
.iter()
.take(max_suggestions)
.copied()
.map(|name| lints::unexpected_cfg_value::ChangeNameSuggestion {
span: name_span,
name,
value,
})
.collect::<Vec<_>>();
lints::unexpected_cfg_value::CodeSuggestion::ChangeName { suggestions }
} else if !possibilities.is_empty() {
// Show the full list if all possible values for a given name, but don't do it
// for names as the possibilities could be very long
let expected_values = {
let (possibilities, and_more) = sort_and_truncate_possibilities(
sess,
@@ -419,3 +437,22 @@ pub(super) fn unexpected_cfg_value(
value: value.map_or_else(String::new, |(v, _span)| v.to_string()),
}
}
/// Ordering of the output is not stable, use this only in diagnostic code.
fn possible_well_known_names_for_cfg_value(sess: &Session, value: Symbol) -> Vec<Symbol> {
#[allow(rustc::potential_query_instability)]
sess.psess
.check_config
.well_known_names
.iter()
.filter(|name| {
sess.psess
.check_config
.expecteds
.get(*name)
.map(|expected_values| expected_values.contains(&Some(value)))
.unwrap_or_default()
})
.copied()
.collect()
}
+18
View File
@@ -2904,6 +2904,10 @@ pub(crate) enum CodeSuggestion {
name: Symbol,
},
ChangeName {
#[subdiagnostic]
suggestions: Vec<ChangeNameSuggestion>,
},
}
#[derive(Subdiagnostic)]
@@ -2961,6 +2965,20 @@ pub(crate) struct ExpectedValues {
pub and_more: usize,
}
#[derive(Subdiagnostic)]
#[suggestion(
"`{$value}` is an expected value for `{$name}`",
code = "{name}",
applicability = "maybe-incorrect",
style = "verbose"
)]
pub(crate) struct ChangeNameSuggestion {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub value: Symbol,
}
#[derive(Subdiagnostic)]
pub(crate) enum InvocationHelp {
#[note(
+7
View File
@@ -65,6 +65,13 @@ fn insert(&mut self, value: T) -> bool {
ExpectedValues::Any => false,
}
}
pub fn contains(&self, value: &Option<T>) -> bool {
match self {
ExpectedValues::Some(expecteds) => expecteds.contains(value),
ExpectedValues::Any => false,
}
}
}
impl<T: Eq + Hash> Extend<T> for ExpectedValues<T> {
@@ -5,34 +5,35 @@
#[cfg(target_abi = "arm")]
//~^ ERROR unexpected `cfg` condition value:
//~| NOTE see <https://doc.rust-lang.org
//~| NOTE expected values for `target_abi` are
//~| HELP `arm` is an expected value for `target_arch`
struct A;
// target env used in `target_arch`
#[cfg(target_arch = "gnu")]
//~^ ERROR unexpected `cfg` condition value:
//~| NOTE see <https://doc.rust-lang.org
//~| NOTE expected values for `target_arch` are
//~| HELP `gnu` is an expected value for `target_env`
struct B;
// target os used in `target_env`
#[cfg(target_env = "openbsd")]
//~^ ERROR unexpected `cfg` condition value:
//~| NOTE see <https://doc.rust-lang.org
//~| NOTE expected values for `target_env` are
//~| HELP `openbsd` is an expected value for `target_os`
struct C;
// target abi used in `target_os`
#[cfg(target_os = "eabi")]
//~^ ERROR unexpected `cfg` condition value:
//~| NOTE see <https://doc.rust-lang.org
//~| NOTE expected values for `target_os` are
//~| HELP `eabi` is an expected value for `target_abi`
struct D;
#[cfg(target_abi = "windows")]
//~^ ERROR unexpected `cfg` condition value:
//~| NOTE see <https://doc.rust-lang.org
//~| NOTE expected values for `target_abi` are
//~| HELP `windows` is an expected value for `target_os`
//~| HELP `windows` is an expected value for `target_family`
struct E;
fn main() {}
@@ -4,13 +4,17 @@ error: unexpected `cfg` condition value: `arm`
LL | #[cfg(target_abi = "arm")]
| ^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_abi` are: ``, `abi64`, `abiv2`, `abiv2hf`, `eabi`, `eabihf`, `elfv1`, `elfv2`, `fortanix`, `ilp32`, `ilp32e`, `llvm`, `macabi`, `sim`, `softfloat`, `spe`, `uwp`, `vec-extabi`, and `x32`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
note: the lint level is defined here
--> $DIR/suggest-alternative-name-on-target.rs:1:9
|
LL | #![deny(unexpected_cfgs)]
| ^^^^^^^^^^^^^^^
help: `arm` is an expected value for `target_arch`
|
LL - #[cfg(target_abi = "arm")]
LL + #[cfg(target_arch = "arm")]
|
error: unexpected `cfg` condition value: `gnu`
--> $DIR/suggest-alternative-name-on-target.rs:12:7
@@ -18,8 +22,12 @@ error: unexpected `cfg` condition value: `gnu`
LL | #[cfg(target_arch = "gnu")]
| ^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch32`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
help: `gnu` is an expected value for `target_env`
|
LL - #[cfg(target_arch = "gnu")]
LL + #[cfg(target_env = "gnu")]
|
error: unexpected `cfg` condition value: `openbsd`
--> $DIR/suggest-alternative-name-on-target.rs:19:7
@@ -27,8 +35,12 @@ error: unexpected `cfg` condition value: `openbsd`
LL | #[cfg(target_env = "openbsd")]
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_env` are: ``, `gnu`, `macabi`, `mlibc`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `p3`, `relibc`, `sgx`, `sim`, `uclibc`, and `v5`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
help: `openbsd` is an expected value for `target_os`
|
LL - #[cfg(target_env = "openbsd")]
LL + #[cfg(target_os = "openbsd")]
|
error: unexpected `cfg` condition value: `eabi`
--> $DIR/suggest-alternative-name-on-target.rs:26:7
@@ -36,8 +48,30 @@ error: unexpected `cfg` condition value: `eabi`
LL | #[cfg(target_os = "eabi")]
| ^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qurt`, `redox`, `rtems`, `solaris`, and `solid_asp3` and 14 more
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
help: `eabi` is an expected value for `target_abi`
|
LL - #[cfg(target_os = "eabi")]
LL + #[cfg(target_abi = "eabi")]
|
error: aborting due to 4 previous errors
error: unexpected `cfg` condition value: `windows`
--> $DIR/suggest-alternative-name-on-target.rs:32:7
|
LL | #[cfg(target_abi = "windows")]
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
help: `windows` is an expected value for `target_os`
|
LL - #[cfg(target_abi = "windows")]
LL + #[cfg(target_os = "windows")]
|
help: `windows` is an expected value for `target_family`
|
LL - #[cfg(target_abi = "windows")]
LL + #[cfg(target_family = "windows")]
|
error: aborting due to 5 previous errors