Skip to content

Commit 228496e

Browse files
committed
Improve check-cfg CLI errors with more structured diagnostics
1 parent 0b418f2 commit 228496e

27 files changed

+150
-33
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_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)