@@ -12,9 +12,9 @@ use attr;
1212use ast;
1313use codemap:: respan;
1414use parse:: { SeqSep , PResult } ;
15- use parse:: token:: { self , Nonterminal } ;
15+ use parse:: token:: { self , Nonterminal , DelimToken } ;
1616use parse:: parser:: { Parser , TokenType , PathStyle } ;
17- use tokenstream:: TokenStream ;
17+ use tokenstream:: { TokenStream , TokenTree } ;
1818
1919#[ derive( Debug ) ]
2020enum InnerAttributeParsePolicy < ' a > {
@@ -116,7 +116,7 @@ impl<'a> Parser<'a> {
116116 } ;
117117
118118 self . expect ( & token:: OpenDelim ( token:: Bracket ) ) ?;
119- let ( path, tokens) = self . parse_path_and_tokens ( ) ?;
119+ let ( path, tokens) = self . parse_meta_item_unrestricted ( ) ?;
120120 self . expect ( & token:: CloseDelim ( token:: Bracket ) ) ?;
121121 let hi = self . prev_span ;
122122
@@ -138,7 +138,16 @@ impl<'a> Parser<'a> {
138138 } )
139139 }
140140
141- crate fn parse_path_and_tokens ( & mut self ) -> PResult < ' a , ( ast:: Path , TokenStream ) > {
141+ /// Parse an inner part of attribute - path and following tokens.
142+ /// The tokens must be either a delimited token stream, or empty token stream,
143+ /// or the "legacy" key-value form.
144+ /// PATH `(` TOKEN_STREAM `)`
145+ /// PATH `[` TOKEN_STREAM `]`
146+ /// PATH `{` TOKEN_STREAM `}`
147+ /// PATH
148+ /// PATH `=` TOKEN_TREE
149+ /// The delimiters or `=` are still put into the resulting token stream.
150+ crate fn parse_meta_item_unrestricted ( & mut self ) -> PResult < ' a , ( ast:: Path , TokenStream ) > {
142151 let meta = match self . token {
143152 token:: Interpolated ( ref nt) => match nt. 0 {
144153 Nonterminal :: NtMeta ( ref meta) => Some ( meta. clone ( ) ) ,
@@ -150,7 +159,22 @@ impl<'a> Parser<'a> {
150159 self . bump ( ) ;
151160 ( meta. ident , meta. node . tokens ( meta. span ) )
152161 } else {
153- ( self . parse_path ( PathStyle :: Mod ) ?, self . parse_tokens ( ) )
162+ let path = self . parse_path ( PathStyle :: Mod ) ?;
163+ let tokens = if self . check ( & token:: OpenDelim ( DelimToken :: Paren ) ) ||
164+ self . check ( & token:: OpenDelim ( DelimToken :: Bracket ) ) ||
165+ self . check ( & token:: OpenDelim ( DelimToken :: Brace ) ) {
166+ self . parse_token_tree ( ) . into ( )
167+ } else if self . eat ( & token:: Eq ) {
168+ let eq = TokenTree :: Token ( self . prev_span , token:: Eq ) ;
169+ let tree = match self . token {
170+ token:: CloseDelim ( _) | token:: Eof => self . unexpected ( ) ?,
171+ _ => self . parse_token_tree ( ) ,
172+ } ;
173+ TokenStream :: concat ( vec ! [ eq. into( ) , tree. into( ) ] )
174+ } else {
175+ TokenStream :: empty ( )
176+ } ;
177+ ( path, tokens)
154178 } )
155179 }
156180
0 commit comments