Skip to content

Commit 5aac5bb

Browse files
committed
Add more suggestion to unexpected cfg names and values
1 parent 855c683 commit 5aac5bb

40 files changed

+539
-77
lines changed

compiler/rustc_lint/src/context.rs

+82-3
Original file line numberDiff line numberDiff line change
@@ -704,9 +704,13 @@ pub trait LintContext {
704704
},
705705
BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => {
706706
let possibilities: Vec<Symbol> = sess.parse_sess.check_config.expecteds.keys().copied().collect();
707+
let is_from_cargo = std::env::var_os("CARGO").is_some();
708+
let mut is_feature_cfg = name == sym::feature;
707709

710+
if is_feature_cfg && is_from_cargo {
711+
db.help("consider defining some features in `Cargo.toml`");
708712
// Suggest the most probable if we found one
709-
if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) {
713+
} else if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) {
710714
if let Some(ExpectedValues::Some(best_match_values)) =
711715
sess.parse_sess.check_config.expecteds.get(&best_match) {
712716
let mut possibilities = best_match_values.iter()
@@ -739,8 +743,8 @@ pub trait LintContext {
739743
} else {
740744
db.span_suggestion(name_span, "there is a config with a similar name", best_match, Applicability::MaybeIncorrect);
741745
}
742-
} else if name == sym::feature && std::env::var_os("CARGO").is_some() {
743-
db.help("consider defining some features in `Cargo.toml`");
746+
747+
is_feature_cfg |= best_match == sym::feature;
744748
} else if !possibilities.is_empty() {
745749
let mut possibilities = possibilities.iter()
746750
.map(Symbol::as_str)
@@ -754,6 +758,23 @@ pub trait LintContext {
754758
// once.
755759
db.help_once(format!("expected names are: `{possibilities}`"));
756760
}
761+
762+
let inst = if let Some((value, _value_span)) = value {
763+
let pre = if is_from_cargo { "\\" } else { "" };
764+
format!("cfg({name}, values({pre}\"{value}{pre}\"))")
765+
} else {
766+
format!("cfg({name})")
767+
};
768+
769+
if is_from_cargo {
770+
if !is_feature_cfg {
771+
db.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`"));
772+
}
773+
db.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration");
774+
} else {
775+
db.help(format!("to expect this configuration use `--check-cfg={inst}`"));
776+
db.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration");
777+
}
757778
},
758779
BuiltinLintDiagnostics::UnexpectedCfgValue((name, name_span), value) => {
759780
let Some(ExpectedValues::Some(values)) = &sess.parse_sess.check_config.expecteds.get(&name) else {
@@ -765,6 +786,7 @@ pub trait LintContext {
765786
.copied()
766787
.flatten()
767788
.collect();
789+
let is_from_cargo = std::env::var_os("CARGO").is_some();
768790

769791
// Show the full list if all possible values for a given name, but don't do it
770792
// for names as the possibilities could be very long
@@ -785,6 +807,8 @@ pub trait LintContext {
785807
db.span_suggestion(value_span, "there is a expected value with a similar name", format!("\"{best_match}\""), Applicability::MaybeIncorrect);
786808

787809
}
810+
} else if name == sym::feature && is_from_cargo {
811+
db.help(format!("consider defining `{name}` as feature in `Cargo.toml`"));
788812
} else if let &[first_possibility] = &possibilities[..] {
789813
db.span_suggestion(name_span.shrink_to_hi(), "specify a config value", format!(" = \"{first_possibility}\""), Applicability::MaybeIncorrect);
790814
}
@@ -794,6 +818,61 @@ pub trait LintContext {
794818
db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", "", Applicability::MaybeIncorrect);
795819
}
796820
}
821+
822+
// We don't want to suggest adding values to well known names
823+
// since those are defined by rustc it-self. Users can still
824+
// do it if they want, but should not encourage them.
825+
const WELL_KNOWN_NAMES: &'static [Symbol] = &[
826+
sym::doc,
827+
sym::miri,
828+
sym::unix,
829+
sym::test,
830+
sym::doctest,
831+
sym::windows,
832+
sym::proc_macro,
833+
sym::panic,
834+
sym::sanitize,
835+
sym::relocation_model,
836+
sym::debug_assertions,
837+
sym::overflow_checks,
838+
sym::target_thread_local,
839+
sym::target_feature,
840+
sym::target_os,
841+
sym::target_family,
842+
sym::target_arch,
843+
sym::target_endian,
844+
sym::target_env,
845+
sym::target_abi,
846+
sym::target_vendor,
847+
sym::target_pointer_width,
848+
sym::target_has_atomic,
849+
sym::target_has_atomic_load_store,
850+
sym::target_has_atomic_equal_alignment,
851+
];
852+
853+
let is_cfg_a_well_know_name = WELL_KNOWN_NAMES.contains(&name);
854+
let inst = if let Some((value, _value_span)) = value {
855+
let pre = if is_from_cargo { "\\" } else { "" };
856+
format!("cfg({name}, values({pre}\"{value}{pre}\"))")
857+
} else {
858+
format!("cfg({name})")
859+
};
860+
861+
if is_from_cargo {
862+
if name == sym::feature {
863+
if let Some((value, _value_span)) = value {
864+
db.help(format!("consider adding `{value}` as a feature in `Cargo.toml`"));
865+
}
866+
} else if !is_cfg_a_well_know_name {
867+
db.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`"));
868+
}
869+
db.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration");
870+
} else {
871+
if !is_cfg_a_well_know_name {
872+
db.help(format!("to expect this configuration use `--check-cfg={inst}`"));
873+
}
874+
db.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration");
875+
}
797876
},
798877
BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(new_span, suggestion) => {
799878
db.multipart_suggestion(

tests/rustdoc-ui/check-cfg/check-cfg.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ warning: unexpected `cfg` condition name: `uniz`
44
LL | #[cfg(uniz)]
55
| ^^^^ help: there is a config with a similar name: `unix`
66
|
7+
= help: to expect this configuration use `--check-cfg=cfg(uniz)`
8+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
79
= note: `#[warn(unexpected_cfgs)]` on by default
810

911
warning: 1 warning emitted

tests/rustdoc-ui/doctest/check-cfg-test.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | #[cfg(feature = "invalid")]
55
| ^^^^^^^^^^^^^^^^^^^
66
|
77
= note: expected values for `feature` are: `test`
8+
= help: to expect this configuration use `--check-cfg=cfg(feature, values("invalid"))`
9+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
810
= note: `#[warn(unexpected_cfgs)]` on by default
911

1012
warning: 1 warning emitted

tests/ui/check-cfg/allow-same-level.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | #[cfg(FALSE)]
55
| ^^^^^
66
|
77
= help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `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(FALSE)`
9+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
810
= note: `#[warn(unexpected_cfgs)]` on by default
911

1012
warning: 1 warning emitted
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
warning: unexpected `cfg` condition name: `feature`
2+
--> $DIR/cargo-feature.rs:13:7
3+
|
4+
LL | #[cfg(feature = "serde")]
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= help: consider defining some features in `Cargo.toml`
8+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
9+
= note: `#[warn(unexpected_cfgs)]` on by default
10+
11+
warning: unexpected `cfg` condition name: `tokio_unstable`
12+
--> $DIR/cargo-feature.rs:18:7
13+
|
14+
LL | #[cfg(tokio_unstable)]
15+
| ^^^^^^^^^^^^^^
16+
|
17+
= help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `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`
18+
= help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(tokio_unstable)");` to the top of a `build.rs`
19+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
20+
21+
warning: unexpected `cfg` condition name: `CONFIG_NVME`
22+
--> $DIR/cargo-feature.rs:22:7
23+
|
24+
LL | #[cfg(CONFIG_NVME = "m")]
25+
| ^^^^^^^^^^^^^^^^^
26+
|
27+
= help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of a `build.rs`
28+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
29+
30+
warning: 3 warnings emitted
31+

tests/ui/check-cfg/cargo-feature.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,25 @@
33
// list of all the expected names
44
//
55
// check-pass
6+
// revisions: some none
67
// rustc-env:CARGO=/usr/bin/cargo
78
// compile-flags: --check-cfg=cfg() -Z unstable-options
8-
// error-pattern:Cargo.toml
9+
// [some]compile-flags: --check-cfg=cfg(feature,values("bitcode"))
10+
// [some]compile-flags: --check-cfg=cfg(CONFIG_NVME,values("y"))
11+
// [none]error-pattern:Cargo.toml
912

1013
#[cfg(feature = "serde")]
11-
//~^ WARNING unexpected `cfg` condition name
14+
//[none]~^ WARNING unexpected `cfg` condition name
15+
//[some]~^^ WARNING unexpected `cfg` condition value
1216
fn ser() {}
1317

18+
#[cfg(tokio_unstable)]
19+
//~^ WARNING unexpected `cfg` condition name
20+
fn tokio() {}
21+
22+
#[cfg(CONFIG_NVME = "m")]
23+
//[none]~^ WARNING unexpected `cfg` condition name
24+
//[some]~^^ WARNING unexpected `cfg` condition value
25+
fn tokio() {}
26+
1427
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
warning: unexpected `cfg` condition value: `serde`
2+
--> $DIR/cargo-feature.rs:13:7
3+
|
4+
LL | #[cfg(feature = "serde")]
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: expected values for `feature` are: `bitcode`
8+
= help: consider adding `serde` as a feature in `Cargo.toml`
9+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
10+
= note: `#[warn(unexpected_cfgs)]` on by default
11+
12+
warning: unexpected `cfg` condition name: `tokio_unstable`
13+
--> $DIR/cargo-feature.rs:18:7
14+
|
15+
LL | #[cfg(tokio_unstable)]
16+
| ^^^^^^^^^^^^^^
17+
|
18+
= help: expected names are: `CONFIG_NVME`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `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`
19+
= help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(tokio_unstable)");` to the top of a `build.rs`
20+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
21+
22+
warning: unexpected `cfg` condition value: `m`
23+
--> $DIR/cargo-feature.rs:22:7
24+
|
25+
LL | #[cfg(CONFIG_NVME = "m")]
26+
| ^^^^^^^^^^^^^^---
27+
| |
28+
| help: there is a expected value with a similar name: `"y"`
29+
|
30+
= note: expected values for `CONFIG_NVME` are: `y`
31+
= help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of a `build.rs`
32+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
33+
34+
warning: 3 warnings emitted
35+

tests/ui/check-cfg/cargo-feature.stderr

-11
This file was deleted.

tests/ui/check-cfg/compact-names.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | #[cfg(target(os = "linux", architecture = "arm"))]
55
| ^^^^^^^^^^^^^^^^^^^^
66
|
77
= help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `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(target_architecture, values("arm"))`
9+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
810
= note: `#[warn(unexpected_cfgs)]` on by default
911

1012
warning: 1 warning emitted

tests/ui/check-cfg/compact-values.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | #[cfg(target(os = "linux", arch = "X"))]
55
| ^^^^^^^^^^
66
|
77
= note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`
8+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
89
= note: `#[warn(unexpected_cfgs)]` on by default
910

1011
warning: 1 warning emitted

tests/ui/check-cfg/concat-values.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | #[cfg(my_cfg)]
55
| ^^^^^^
66
|
77
= note: expected values for `my_cfg` are: `bar`, `foo`
8+
= help: to expect this configuration use `--check-cfg=cfg(my_cfg)`
9+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
810
= note: `#[warn(unexpected_cfgs)]` on by default
911

1012
warning: unexpected `cfg` condition value: `unk`
@@ -14,6 +16,8 @@ LL | #[cfg(my_cfg = "unk")]
1416
| ^^^^^^^^^^^^^^
1517
|
1618
= note: expected values for `my_cfg` are: `bar`, `foo`
19+
= help: to expect this configuration use `--check-cfg=cfg(my_cfg, values("unk"))`
20+
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
1721

1822
warning: 2 warnings emitted
1923

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
warning: unexpected `cfg` condition name: `featur`
2+
--> $DIR/diagnotics.rs:7:7
3+
|
4+
LL | #[cfg(featur)]
5+
| ^^^^^^ help: there is a config with a similar name: `feature`
6+
|
7+
= help: expected values for `feature` are: `foo`
8+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
9+
= note: `#[warn(unexpected_cfgs)]` on by default
10+
11+
warning: unexpected `cfg` condition name: `featur`
12+
--> $DIR/diagnotics.rs:11:7
13+
|
14+
LL | #[cfg(featur = "foo")]
15+
| ^^^^^^^^^^^^^^
16+
|
17+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
18+
help: there is a config with a similar name and value
19+
|
20+
LL | #[cfg(feature = "foo")]
21+
| ~~~~~~~
22+
23+
warning: unexpected `cfg` condition name: `featur`
24+
--> $DIR/diagnotics.rs:15:7
25+
|
26+
LL | #[cfg(featur = "fo")]
27+
| ^^^^^^^^^^^^^
28+
|
29+
= help: expected values for `feature` are: `foo`
30+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
31+
help: there is a config with a similar name and different values
32+
|
33+
LL | #[cfg(feature = "foo")]
34+
| ~~~~~~~~~~~~~~~
35+
36+
warning: unexpected `cfg` condition name: `no_value`
37+
--> $DIR/diagnotics.rs:22:7
38+
|
39+
LL | #[cfg(no_value)]
40+
| ^^^^^^^^ help: there is a config with a similar name: `no_values`
41+
|
42+
= help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(no_value)");` to the top of a `build.rs`
43+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
44+
45+
warning: unexpected `cfg` condition name: `no_value`
46+
--> $DIR/diagnotics.rs:26:7
47+
|
48+
LL | #[cfg(no_value = "foo")]
49+
| ^^^^^^^^^^^^^^^^
50+
|
51+
= help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(no_value, values(\"foo\"))");` to the top of a `build.rs`
52+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
53+
help: there is a config with a similar name and no value
54+
|
55+
LL | #[cfg(no_values)]
56+
| ~~~~~~~~~
57+
58+
warning: unexpected `cfg` condition value: `bar`
59+
--> $DIR/diagnotics.rs:30:7
60+
|
61+
LL | #[cfg(no_values = "bar")]
62+
| ^^^^^^^^^--------
63+
| |
64+
| help: remove the value
65+
|
66+
= note: no expected value for `no_values`
67+
= help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(no_values, values(\"bar\"))");` to the top of a `build.rs`
68+
= note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration
69+
70+
warning: 6 warnings emitted
71+

0 commit comments

Comments
 (0)