Skip to content

Commit

Permalink
Merge pull request dtolnay#853 from dtolnay/attr
Browse files Browse the repository at this point in the history
Move none-delimited attr behavior only to exprs
  • Loading branch information
dtolnay authored Jun 20, 2020
2 parents fc38b11 + 4147689 commit 1003786
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ impl Attribute {
#[cfg(feature = "parsing")]
pub fn parse_outer(input: ParseStream) -> Result<Vec<Self>> {
let mut attrs = Vec::new();
while input.peek(Token![#]) && !input.peek(token::Group) {
while input.peek(Token![#]) {
attrs.push(input.call(parsing::single_parse_outer)?);
}
Ok(attrs)
Expand All @@ -276,7 +276,7 @@ impl Attribute {
#[cfg(feature = "parsing")]
pub fn parse_inner(input: ParseStream) -> Result<Vec<Self>> {
let mut attrs = Vec::new();
while input.peek(Token![#]) && input.peek2(Token![!]) && !input.peek(token::Group) {
while input.peek(Token![#]) && input.peek2(Token![!]) {
attrs.push(input.call(parsing::single_parse_inner)?);
}
Ok(attrs)
Expand Down
26 changes: 25 additions & 1 deletion src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1543,14 +1543,38 @@ pub(crate) mod parsing {
parse_expr(input, lhs, allow_struct, Precedence::Any)
}

#[cfg(feature = "full")]
fn expr_attrs(input: ParseStream) -> Result<Vec<Attribute>> {
let mut attrs = Vec::new();
loop {
if input.peek(token::Group) {
let ahead = input.fork();
let group = crate::group::parse_group(&ahead)?;
if !group.content.peek(Token![#]) || group.content.peek2(Token![!]) {
break;
}
let attr = group.content.call(attr::parsing::single_parse_outer)?;
if !group.content.is_empty() {
break;
}
attrs.push(attr);
} else if input.peek(Token![#]) {
attrs.push(input.call(attr::parsing::single_parse_outer)?);
} else {
break;
}
}
Ok(attrs)
}

// <UnOp> <trailer>
// & <trailer>
// &mut <trailer>
// box <trailer>
#[cfg(feature = "full")]
fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
let begin = input.fork();
let attrs = input.call(Attribute::parse_outer)?;
let attrs = input.call(expr_attrs)?;
if input.peek(Token![&]) {
let and_token: Token![&] = input.parse()?;
let raw: Option<raw> =
Expand Down
45 changes: 45 additions & 0 deletions tests/test_item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#[macro_use]
mod macros;

use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
use quote::quote;
use std::iter::FromIterator;
use syn::Item;

#[test]
fn test_macro_variable_attr() {
// mimics the token stream corresponding to `$attr fn f() {}`
let tokens = TokenStream::from_iter(vec![
TokenTree::Group(Group::new(Delimiter::None, quote! { #[test] })),
TokenTree::Ident(Ident::new("fn", Span::call_site())),
TokenTree::Ident(Ident::new("f", Span::call_site())),
TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
]);

snapshot!(tokens as Item, @r###"
Item::Fn {
attrs: [
Attribute {
style: Outer,
path: Path {
segments: [
PathSegment {
ident: "test",
arguments: None,
},
],
},
tokens: TokenStream(``),
},
],
vis: Inherited,
sig: Signature {
ident: "f",
generics: Generics,
output: Default,
},
block: Block,
}
"###);
}

0 comments on commit 1003786

Please sign in to comment.