Skip to content

Commit c6f3767

Browse files
authored
Unrolled build for rust-lang#118855
Rollup merge of rust-lang#118855 - nnethercote:improve-attribute-value-error, r=compiler-errors,petrochenkov Improve an error involving attribute values. Attribute values must be literals. The error you get when that doesn't hold is pretty bad, e.g.: ``` unexpected expression: 1 + 1 ``` You also get the same error if the attribute value is a literal, but an invalid literal, e.g.: ``` unexpected expression: "foo"suffix ``` This commit does two things. - Changes the error message to "attribute value must be a literal", which gives a better idea of what the problem is and how to fix it. It also no longer prints the invalid expression, because the carets below highlight it anyway. - Separates the "not a literal" case from the "invalid literal" case. Which means invalid literals now get the specific error at the literal level, rather than at the attribute level. r? `@compiler-errors`
2 parents 835ed00 + 226edf6 commit c6f3767

17 files changed

+87
-62
lines changed

compiler/rustc_parse/src/validate_attr.rs

+38-22
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use rustc_ast::token::Delimiter;
66
use rustc_ast::tokenstream::DelimSpan;
77
use rustc_ast::MetaItemKind;
88
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem};
9-
use rustc_ast_pretty::pprust;
109
use rustc_errors::{Applicability, FatalError, PResult};
1110
use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
11+
use rustc_session::errors::report_lit_error;
1212
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
1313
use rustc_session::parse::ParseSess;
1414
use rustc_span::{sym, Span, Symbol};
@@ -51,28 +51,44 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
5151
MetaItemKind::List(nmis)
5252
}
5353
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
54-
if let ast::ExprKind::Lit(token_lit) = expr.kind
55-
&& let Ok(lit) = ast::MetaItemLit::from_token_lit(token_lit, expr.span)
56-
{
57-
if token_lit.suffix.is_some() {
58-
let mut err = sess.span_diagnostic.struct_span_err(
59-
expr.span,
60-
"suffixed literals are not allowed in attributes",
61-
);
62-
err.help(
63-
"instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), \
64-
use an unsuffixed version (`1`, `1.0`, etc.)",
65-
);
66-
return Err(err);
67-
} else {
68-
MetaItemKind::NameValue(lit)
69-
}
54+
if let ast::ExprKind::Lit(token_lit) = expr.kind {
55+
let res = ast::MetaItemLit::from_token_lit(token_lit, expr.span);
56+
let res = match res {
57+
Ok(lit) => {
58+
if token_lit.suffix.is_some() {
59+
let mut err = sess.span_diagnostic.struct_span_err(
60+
expr.span,
61+
"suffixed literals are not allowed in attributes",
62+
);
63+
err.help(
64+
"instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), \
65+
use an unsuffixed version (`1`, `1.0`, etc.)",
66+
);
67+
return Err(err);
68+
} else {
69+
MetaItemKind::NameValue(lit)
70+
}
71+
}
72+
Err(err) => {
73+
report_lit_error(sess, err, token_lit, expr.span);
74+
let lit = ast::MetaItemLit {
75+
symbol: token_lit.symbol,
76+
suffix: token_lit.suffix,
77+
kind: ast::LitKind::Err,
78+
span: expr.span,
79+
};
80+
MetaItemKind::NameValue(lit)
81+
}
82+
};
83+
res
7084
} else {
71-
// The non-error case can happen with e.g. `#[foo = 1+1]`. The error case can
72-
// happen with e.g. `#[foo = include_str!("nonexistent-file.rs")]`; in that
73-
// case we delay the error because an earlier error will have already been
74-
// reported.
75-
let msg = format!("unexpected expression: `{}`", pprust::expr_to_string(expr));
85+
// Example cases:
86+
// - `#[foo = 1+1]`: results in `ast::ExprKind::BinOp`.
87+
// - `#[foo = include_str!("nonexistent-file.rs")]`:
88+
// results in `ast::ExprKind::Err`. In that case we delay
89+
// the error because an earlier error will have already
90+
// been reported.
91+
let msg = format!("attribute value must be a literal");
7692
let mut err = sess.span_diagnostic.struct_span_err(expr.span, msg);
7793
if let ast::ExprKind::Err = expr.kind {
7894
err.downgrade_to_delayed_bug();

tests/ui/attributes/issue-90873.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#![u=||{static d=||1;}]
2-
//~^ unexpected expression
2+
//~^ attribute value must be a literal
33
//~| cannot find attribute `u` in this scope
44
//~| missing type for `static` item
55

66
#![a={impl std::ops::Neg for i8 {}}]
7-
//~^ ERROR unexpected expression
7+
//~^ ERROR attribute value must be a literal
88
//~| ERROR cannot find attribute `a` in this scope
99
//~| ERROR `main` function not found in crate `issue_90873`

tests/ui/attributes/issue-90873.stderr

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
error: unexpected expression: `||
2-
{
3-
static d: _ = || 1;
4-
}`
1+
error: attribute value must be a literal
52
--> $DIR/issue-90873.rs:1:6
63
|
74
LL | #![u=||{static d=||1;}]
85
| ^^^^^^^^^^^^^^^^^
96

10-
error: unexpected expression: `{
11-
impl std::ops::Neg for i8 {}
12-
}`
7+
error: attribute value must be a literal
138
--> $DIR/issue-90873.rs:6:6
149
|
1510
LL | #![a={impl std::ops::Neg for i8 {}}]

tests/ui/attributes/key-value-expansion-on-mac.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ macro_rules! bar {
77

88
// FIXME?: `bar` here expands before `stringify` has a chance to expand.
99
// `#[rustc_dummy = ...]` is validated and dropped during expansion of `bar`,
10-
// the "unexpected expression" errors comes from the validation.
11-
#[rustc_dummy = stringify!(b)] //~ ERROR unexpected expression: `stringify!(b)`
10+
// the "attribute value must be a literal" error comes from the validation.
11+
#[rustc_dummy = stringify!(b)] //~ ERROR attribute value must be a literal
1212
bar!();
1313

1414
fn main() {}

tests/ui/attributes/key-value-expansion-on-mac.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: unexpected expression: `stringify!(b)`
1+
error: attribute value must be a literal
22
--> $DIR/key-value-expansion-on-mac.rs:11:17
33
|
44
LL | #[rustc_dummy = stringify!(b)]

tests/ui/attributes/key-value-expansion.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ macro_rules! bug {
1818

1919
// Any expressions containing macro call `X` that's more complex than `X` itself.
2020
// Parentheses will work.
21-
bug!((column!())); //~ ERROR unexpected expression: `(7u32)`
21+
bug!((column!())); //~ ERROR attribute value must be a literal
2222

2323
// Original test case.
2424

2525
macro_rules! bug {
2626
() => {
27-
bug!("bug" + stringify!(found)); //~ ERROR unexpected expression: `"bug" + "found"`
27+
bug!("bug" + stringify!(found)); //~ ERROR attribute value must be a literal
2828
};
2929
($test:expr) => {
3030
#[doc = $test]
@@ -46,7 +46,7 @@ macro_rules! doc_comment {
4646
macro_rules! some_macro {
4747
($t1: ty) => {
4848
doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()}
49-
//~^ ERROR unexpected expression: `{
49+
//~^ ERROR attribute value must be a literal
5050
};
5151
}
5252

tests/ui/attributes/key-value-expansion.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: unexpected expression: `(7u32)`
1+
error: attribute value must be a literal
22
--> $DIR/key-value-expansion.rs:21:6
33
|
44
LL | bug!((column!()));
55
| ^^^^^^^^^^^
66

7-
error: unexpected expression: `"bug" + "found"`
7+
error: attribute value must be a literal
88
--> $DIR/key-value-expansion.rs:27:14
99
|
1010
LL | bug!("bug" + stringify!(found));
@@ -15,7 +15,7 @@ LL | bug!();
1515
|
1616
= note: this error originates in the macro `bug` (in Nightly builds, run with -Z macro-backtrace for more info)
1717

18-
error: unexpected expression: `{ let res = ::alloc::fmt::format(format_args!("{0}", "u8")); res }.as_str()`
18+
error: attribute value must be a literal
1919
--> $DIR/key-value-expansion.rs:48:23
2020
|
2121
LL | doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()}

tests/ui/attributes/unused-item-in-attr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#[w = { extern crate alloc; }]
2-
//~^ ERROR unexpected expression: `{
2+
//~^ ERROR attribute value must be a literal
33
//~| ERROR cannot find attribute `w` in this scope
44
fn f() {}
55

tests/ui/attributes/unused-item-in-attr.stderr

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
error: unexpected expression: `{
2-
extern crate alloc;
3-
}`
1+
error: attribute value must be a literal
42
--> $DIR/unused-item-in-attr.rs:1:7
53
|
64
LL | #[w = { extern crate alloc; }]

tests/ui/consts/issue-90878-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![l=|x|[b;x ]] //~ ERROR unexpected expression: `|x| [b; x]`
1+
#![l=|x|[b;x ]] //~ ERROR attribute value must be a literal
22
//~^ ERROR cannot find attribute `l` in this scope
33

44
// notice the space at the start,

tests/ui/consts/issue-90878-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: unexpected expression: `|x| [b; x]`
1+
error: attribute value must be a literal
22
--> $DIR/issue-90878-2.rs:1:7
33
|
44
LL | #![l=|x|[b;x ]]

tests/ui/malformed/malformed-interpolated.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ macro_rules! check {
1010
check!("0"); // OK
1111
check!(0); // OK
1212
check!(0u8); //~ ERROR suffixed literals are not allowed in attributes
13-
check!(-0); //~ ERROR unexpected expression: `-0`
14-
check!(0 + 0); //~ ERROR unexpected expression: `0 + 0`
13+
check!(-0); //~ ERROR attribute value must be a literal
14+
check!(0 + 0); //~ ERROR attribute value must be a literal
1515

1616
fn main() {}

tests/ui/malformed/malformed-interpolated.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ LL | check!(0u8);
66
|
77
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
88

9-
error: unexpected expression: `-0`
9+
error: attribute value must be a literal
1010
--> $DIR/malformed-interpolated.rs:13:8
1111
|
1212
LL | check!(-0);
1313
| ^^
1414

15-
error: unexpected expression: `0 + 0`
15+
error: attribute value must be a literal
1616
--> $DIR/malformed-interpolated.rs:14:8
1717
|
1818
LL | check!(0 + 0);

tests/ui/parser/bad-lit-suffixes.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ fn main() {
2828
}
2929

3030
#[rustc_dummy = "string"suffix]
31-
//~^ ERROR unexpected expression: `"string"suffix`
31+
//~^ ERROR suffixes on string literals are invalid
3232
fn f() {}
3333

3434
#[must_use = "string"suffix]
35-
//~^ ERROR unexpected expression: `"string"suffix`
35+
//~^ ERROR suffixes on string literals are invalid
36+
//~| ERROR malformed `must_use` attribute input
3637
fn g() {}
3738

3839
#[link(name = "string"suffix)]

tests/ui/parser/bad-lit-suffixes.stderr

+20-7
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,39 @@ error: suffixes on string literals are invalid
1010
LL | "C"suffix
1111
| ^^^^^^^^^ invalid suffix `suffix`
1212

13-
error: unexpected expression: `"string"suffix`
13+
error: suffixes on string literals are invalid
1414
--> $DIR/bad-lit-suffixes.rs:30:17
1515
|
1616
LL | #[rustc_dummy = "string"suffix]
17-
| ^^^^^^^^^^^^^^
17+
| ^^^^^^^^^^^^^^ invalid suffix `suffix`
1818

19-
error: unexpected expression: `"string"suffix`
19+
error: suffixes on string literals are invalid
2020
--> $DIR/bad-lit-suffixes.rs:34:14
2121
|
2222
LL | #[must_use = "string"suffix]
23-
| ^^^^^^^^^^^^^^
23+
| ^^^^^^^^^^^^^^ invalid suffix `suffix`
24+
25+
error: malformed `must_use` attribute input
26+
--> $DIR/bad-lit-suffixes.rs:34:1
27+
|
28+
LL | #[must_use = "string"suffix]
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30+
|
31+
help: the following are the possible correct uses
32+
|
33+
LL | #[must_use = "reason"]
34+
|
35+
LL | #[must_use]
36+
|
2437

2538
error: suffixes on string literals are invalid
26-
--> $DIR/bad-lit-suffixes.rs:38:15
39+
--> $DIR/bad-lit-suffixes.rs:39:15
2740
|
2841
LL | #[link(name = "string"suffix)]
2942
| ^^^^^^^^^^^^^^ invalid suffix `suffix`
3043

3144
error: invalid suffix `suffix` for number literal
32-
--> $DIR/bad-lit-suffixes.rs:42:41
45+
--> $DIR/bad-lit-suffixes.rs:43:41
3346
|
3447
LL | #[rustc_layout_scalar_valid_range_start(0suffix)]
3548
| ^^^^^^^ invalid suffix `suffix`
@@ -136,5 +149,5 @@ LL | 1.0e10suffix;
136149
|
137150
= help: valid suffixes are `f32` and `f64`
138151

139-
error: aborting due to 20 previous errors
152+
error: aborting due to 21 previous errors
140153

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#![feature(rustc_attrs)]
22

3-
#![rustc_dummy=5z] //~ ERROR unexpected expression: `5z`
3+
#![rustc_dummy=5z] //~ ERROR invalid suffix `z` for number literal
44
fn main() {}
+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
error: unexpected expression: `5z`
1+
error: invalid suffix `z` for number literal
22
--> $DIR/issue-104620.rs:3:16
33
|
44
LL | #![rustc_dummy=5z]
5-
| ^^
5+
| ^^ invalid suffix `z`
6+
|
7+
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
68

79
error: aborting due to 1 previous error
810

0 commit comments

Comments
 (0)