Skip to content

Commit c8a49fc

Browse files
committed
Auto merge of #94561 - Urgau:check-cfg-lint-help-remove, r=petrochenkov
Improve unexpected_cfgs lint when their is no value expected This pull-request improve the `unexpected_cfgs` when their is no value expected by suggesting to remove the value. I also took the liberty to special case it for `feature` as it seems wrong to suggest to remove the value when the problem is most probably the absence of value(s) and also the fact that it doesn't make sense to only have `feature` without a value. r? `@petrochenkov`
2 parents 86067bb + 92544f4 commit c8a49fc

File tree

7 files changed

+52
-29
lines changed

7 files changed

+52
-29
lines changed

compiler/rustc_attr/src/builtin.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ pub fn cfg_matches(
476476
cfg.span,
477477
lint_node_id,
478478
"unexpected `cfg` condition name",
479-
BuiltinLintDiagnostics::UnexpectedCfg(ident.span, name, None),
479+
BuiltinLintDiagnostics::UnexpectedCfg((name, ident.span), None),
480480
);
481481
}
482482
}
@@ -489,9 +489,8 @@ pub fn cfg_matches(
489489
lint_node_id,
490490
"unexpected `cfg` condition value",
491491
BuiltinLintDiagnostics::UnexpectedCfg(
492-
cfg.name_value_literal_span().unwrap(),
493-
name,
494-
Some(value),
492+
(name, ident.span),
493+
Some((value, cfg.name_value_literal_span().unwrap())),
495494
),
496495
);
497496
}

compiler/rustc_lint/src/context.rs

+26-20
Original file line numberDiff line numberDiff line change
@@ -779,37 +779,43 @@ pub trait LintContext: Sized {
779779
db.help(&help);
780780
db.note("see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information");
781781
},
782-
BuiltinLintDiagnostics::UnexpectedCfg(span, name, value) => {
783-
let possibilities: Vec<Symbol> = if value.is_some() {
784-
let Some(values) = &sess.parse_sess.check_config.values_valid.get(&name) else {
785-
bug!("it shouldn't be possible to have a diagnostic on a value whose name is not in values");
786-
};
787-
values.iter().map(|&s| s).collect()
788-
} else {
789-
let Some(names_valid) = &sess.parse_sess.check_config.names_valid else {
790-
bug!("it shouldn't be possible to have a diagnostic on a name if name checking is not enabled");
791-
};
792-
names_valid.iter().map(|s| *s).collect()
782+
BuiltinLintDiagnostics::UnexpectedCfg((name, name_span), None) => {
783+
let Some(names_valid) = &sess.parse_sess.check_config.names_valid else {
784+
bug!("it shouldn't be possible to have a diagnostic on a name if name checking is not enabled");
785+
};
786+
let possibilities: Vec<Symbol> = names_valid.iter().map(|s| *s).collect();
787+
788+
// Suggest the most probable if we found one
789+
if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) {
790+
db.span_suggestion(name_span, "did you mean", format!("{best_match}"), Applicability::MaybeIncorrect);
791+
}
792+
},
793+
BuiltinLintDiagnostics::UnexpectedCfg((name, name_span), Some((value, value_span))) => {
794+
let Some(values) = &sess.parse_sess.check_config.values_valid.get(&name) else {
795+
bug!("it shouldn't be possible to have a diagnostic on a value whose name is not in values");
793796
};
797+
let possibilities: Vec<Symbol> = values.iter().map(|&s| s).collect();
794798

795799
// Show the full list if all possible values for a given name, but don't do it
796800
// for names as the possibilities could be very long
797-
if value.is_some() {
798-
if !possibilities.is_empty() {
801+
if !possibilities.is_empty() {
802+
{
799803
let mut possibilities = possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>();
800804
possibilities.sort();
801805

802806
let possibilities = possibilities.join(", ");
803807
db.note(&format!("expected values for `{name}` are: {possibilities}"));
804-
} else {
805-
db.note(&format!("no expected value for `{name}`"));
806808
}
807-
}
808809

809-
// Suggest the most probable if we found one
810-
if let Some(best_match) = find_best_match_for_name(&possibilities, value.unwrap_or(name), None) {
811-
let punctuation = if value.is_some() { "\"" } else { "" };
812-
db.span_suggestion(span, "did you mean", format!("{punctuation}{best_match}{punctuation}"), Applicability::MaybeIncorrect);
810+
// Suggest the most probable if we found one
811+
if let Some(best_match) = find_best_match_for_name(&possibilities, value, None) {
812+
db.span_suggestion(value_span, "did you mean", format!("\"{best_match}\""), Applicability::MaybeIncorrect);
813+
}
814+
} else {
815+
db.note(&format!("no expected value for `{name}`"));
816+
if name != sym::feature {
817+
db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", String::new(), Applicability::MaybeIncorrect);
818+
}
813819
}
814820
},
815821
}

compiler/rustc_lint_defs/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ pub enum BuiltinLintDiagnostics {
426426
BreakWithLabelAndLoop(Span),
427427
NamedAsmLabel(String),
428428
UnicodeTextFlow(Span, String),
429-
UnexpectedCfg(Span, Symbol, Option<Symbol>),
429+
UnexpectedCfg((Symbol, Span), Option<(Symbol, Span)>),
430430
}
431431

432432
/// Lints that are buffered up early on in the `Session` before the

src/test/ui/check-cfg/empty-values.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ warning: unexpected `cfg` condition value
22
--> $DIR/empty-values.rs:6:7
33
|
44
LL | #[cfg(test = "value")]
5-
| ^^^^^^^^^^^^^^
5+
| ^^^^----------
6+
| |
7+
| help: remove the value
68
|
79
= note: `#[warn(unexpected_cfgs)]` on by default
810
= note: no expected value for `test`

src/test/ui/check-cfg/no-values.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
// Check that we detect unexpected value when none are allowed
22
//
33
// check-pass
4-
// compile-flags: --check-cfg=values(feature) -Z unstable-options
4+
// compile-flags: --check-cfg=values(test) --check-cfg=values(feature) -Z unstable-options
55

66
#[cfg(feature = "foo")]
77
//~^ WARNING unexpected `cfg` condition value
88
fn do_foo() {}
99

10+
#[cfg(test = "foo")]
11+
//~^ WARNING unexpected `cfg` condition value
12+
fn do_foo() {}
13+
1014
fn main() {}

src/test/ui/check-cfg/no-values.stderr

+11-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,15 @@ LL | #[cfg(feature = "foo")]
77
= note: `#[warn(unexpected_cfgs)]` on by default
88
= note: no expected value for `feature`
99

10-
warning: 1 warning emitted
10+
warning: unexpected `cfg` condition value
11+
--> $DIR/no-values.rs:10:7
12+
|
13+
LL | #[cfg(test = "foo")]
14+
| ^^^^--------
15+
| |
16+
| help: remove the value
17+
|
18+
= note: no expected value for `test`
19+
20+
warning: 2 warnings emitted
1121

src/test/ui/check-cfg/well-known-values.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ warning: unexpected `cfg` condition value
2323
--> $DIR/well-known-values.rs:21:7
2424
|
2525
LL | #[cfg(unix = "aa")]
26-
| ^^^^^^^^^^^
26+
| ^^^^-------
27+
| |
28+
| help: remove the value
2729
|
2830
= note: no expected value for `unix`
2931

0 commit comments

Comments
 (0)