@@ -12,9 +12,9 @@ use attr;
12
12
use ast;
13
13
use codemap:: respan;
14
14
use parse:: { SeqSep , PResult } ;
15
- use parse:: token:: { self , Nonterminal } ;
15
+ use parse:: token:: { self , Nonterminal , DelimToken } ;
16
16
use parse:: parser:: { Parser , TokenType , PathStyle } ;
17
- use tokenstream:: TokenStream ;
17
+ use tokenstream:: { TokenStream , TokenTree } ;
18
18
19
19
#[ derive( Debug ) ]
20
20
enum InnerAttributeParsePolicy < ' a > {
@@ -116,7 +116,7 @@ impl<'a> Parser<'a> {
116
116
} ;
117
117
118
118
self . expect ( & token:: OpenDelim ( token:: Bracket ) ) ?;
119
- let ( path, tokens) = self . parse_path_and_tokens ( ) ?;
119
+ let ( path, tokens) = self . parse_meta_item_unrestricted ( ) ?;
120
120
self . expect ( & token:: CloseDelim ( token:: Bracket ) ) ?;
121
121
let hi = self . prev_span ;
122
122
@@ -138,7 +138,16 @@ impl<'a> Parser<'a> {
138
138
} )
139
139
}
140
140
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 ) > {
142
151
let meta = match self . token {
143
152
token:: Interpolated ( ref nt) => match nt. 0 {
144
153
Nonterminal :: NtMeta ( ref meta) => Some ( meta. clone ( ) ) ,
@@ -150,7 +159,22 @@ impl<'a> Parser<'a> {
150
159
self . bump ( ) ;
151
160
( meta. ident , meta. node . tokens ( meta. span ) )
152
161
} 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)
154
178
} )
155
179
}
156
180
0 commit comments