Rollup merge of #154777 - scrabsha:push-nunzyzrqlwqw, r=jdonszelmann

`#[cfg]`: suggest alternative `target_` name when the value does not match
This commit is contained in:
Jonathan Brouwer
2026-04-06 08:27:52 +02:00
committed by GitHub
5 changed files with 181 additions and 3 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> {
@@ -0,0 +1,39 @@
#![deny(unexpected_cfgs)]
//~^ NOTE lint level is defined here
// target arch used in `target_abi`
#[cfg(target_abi = "arm")]
//~^ ERROR unexpected `cfg` condition value:
//~| NOTE see <https://doc.rust-lang.org
//~| 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
//~| 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
//~| 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
//~| 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
//~| HELP `windows` is an expected value for `target_os`
//~| HELP `windows` is an expected value for `target_family`
struct E;
fn main() {}
@@ -0,0 +1,77 @@
error: unexpected `cfg` condition value: `arm`
--> $DIR/suggest-alternative-name-on-target.rs:5:7
|
LL | #[cfg(target_abi = "arm")]
| ^^^^^^^^^^^^^^^^^^
|
= 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
|
LL | #[cfg(target_arch = "gnu")]
| ^^^^^^^^^^^^^^^^^^^
|
= 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
|
LL | #[cfg(target_env = "openbsd")]
| ^^^^^^^^^^^^^^^^^^^^^^
|
= 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
|
LL | #[cfg(target_os = "eabi")]
| ^^^^^^^^^^^^^^^^^^
|
= 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: 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