mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
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:
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user