Skip to content

Commit

Permalink
Restrict value in key-value attributes to literals
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Feb 25, 2019
1 parent b57fe74 commit 8e1b5d8
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 18 deletions.
18 changes: 14 additions & 4 deletions src/libsyntax/parse/attr.rs
Expand Up @@ -158,11 +158,21 @@ impl<'a> Parser<'a> {
self.parse_token_tree().into()
} else if self.eat(&token::Eq) {
let eq = TokenTree::Token(self.prev_span, token::Eq);
let tree = match self.token {
token::CloseDelim(_) | token::Eof => self.unexpected()?,
_ => self.parse_token_tree(),
let mut is_interpolated_expr = false;
if let token::Interpolated(nt) = &self.token {
if let token::NtExpr(..) = **nt {
is_interpolated_expr = true;
}
}
let tokens = if is_interpolated_expr {
// We need to accept arbitrary interpolated expressions to continue
// supporting things like `doc = $expr` that work on stable.
// Non-literal interpolated expressions are rejected after expansion.
self.parse_token_tree().into()
} else {
self.parse_unsuffixed_lit()?.tokens()
};
TokenStream::new(vec![eq.into(), tree.into()])
TokenStream::from_streams(vec![eq.into(), tokens])
} else {
TokenStream::empty()
};
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/tokenstream.rs
Expand Up @@ -254,7 +254,7 @@ impl TokenStream {
}
}

fn from_streams(mut streams: Vec<TokenStream>) -> TokenStream {
pub(crate) fn from_streams(mut streams: Vec<TokenStream>) -> TokenStream {
match streams.len() {
0 => TokenStream::empty(),
1 => streams.pop().unwrap(),
Expand Down
4 changes: 1 addition & 3 deletions src/test/ui/attr-eq-token-tree.rs
@@ -1,6 +1,4 @@
// compile-pass

#![feature(custom_attribute, unrestricted_attribute_tokens)]

#[my_attr = !] // OK under feature gate
#[my_attr = !] //~ ERROR unexpected token: `!`
fn main() {}
8 changes: 8 additions & 0 deletions src/test/ui/attr-eq-token-tree.stderr
@@ -0,0 +1,8 @@
error: unexpected token: `!`
--> $DIR/attr-eq-token-tree.rs:3:11
|
LL | #[my_attr = !] //~ ERROR unexpected token: `!`
| ^

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/macros/macro-attribute.rs
@@ -1,4 +1,4 @@
#![feature(unrestricted_attribute_tokens)]

#[doc = $not_there] //~ ERROR expected `]`, found `not_there`
#[doc = $not_there] //~ ERROR unexpected token: `$`
fn main() { }
8 changes: 4 additions & 4 deletions src/test/ui/macros/macro-attribute.stderr
@@ -1,8 +1,8 @@
error: expected `]`, found `not_there`
--> $DIR/macro-attribute.rs:3:10
error: unexpected token: `$`
--> $DIR/macro-attribute.rs:3:7
|
LL | #[doc = $not_there] //~ ERROR expected `]`, found `not_there`
| ^^^^^^^^^ expected `]`
LL | #[doc = $not_there] //~ ERROR unexpected token: `$`
| ^

error: aborting due to previous error

18 changes: 18 additions & 0 deletions src/test/ui/malformed/malformed-interpolated.rs
@@ -0,0 +1,18 @@
#![feature(custom_attribute)]

macro_rules! check {
($expr: expr) => (
#[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes
//~| ERROR unexpected token: `-0`
//~| ERROR unexpected token: `0 + 0`
use main as _;
);
}

check!("0"); // OK
check!(0); // OK
check!(0u8); // ERROR, see above
check!(-0); // ERROR, see above
check!(0 + 0); // ERROR, see above

fn main() {}
35 changes: 35 additions & 0 deletions src/test/ui/malformed/malformed-interpolated.stderr
@@ -0,0 +1,35 @@
error: suffixed literals are not allowed in attributes
--> $DIR/malformed-interpolated.rs:5:21
|
LL | #[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes
| ^^^^^
...
LL | check!(0u8); // ERROR, see above
| ------------ in this macro invocation
|
= help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.).

error: unexpected token: `-0`
--> $DIR/malformed-interpolated.rs:5:19
|
LL | #[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes
| ^
...
LL | check!(-0); // ERROR, see above
| ----------- in this macro invocation
|
= help: try enabling `#![feature(unrestricted_attribute_tokens)]`

error: unexpected token: `0 + 0`
--> $DIR/malformed-interpolated.rs:5:19
|
LL | #[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes
| ^
...
LL | check!(0 + 0); // ERROR, see above
| -------------- in this macro invocation
|
= help: try enabling `#![feature(unrestricted_attribute_tokens)]`

error: aborting due to 3 previous errors

4 changes: 2 additions & 2 deletions src/test/ui/parser/attr-bad-meta-2.stderr
@@ -1,8 +1,8 @@
error: unexpected token: `]`
--> $DIR/attr-bad-meta-2.rs:1:9
--> $DIR/attr-bad-meta-2.rs:1:8
|
LL | #[path =] //~ ERROR unexpected token: `]`
| ^ unexpected token after this
| ^

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/proc-macro/proc-macro-gates.rs
Expand Up @@ -19,7 +19,7 @@ mod _test2_inner {
//~| ERROR: non-builtin inner attributes are unstable
}

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

fn attrs() {
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/proc-macro/proc-macro-gates.stderr
Expand Up @@ -33,8 +33,8 @@ LL | #![a] //~ ERROR: custom attributes cannot be applied to modules
error: custom attribute invocations must be of the form #[foo] or #[foo(..)], the macro name must only be followed by a delimiter token
--> $DIR/proc-macro-gates.rs:22:1
|
LL | #[a = y] //~ ERROR: must only be followed by a delimiter token
| ^^^^^^^^
LL | #[a = "y"] //~ ERROR: must only be followed by a delimiter token
| ^^^^^^^^^^

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

0 comments on commit 8e1b5d8

Please sign in to comment.