Skip to content

Commit cbe9c4d

Browse files
Rollup merge of rust-lang#154777 - scrabsha:push-nunzyzrqlwqw, r=jdonszelmann
`#[cfg]`: suggest alternative `target_` name when the value does not match
2 parents 9a9ea5d + 1d79216 commit cbe9c4d

5 files changed

Lines changed: 181 additions & 3 deletions

File tree

compiler/rustc_lint/src/early/diagnostics/check_cfg.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,9 +316,27 @@ pub(super) fn unexpected_cfg_value(
316316
let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
317317
let is_from_external_macro = name_span.in_external_macro(sess.source_map());
318318

319-
// Show the full list if all possible values for a given name, but don't do it
320-
// for names as the possibilities could be very long
321-
let code_sugg = if !possibilities.is_empty() {
319+
let code_sugg = if let Some((value, _)) = value
320+
&& sess.psess.check_config.well_known_names.contains(&name)
321+
&& let valid_names = possible_well_known_names_for_cfg_value(sess, value)
322+
&& !valid_names.is_empty()
323+
{
324+
// Suggest changing the name to something for which `value` is an expected value.
325+
let max_suggestions = 3;
326+
let suggestions = valid_names
327+
.iter()
328+
.take(max_suggestions)
329+
.copied()
330+
.map(|name| lints::unexpected_cfg_value::ChangeNameSuggestion {
331+
span: name_span,
332+
name,
333+
value,
334+
})
335+
.collect::<Vec<_>>();
336+
lints::unexpected_cfg_value::CodeSuggestion::ChangeName { suggestions }
337+
} else if !possibilities.is_empty() {
338+
// Show the full list if all possible values for a given name, but don't do it
339+
// for names as the possibilities could be very long
322340
let expected_values = {
323341
let (possibilities, and_more) = sort_and_truncate_possibilities(
324342
sess,
@@ -419,3 +437,22 @@ pub(super) fn unexpected_cfg_value(
419437
value: value.map_or_else(String::new, |(v, _span)| v.to_string()),
420438
}
421439
}
440+
441+
/// Ordering of the output is not stable, use this only in diagnostic code.
442+
fn possible_well_known_names_for_cfg_value(sess: &Session, value: Symbol) -> Vec<Symbol> {
443+
#[allow(rustc::potential_query_instability)]
444+
sess.psess
445+
.check_config
446+
.well_known_names
447+
.iter()
448+
.filter(|name| {
449+
sess.psess
450+
.check_config
451+
.expecteds
452+
.get(*name)
453+
.map(|expected_values| expected_values.contains(&Some(value)))
454+
.unwrap_or_default()
455+
})
456+
.copied()
457+
.collect()
458+
}

compiler/rustc_lint/src/lints.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2904,6 +2904,10 @@ pub(crate) mod unexpected_cfg_value {
29042904

29052905
name: Symbol,
29062906
},
2907+
ChangeName {
2908+
#[subdiagnostic]
2909+
suggestions: Vec<ChangeNameSuggestion>,
2910+
},
29072911
}
29082912

29092913
#[derive(Subdiagnostic)]
@@ -2961,6 +2965,20 @@ pub(crate) mod unexpected_cfg_value {
29612965
pub and_more: usize,
29622966
}
29632967

2968+
#[derive(Subdiagnostic)]
2969+
#[suggestion(
2970+
"`{$value}` is an expected value for `{$name}`",
2971+
code = "{name}",
2972+
applicability = "maybe-incorrect",
2973+
style = "verbose"
2974+
)]
2975+
pub(crate) struct ChangeNameSuggestion {
2976+
#[primary_span]
2977+
pub span: Span,
2978+
pub name: Symbol,
2979+
pub value: Symbol,
2980+
}
2981+
29642982
#[derive(Subdiagnostic)]
29652983
pub(crate) enum InvocationHelp {
29662984
#[note(

compiler/rustc_session/src/config/cfg.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ impl<T: Eq + Hash> ExpectedValues<T> {
6565
ExpectedValues::Any => false,
6666
}
6767
}
68+
69+
pub fn contains(&self, value: &Option<T>) -> bool {
70+
match self {
71+
ExpectedValues::Some(expecteds) => expecteds.contains(value),
72+
ExpectedValues::Any => false,
73+
}
74+
}
6875
}
6976

