Skip to content

Commit 61ff7de

Browse files
committed
Suggest name value cfg when only value is used for check-cfg
1 parent 6351247 commit 61ff7de

File tree

5 files changed

+113
-10
lines changed

5 files changed

+113
-10
lines changed

compiler/rustc_lint/src/context/diagnostics.rs

+40-10
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,24 @@ pub(super) fn builtin(
187187
BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => {
188188
let possibilities: Vec<Symbol> =
189189
sess.parse_sess.check_config.expecteds.keys().copied().collect();
190+
191+
let mut names_possibilities: Vec<_> = if value.is_none() {
192+
// We later sort and display all the possibilities, so the order here does not matter.
193+
#[allow(rustc::potential_query_instability)]
194+
sess.parse_sess
195+
.check_config
196+
.expecteds
197+
.iter()
198+
.filter_map(|(k, v)| match v {
199+
ExpectedValues::Some(v) if v.contains(&Some(name)) => Some(k),
200+
_ => None,
201+
})
202+
.collect()
203+
} else {
204+
Vec::new()
205+
};
206+
names_possibilities.sort();
207+
190208
let is_from_cargo = std::env::var_os("CARGO").is_some();
191209
let mut is_feature_cfg = name == sym::feature;
192210

@@ -261,17 +279,29 @@ pub(super) fn builtin(
261279
}
262280

263281
is_feature_cfg |= best_match == sym::feature;
264-
} else if !possibilities.is_empty() {
265-
let mut possibilities =
266-
possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>();
267-
possibilities.sort();
268-
let possibilities = possibilities.join("`, `");
282+
} else {
283+
if !names_possibilities.is_empty() {
284+
for cfg_name in names_possibilities.iter() {
285+
db.span_suggestion(
286+
name_span,
287+
"found config with similar value",
288+
format!("{cfg_name} = \"{name}\""),
289+
Applicability::MaybeIncorrect,
290+
);
291+
}
292+
}
293+
if !possibilities.is_empty() {
294+
let mut possibilities =
295+
possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>();
296+
possibilities.sort();
297+
let possibilities = possibilities.join("`, `");
269298

270-
// The list of expected names can be long (even by default) and
271-
// so the diagnostic produced can take a lot of space. To avoid
272-
// cloging the user output we only want to print that diagnostic
273-
// once.
274-
db.help_once(format!("expected names are: `{possibilities}`"));
299+
// The list of expected names can be long (even by default) and
300+
// so the diagnostic produced can take a lot of space. To avoid
301+
// cloging the user output we only want to print that diagnostic
302+
// once.
303+
db.help_once(format!("expected names are: `{possibilities}`"));
304+
}
275305
}
276306

277307
let inst = if let Some((value, _value_span)) = value {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// #120427
2+
// This test checks that when a single cfg has a value for user's specified name
3+
//
4+
// check-pass
5+
// compile-flags: -Z unstable-options
6+
// compile-flags: --check-cfg=cfg(foo,values("my_value")) --check-cfg=cfg(bar,values("my_value"))
7+
8+
#[cfg(my_value)]
9+
//~^ WARNING unexpected `cfg` condition name: `my_value`
10+
fn x() {}
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
warning: unexpected `cfg` condition name: `my_value`
2+
--> $DIR/cfg-value-for-cfg-name-multiple.rs:8:7
3+
|
4+
LL | #[cfg(my_value)]
5+
| ^^^^^^^^
6+
|
7+
= help: expected names are: `bar`, `debug_assertions`, `doc`, `doctest`, `foo`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows`
8+
= help: to expect this configuration use `--check-cfg=cfg(my_value)`
9+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
10+
= note: `#[warn(unexpected_cfgs)]` on by default
11+
help: found config with similar value
12+
|
13+
LL | #[cfg(foo = "my_value")]
14+
| ~~~~~~~~~~~~~~~~
15+
help: found config with similar value
16+
|
17+
LL | #[cfg(bar = "my_value")]
18+
| ~~~~~~~~~~~~~~~~
19+
20+
warning: 1 warning emitted
21+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// #120427
2+
// This test checks that when a single cfg has a value for user's specified name
3+
// suggest to use `#[cfg(target_os = "linux")]` instead of `#[cfg(linux)]`
4+
//
5+
// check-pass
6+
// compile-flags: -Z unstable-options
7+
// compile-flags: --check-cfg=cfg()
8+
9+
#[cfg(linux)]
10+
//~^ WARNING unexpected `cfg` condition name: `linux`
11+
fn x() {}
12+
13+
// will not suggest if the cfg has a value
14+
#[cfg(linux = "os-name")]
15+
//~^ WARNING unexpected `cfg` condition name: `linux`
16+
fn y() {}
17+
18+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
warning: unexpected `cfg` condition name: `linux`
2+
--> $DIR/cfg-value-for-cfg-name.rs:9:7
3+
|
4+
LL | #[cfg(linux)]
5+
| ^^^^^ help: found config with similar value: `target_os = "linux"`
6+
|
7+
= help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows`
8+
= help: to expect this configuration use `--check-cfg=cfg(linux)`
9+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
10+
= note: `#[warn(unexpected_cfgs)]` on by default
11+
12+
warning: unexpected `cfg` condition name: `linux`
13+
--> $DIR/cfg-value-for-cfg-name.rs:14:7
14+
|
15+
LL | #[cfg(linux = "os-name")]
16+
| ^^^^^^^^^^^^^^^^^
17+
|
18+
= help: to expect this configuration use `--check-cfg=cfg(linux, values("os-name"))`
19+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
20+
21+
warning: 2 warnings emitted
22+

0 commit comments

Comments
 (0)