Skip to content

Commit 69f53f5

Browse files
committed
Auto merge of #124679 - Urgau:check-cfg-structured-cli-errors, r=nnethercote
Improve check-cfg CLI errors with more structured diagnostics This PR improve check-cfg CLI errors with more structured diagnostics. In particular it now shows the statement where the error occurred, what kind lit it is, as well as pointing users to the doc for more details. `@rustbot` label +F-check-cfg
2 parents d287f3e + 228496e commit 69f53f5

28 files changed

+151
-34
lines changed

Diff for: Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4162,6 +4162,7 @@ dependencies = [
41624162
"rustc_ast",
41634163
"rustc_ast_lowering",
41644164
"rustc_ast_passes",
4165+
"rustc_ast_pretty",
41654166
"rustc_attr",
41664167
"rustc_borrowck",
41674168
"rustc_builtin_macros",

Diff for: compiler/rustc_ast/src/token.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl LitKind {
167167

168168
pub fn descr(self) -> &'static str {
169169
match self {
170-
Bool => panic!("literal token contains `Lit::Bool`"),
170+
Bool => "boolean",
171171
Byte => "byte",
172172
Char => "char",
173173
Integer => "integer",

Diff for: compiler/rustc_interface/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ rustc-rayon-core = { version = "0.5.0", optional = true }
1010
rustc_ast = { path = "../rustc_ast" }
1111
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
1212
rustc_ast_passes = { path = "../rustc_ast_passes" }
13+
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
1314
rustc_attr = { path = "../rustc_attr" }
1415
rustc_borrowck = { path = "../rustc_borrowck" }
1516
rustc_builtin_macros = { path = "../rustc_builtin_macros" }

Diff for: compiler/rustc_interface/src/interface.rs

+41-10
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,45 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
120120
);
121121
let filename = FileName::cfg_spec_source_code(&s);
122122

123+
const VISIT: &str =
124+
"visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details";
125+
123126
macro_rules! error {
124127
($reason:expr) => {
125128
#[allow(rustc::untranslatable_diagnostic)]
126129
#[allow(rustc::diagnostic_outside_of_impl)]
127-
dcx.fatal(format!(
128-
concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"),
129-
s
130-
))
130+
{
131+
let mut diag =
132+
dcx.struct_fatal(format!("invalid `--check-cfg` argument: `{s}`"));
133+
diag.note($reason);
134+
diag.note(VISIT);
135+
diag.emit()
136+
}
137+
};
138+
(in $arg:expr, $reason:expr) => {
139+
#[allow(rustc::untranslatable_diagnostic)]
140+
#[allow(rustc::diagnostic_outside_of_impl)]
141+
{
142+
let mut diag =
143+
dcx.struct_fatal(format!("invalid `--check-cfg` argument: `{s}`"));
144+
145+
let pparg = rustc_ast_pretty::pprust::meta_list_item_to_string($arg);
146+
if let Some(lit) = $arg.lit() {
147+
let (lit_kind_article, lit_kind_descr) = {
148+
let lit_kind = lit.as_token_lit().kind;
149+
(lit_kind.article(), lit_kind.descr())
150+
};
151+
diag.note(format!(
152+
"`{pparg}` is {lit_kind_article} {lit_kind_descr} literal"
153+
));
154+
} else {
155+
diag.note(format!("`{pparg}` is invalid"));
156+
}
157+
158+
diag.note($reason);
159+
diag.note(VISIT);
160+
diag.emit()
161+
}
131162
};
132163
}
133164

@@ -183,7 +214,7 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
183214
}
184215
any_specified = true;
185216
if !args.is_empty() {
186-
error!("`any()` must be empty");
217+
error!(in arg, "`any()` takes no argument");
187218
}
188219
} else if arg.has_name(sym::values)
189220
&& let Some(args) = arg.meta_item_list()
@@ -202,25 +233,25 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
202233
&& let Some(args) = arg.meta_item_list()
203234
{
204235
if values_any_specified {
205-
error!("`any()` in `values()` cannot be specified multiple times");
236+
error!(in arg, "`any()` in `values()` cannot be specified multiple times");
206237
}
207238
values_any_specified = true;
208239
if !args.is_empty() {
209-
error!("`any()` must be empty");
240+
error!(in arg, "`any()` in `values()` takes no argument");
210241
}
211242
} else if arg.has_name(sym::none)
212243
&& let Some(args) = arg.meta_item_list()
213244
{
214245
values.insert(None);
215246
if !args.is_empty() {
216-
error!("`none()` must be empty");
247+
error!(in arg, "`none()` in `values()` takes no argument");
217248
}
218249
} else {
219-
error!("`values()` arguments must be string literals, `none()` or `any()`");
250+
error!(in arg, "`values()` arguments must be string literals, `none()` or `any()`");
220251
}
221252
}
222253
} else {
223-
error!("`cfg()` arguments must be simple identifiers, `any()` or `values(...)`");
254+
error!(in arg, "`cfg()` arguments must be simple identifiers, `any()` or `values(...)`");
224255
}
225256
}
226257

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `cfg(any(),values())` (`values()` cannot be specified before the names)
1+
error: invalid `--check-cfg` argument: `cfg(any(),values())`
2+
|
3+
= note: `values()` cannot be specified before the names
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `anything_else(...)` (expected `cfg(name, values("value1", "value2", ... "valueN"))`)
1+
error: invalid `--check-cfg` argument: `anything_else(...)`
2+
|
3+
= note: expected `cfg(name, values("value1", "value2", ... "valueN"))`
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