7077
impl<T: Eq + Hash> Extend<T> for ExpectedValues<T> {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#![deny(unexpected_cfgs)]
2+
//~^ NOTE lint level is defined here
3+
4+
// target arch used in `target_abi`
5+
#[cfg(target_abi = "arm")]
6+
//~^ ERROR unexpected `cfg` condition value:
7+
//~| NOTE see <https://doc.rust-lang.org
8+
//~| HELP `arm` is an expected value for `target_arch`
9+
struct A;
10+
11+
// target env used in `target_arch`
12+
#[cfg(target_arch = "gnu")]
13+
//~^ ERROR unexpected `cfg` condition value:
14+
//~| NOTE see <https://doc.rust-lang.org
15+
//~| HELP `gnu` is an expected value for `target_env`
16+
struct B;
17+
18+
// target os used in `target_env`
19+
#[cfg(target_env = "openbsd")]
20+
//~^ ERROR unexpected `cfg` condition value:
21+
//~| NOTE see <https://doc.rust-lang.org
22+
//~| HELP `openbsd` is an expected value for `target_os`
23+
struct C;
24+
25+
// target abi used in `target_os`
26+
#[cfg(target_os = "eabi")]
27+
//~^ ERROR unexpected `cfg` condition value:
28+
//~| NOTE see <https://doc.rust-lang.org
29+
//~| HELP `eabi` is an expected value for `target_abi`
30+
struct D;
31+
32+
#[cfg(target_abi = "windows")]
33+
//~^ ERROR unexpected `cfg` condition value:
34+
//~| NOTE see <https://doc.rust-lang.org
35+
//~| HELP `windows` is an expected value for `target_os`
36+
//~| HELP `windows` is an expected value for `target_family`
37+
struct E;
38+
39+
fn main() {}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
error: unexpected `cfg` condition value: `arm`
2+
--> $DIR/suggest-alternative-name-on-target.rs:5:7
3+
|
4+
LL | #[cfg(target_abi = "arm")]
5+
| ^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
8+
note: the lint level is defined here
9+
--> $DIR/suggest-alternative-name-on-target.rs:1:9
10+
|
11+
LL | #![deny(unexpected_cfgs)]
12+
| ^^^^^^^^^^^^^^^
13+
help: `arm` is an expected value for `target_arch`
14+
|
15+
LL - #[cfg(target_abi = "arm")]
16+
LL + #[cfg(target_arch = "arm")]
17+
|
18+
19+
error: unexpected `cfg` condition value: `gnu`
20+
--> $DIR/suggest-alternative-name-on-target.rs:12:7
21+
|
22+
LL | #[cfg(target_arch = "gnu")]
23+
| ^^^^^^^^^^^^^^^^^^^
24+
|
25+
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
26+
help: `gnu` is an expected value for `target_env`
27+
|
28+
LL - #[cfg(target_arch = "gnu")]
29+
LL + #[cfg(target_env = "gnu")]
30+
|
31+
32+
error: unexpected `cfg` condition value: `openbsd`
33+
--> $DIR/suggest-alternative-name-on-target.rs:19:7
34+
|
35+
LL | #[cfg(target_env = "openbsd")]
36+
| ^^^^^^^^^^^^^^^^^^^^^^
37+
|
38+
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
39+
help: `openbsd` is an expected value for `target_os`
40+
|
41+
LL - #[cfg(target_env = "openbsd")]
42+
LL + #[cfg(target_os = "openbsd")]
43+
|
44+
45+
error: unexpected `cfg` condition value: `eabi`
46+
--> $DIR/suggest-alternative-name-on-target.rs:26:7
47+
|
48+
LL | #[cfg(target_os = "eabi")]
49+
| ^^^^^^^^^^^^^^^^^^
50+
|
51+
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
52+
help: `eabi` is an expected value for `target_abi`
53+
|
54+
LL - #[cfg(target_os = "eabi")]
55+
LL + #[cfg(target_abi = "eabi")]
56+
|
57+
58+
error: unexpected `cfg` condition value: `windows`
59+
--> $DIR/suggest-alternative-name-on-target.rs:32:7
60+
|
61+
LL | #[cfg(target_abi = "windows")]
62+
| ^^^^^^^^^^^^^^^^^^^^^^
63+
|
64+
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
65+
help: `windows` is an expected value for `target_os`
66+
|
67+
LL - #[cfg(target_abi = "windows")]
68+
LL + #[cfg(target_os = "windows")]
69+
|
70+
help: `windows` is an expected value for `target_family`
71+
|
72+
LL - #[cfg(target_abi = "windows")]
73+
LL + #[cfg(target_family = "windows")]
74+
|
75+
76+
error: aborting due to 5 previous errors
77+

0 commit comments

Comments
 (0)