Skip to content

Commit 3b37f15

Browse files
committed
Restrict value in key-value attributes to literals
1 parent 8e0141b commit 3b37f15

11 files changed

+90
-19
lines changed

Diff for: src/libsyntax/feature_gate.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ use edition::{ALL_EDITIONS, Edition};
2424
use syntax_pos::{Span, DUMMY_SP};
2525
use errors::{DiagnosticBuilder, Handler};
2626
use visit::{self, FnKind, Visitor};
27-
use parse::ParseSess;
27+
use parse::{token, ParseSess};
2828
use symbol::{keywords, Symbol};
29+
use tokenstream::TokenTree;
2930

3031
use std::{env};
3132

@@ -1557,7 +1558,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
15571558
}
15581559
Err(mut err) => err.emit(),
15591560
}
1560-
None => {}
1561+
None => if let Some(TokenTree::Token(_, token::Eq)) = attr.tokens.trees().next() {
1562+
// All key-value attributes are restricted to what fits into a meta-item.
1563+
if let Err(mut err) = attr.parse_meta(self.context.parse_sess) {
1564+
err.emit();
1565+
}
1566+
}
15611567
}
15621568
}
15631569

Diff for: src/libsyntax/parse/attr.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,21 @@ impl<'a> Parser<'a> {
156156
self.parse_token_tree().into()
157157
} else if self.eat(&token::Eq) {
158158
let eq = TokenTree::Token(self.prev_span, token::Eq);
159-
let tree = match self.token {
160-
token::CloseDelim(_) | token::Eof => self.unexpected()?,
161-
_ => self.parse_token_tree(),
159+
let mut is_interpolated_expr = false;
160+
if let token::Interpolated(nt) = &self.token {
161+
if let token::NtExpr(..) = nt.0 {
162+
is_interpolated_expr = true;
163+
}
164+
}
165+
let tokens = if is_interpolated_expr {
166+
// We need to accept arbitrary interpolated expressions to continue
167+
// supporting things like `doc = $expr` that work on stable.
168+
// Non-literal interpolated expressions are rejected after expansion.
169+
self.parse_token_tree().into()
170+
} else {
171+
self.parse_unsuffixed_lit()?.tokens()
162172
};
163-
TokenStream::new(vec![eq.into(), tree.into()])
173+
TokenStream::new(vec![eq.into(), tokens])
164174
} else {
165175
TokenStream::empty()
166176
};

Diff for: src/test/ui/attr-eq-token-tree.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// compile-pass
2-
31
#![feature(custom_attribute)]
42

5-
#[my_attr = !] // OK under feature gate
3+
#[my_attr = !] //~ ERROR unexpected token: `!`
64
fn main() {}

Diff for: src/test/ui/attr-eq-token-tree.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: unexpected token: `!`
2+
--> $DIR/attr-eq-token-tree.rs:3:11
3+
|
4+
LL | #[my_attr = !] //~ ERROR unexpected token: `!`
5+
| ^
6+
7+
error: aborting due to previous error
8+

Diff for: src/test/ui/macros/macro-attribute.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
#[doc = $not_there] //~ ERROR expected `]`, found `not_there`
1+
#[doc = $not_there] //~ ERROR unexpected token: `$`
22
fn main() { }

Diff for: src/test/ui/macros/macro-attribute.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: expected `]`, found `not_there`
2-
--> $DIR/macro-attribute.rs:1:10
1+
error: unexpected token: `$`
2+
--> $DIR/macro-attribute.rs:1:7
33
|
4-
LL | #[doc = $not_there] //~ ERROR expected `]`, found `not_there`
5-
| ^^^^^^^^^ expected `]`
4+
LL | #[doc = $not_there] //~ ERROR unexpected token: `$`
5+
| ^
66

77
error: aborting due to previous error
88

Diff for: src/test/ui/malformed/malformed-interpolated.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![feature(custom_attribute)]
2+
3+
macro_rules! check {
4+
($expr: expr) => (
5+
#[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes
6+
//~| ERROR unexpected token: `-0`
7+
//~| ERROR unexpected token: `0 + 0`
8+
use main as _;
9+
);
10+
}
11+
12+
check!("0"); // OK
13+
check!(0); // OK
14+
check!(0u8); // ERROR, see above
15+
check!(-0); // ERROR, see above
16+
check!(0 + 0); // ERROR, see above
17+
18+
fn main() {}

Diff for: src/test/ui/malformed/malformed-interpolated.stderr

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error: suffixed literals are not allowed in attributes
2+
--> $DIR/malformed-interpolated.rs:5:21
3+
|
4+
LL | #[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes
5+
| ^^^^^
6+
...
7+
LL | check!(0u8); // ERROR, see above
8+
| ------------ in this macro invocation
9+
|
10+
= help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.).
11+
12+
error: unexpected token: `-0`
13+
--> $DIR/malformed-interpolated.rs:5:19
14+
|
15+
LL | #[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes
16+
| ^
17+
...
18+
LL | check!(-0); // ERROR, see above
19+
| ----------- in this macro invocation
20+
21+
error: unexpected token: `0 + 0`
22+
--> $DIR/malformed-interpolated.rs:5:19
23+
|
24+
LL | #[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes
25+
| ^
26+
...
27+
LL | check!(0 + 0); // ERROR, see above
28+
| -------------- in this macro invocation
29+
30+
error: aborting due to 3 previous errors
31+

Diff for: src/test/ui/parser/attr-bad-meta-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: unexpected token: `]`
2-
--> $DIR/attr-bad-meta-2.rs:3:9
2+
--> $DIR/attr-bad-meta-2.rs:3:8
33
|
44
LL | #[path =] //~ ERROR unexpected token: `]`
5-
| ^ unexpected token after this
5+
| ^
66

77
error: aborting due to previous error
88

Diff for: src/test/ui/proc-macro/proc-macro-gates.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ mod _test2_inner {
1919
//~| ERROR: non-builtin inner attributes are unstable
2020
}
2121

22-
#[a = y] //~ ERROR: must only be followed by a delimiter token
22+
#[a = "y"] //~ ERROR: must only be followed by a delimiter token
2323
fn _test3() {}
2424

2525
fn attrs() {

Diff for: src/test/ui/proc-macro/proc-macro-gates.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ LL | #![a] //~ ERROR: custom attributes cannot be applied to modules
3333
error: custom attribute invocations must be of the form #[foo] or #[foo(..)], the macro name must only be followed by a delimiter token
3434
--> $DIR/proc-macro-gates.rs:22:1
3535
|
36-
LL | #[a = y] //~ ERROR: must only be followed by a delimiter token
37-
| ^^^^^^^^
36+
LL | #[a = "y"] //~ ERROR: must only be followed by a delimiter token
37+
| ^^^^^^^^^^
3838

3939
error[E0658]: custom attributes cannot be applied to statements (see issue #54727)
4040
--> $DIR/proc-macro-gates.rs:31:5

0 commit comments

Comments
 (0)