Diff for: tests/ui/check-cfg/invalid-arguments.boolean.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
error: invalid `--check-cfg` argument: `cfg(true)`
2+
|
3+
= note: `true` is a boolean literal
4+
= note: `cfg()` arguments must be simple identifiers, `any()` or `values(...)`
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
6+

Diff for: tests/ui/check-cfg/invalid-arguments.cfg_none.stderr

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(none())` (`cfg()` arguments must be simple identifiers, `any()` or `values(...)`)
1+
error: invalid `--check-cfg` argument: `cfg(none())`
2+
|
3+
= note: `none()` is invalid
4+
= note: `cfg()` arguments must be simple identifiers, `any()` or `values(...)`
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

Diff for: tests/ui/check-cfg/invalid-arguments.giberich.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `cfg(...)` (expected `cfg(name, values("value1", "value2", ... "valueN"))`)
1+
error: invalid `--check-cfg` argument: `cfg(...)`
2+
|
3+
= note: expected `cfg(name, values("value1", "value2", ... "valueN"))`
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,values(bar))` (`values()` arguments must be string literals, `none()` or `any()`)
1+
error: invalid `--check-cfg` argument: `cfg(foo,values(bar))`
2+
|
3+
= note: `bar` is invalid
4+
= note: `values()` arguments must be string literals, `none()` or `any()`
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,values("bar",bar,"bar"))` (`values()` arguments must be string literals, `none()` or `any()`)
1+
error: invalid `--check-cfg` argument: `cfg(foo,values("bar",bar,"bar"))`
2+
|
3+
= note: `bar` is invalid
4+
= note: `values()` arguments must be string literals, `none()` or `any()`
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `cfg(any(),values(any()))` (`values()` cannot be specified before the names)
1+
error: invalid `--check-cfg` argument: `cfg(any(),values(any()))`
2+
|
3+
= note: `values()` cannot be specified before the names
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,values("bar",any()))` (`values()` arguments cannot specify string literals and `any()` at the same time)
1+
error: invalid `--check-cfg` argument: `cfg(foo,values("bar",any()))`
2+
|
3+
= note: `values()` arguments cannot specify string literals and `any()` at the same time
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `cfg(any(),any())` (`any()` cannot be specified multiple times)
1+
error: invalid `--check-cfg` argument: `cfg(any(),any())`
2+
|
3+
= note: `any()` cannot be specified multiple times
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,values(),values())` (`values()` cannot be specified multiple times)
1+
error: invalid `--check-cfg` argument: `cfg(foo,values(),values())`
2+
|
3+
= note: `values()` cannot be specified multiple times
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,values(any(),any()))` (`any()` in `values()` cannot be specified multiple times)
1+
error: invalid `--check-cfg` argument: `cfg(foo,values(any(),any()))`
2+
|
3+
= note: `any()` is invalid
4+
= note: `any()` in `values()` cannot be specified multiple times
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,values(none("test")))` (`none()` must be empty)
1+
error: invalid `--check-cfg` argument: `cfg(foo,values(none("test")))`
2+
|
3+
= note: `none("test")` is invalid
4+
= note: `none()` in `values()` takes no argument
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(any(foo))` (`any()` must be empty)
1+
error: invalid `--check-cfg` argument: `cfg(any(foo))`
2+
|
3+
= note: `any(foo)` is invalid
4+
= note: `any()` takes no argument
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,values(any(bar)))` (`any()` must be empty)
1+
error: invalid `--check-cfg` argument: `cfg(foo,values(any(bar)))`
2+
|
3+
= note: `any(bar)` is invalid
4+
= note: `any()` in `values()` takes no argument
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

Diff for: tests/ui/check-cfg/invalid-arguments.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
//@ check-fail
44
//@ no-auto-check-cfg
5-
//@ revisions: anything_else
5+
//@ revisions: anything_else boolean
66
//@ revisions: string_for_name_1 string_for_name_2 multiple_any multiple_values
77
//@ revisions: multiple_values_any not_empty_any not_empty_values_any
88
//@ revisions: values_any_missing_values values_any_before_ident ident_in_values_1
@@ -11,6 +11,7 @@
1111
//@ revisions: none_not_empty cfg_none
1212
//
1313
//@ [anything_else]compile-flags: --check-cfg=anything_else(...)
14+
//@ [boolean]compile-flags: --check-cfg=cfg(true)
1415
//@ [string_for_name_1]compile-flags: --check-cfg=cfg("NOT_IDENT")
1516
//@ [string_for_name_2]compile-flags: --check-cfg=cfg(foo,"NOT_IDENT",bar)
1617
//@ [multiple_any]compile-flags: --check-cfg=cfg(any(),any())
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg("NOT_IDENT")` (`cfg()` arguments must be simple identifiers, `any()` or `values(...)`)
1+
error: invalid `--check-cfg` argument: `cfg("NOT_IDENT")`
2+
|
3+
= note: `"NOT_IDENT"` is a string literal
4+
= note: `cfg()` arguments must be simple identifiers, `any()` or `values(...)`
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,"NOT_IDENT",bar)` (`cfg()` arguments must be simple identifiers, `any()` or `values(...)`)
1+
error: invalid `--check-cfg` argument: `cfg(foo,"NOT_IDENT",bar)`
2+
|
3+
= note: `"NOT_IDENT"` is a string literal
4+
= note: `cfg()` arguments must be simple identifiers, `any()` or `values(...)`
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `abc()` (expected `cfg(name, values("value1", "value2", ... "valueN"))`)
1+
error: invalid `--check-cfg` argument: `abc()`
2+
|
3+
= note: expected `cfg(name, values("value1", "value2", ... "valueN"))`
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,test())` (`cfg()` arguments must be simple identifiers, `any()` or `values(...)`)
1+
error: invalid `--check-cfg` argument: `cfg(foo,test())`
2+
|
3+
= note: `test()` is invalid
4+
= note: `cfg()` arguments must be simple identifiers, `any()` or `values(...)`
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,values(test()))` (`values()` arguments must be string literals, `none()` or `any()`)
1+
error: invalid `--check-cfg` argument: `cfg(foo,values(test()))`
2+
|
3+
= note: `test()` is invalid
4+
= note: `values()` arguments must be string literals, `none()` or `any()`
5+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
26

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `cfg(` (expected `cfg(name, values("value1", "value2", ... "valueN"))`)
1+
error: invalid `--check-cfg` argument: `cfg(`
2+
|
3+
= note: expected `cfg(name, values("value1", "value2", ... "valueN"))`
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `cfg(values(any()),foo)` (`values()` cannot be specified before the names)
1+
error: invalid `--check-cfg` argument: `cfg(values(any()),foo)`
2+
|
3+
= note: `values()` cannot be specified before the names
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
error: invalid `--check-cfg` argument: `cfg(foo,any())` (`cfg(any())` can only be provided in isolation)
1+
error: invalid `--check-cfg` argument: `cfg(foo,any())`
2+
|
3+
= note: `cfg(any())` can only be provided in isolation
4+
= note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
25

0 commit comments

Comments
 (0)