@@ -168,7 +168,7 @@ pub struct Parser<'a> {
168
168
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure
169
169
// it doesn't unintentionally get bigger.
170
170
#[ cfg( all( target_arch = "x86_64" , target_pointer_width = "64" ) ) ]
171
- rustc_data_structures:: static_assert_size!( Parser <' _>, 336 ) ;
171
+ rustc_data_structures:: static_assert_size!( Parser <' _>, 312 ) ;
172
172
173
173
/// Stores span information about a closure.
174
174
#[ derive( Clone ) ]
@@ -223,16 +223,21 @@ impl<'a> Drop for Parser<'a> {
223
223
224
224
#[ derive( Clone ) ]
225
225
struct TokenCursor {
226
- // The current (innermost) frame. `frame` and `stack` could be combined,
227
- // but it's faster to keep them separate and access `frame` directly
228
- // rather than via something like `stack.last().unwrap()` or
229
- // `stack[stack.len() - 1]`.
230
- frame : TokenCursorFrame ,
231
- // Additional frames that enclose `frame`.
232
- stack : Vec < TokenCursorFrame > ,
226
+ // Cursor for the current (innermost) token stream. The delimiters for this
227
+ // token stream are found in `self.stack.last()`; when that is `None` then
228
+ // we are in the outermost token stream which never has delimiters.
229
+ tree_cursor : tokenstream:: Cursor ,
230
+
231
+ // Token streams surrounding the current one. The delimiters for stack[n]'s
232
+ // tokens are in `stack[n-1]`. `stack[0]` (when present) has no delimiters
233
+ // because it's the outermost token stream which never has delimiters.
234
+ stack : Vec < ( tokenstream:: Cursor , Delimiter , DelimSpan ) > ,
235
+
233
236
desugar_doc_comments : bool ,
237
+
234
238
// Counts the number of calls to `{,inlined_}next`.
235
239
num_next_calls : usize ,
240
+
236
241
// During parsing, we may sometimes need to 'unglue' a
237
242
// glued token into two component tokens
238
243
// (e.g. '>>' into '>' and '>), so that the parser
@@ -257,19 +262,6 @@ struct TokenCursor {
257
262
break_last_token : bool ,
258
263
}
259
264
260
- #[ derive( Clone ) ]
261
- struct TokenCursorFrame {
262
- // This is `None` only for the outermost frame.
263
- delim_sp : Option < ( Delimiter , DelimSpan ) > ,
264
- tree_cursor : tokenstream:: Cursor ,
265
- }
266
-
267
- impl TokenCursorFrame {
268
- fn new ( delim_sp : Option < ( Delimiter , DelimSpan ) > , tts : TokenStream ) -> Self {
269
- TokenCursorFrame { delim_sp, tree_cursor : tts. into_trees ( ) }
270
- }
271
- }
272
-
273
265
impl TokenCursor {
274
266
fn next ( & mut self , desugar_doc_comments : bool ) -> ( Token , Spacing ) {
275
267
self . inlined_next ( desugar_doc_comments)
@@ -282,12 +274,12 @@ impl TokenCursor {
282
274
// FIXME: we currently don't return `Delimiter` open/close delims. To fix #67062 we will
283
275
// need to, whereupon the `delim != Delimiter::Invisible` conditions below can be
284
276
// removed.
285
- if let Some ( tree) = self . frame . tree_cursor . next_ref ( ) {
277
+ if let Some ( tree) = self . tree_cursor . next_ref ( ) {
286
278
match tree {
287
279
& TokenTree :: Token ( ref token, spacing) => match ( desugar_doc_comments, token) {
288
280
( true , & Token { kind : token:: DocComment ( _, attr_style, data) , span } ) => {
289
281
let desugared = self . desugar ( attr_style, data, span) ;
290
- self . frame . tree_cursor . replace_prev_and_rewind ( desugared) ;
282
+ self . tree_cursor . replace_prev_and_rewind ( desugared) ;
291
283
// Continue to get the first token of the desugared doc comment.
292
284
}
293
285
_ => {
@@ -299,25 +291,23 @@ impl TokenCursor {
299
291
}
300
292
} ,
301
293
& TokenTree :: Delimited ( sp, delim, ref tts) => {
302
- // Set `open_delim` to true here because we deal with it immediately.
303
- let frame = TokenCursorFrame :: new ( Some ( ( delim, sp) ) , tts. clone ( ) ) ;
304
- self . stack . push ( mem:: replace ( & mut self . frame , frame) ) ;
294
+ let trees = tts. clone ( ) . into_trees ( ) ;
295
+ self . stack . push ( ( mem:: replace ( & mut self . tree_cursor , trees) , delim, sp) ) ;
305
296
if delim != Delimiter :: Invisible {
306
297
return ( Token :: new ( token:: OpenDelim ( delim) , sp. open ) , Spacing :: Alone ) ;
307
298
}
308
299
// No open delimiter to return; continue on to the next iteration.
309
300
}
310
301
} ;
311
- } else if let Some ( frame) = self . stack . pop ( ) {
312
- // We have exhausted this frame. Move back to its parent frame.
313
- let ( delim, span) = self . frame . delim_sp . unwrap ( ) ;
314
- self . frame = frame;
302
+ } else if let Some ( ( tree_cursor, delim, span) ) = self . stack . pop ( ) {
303
+ // We have exhausted this token stream. Move back to its parent token stream.
304
+ self . tree_cursor = tree_cursor;
315
305
if delim != Delimiter :: Invisible {
316
306
return ( Token :: new ( token:: CloseDelim ( delim) , span. close ) , Spacing :: Alone ) ;
317
307
}
318
308
// No close delimiter to return; continue on to the next iteration.
319
309
} else {
320
- // We have exhausted the outermost frame .
310
+ // We have exhausted the outermost token stream .
321
311
return ( Token :: new ( token:: Eof , DUMMY_SP ) , Spacing :: Alone ) ;
322
312
}
323
313
}
@@ -475,7 +465,7 @@ impl<'a> Parser<'a> {
475
465
restrictions : Restrictions :: empty ( ) ,
476
466
expected_tokens : Vec :: new ( ) ,
477
467
token_cursor : TokenCursor {
478
- frame : TokenCursorFrame :: new ( None , tokens) ,
468
+ tree_cursor : tokens. into_trees ( ) ,
479
469
stack : Vec :: new ( ) ,
480
470
num_next_calls : 0 ,
481
471
desugar_doc_comments,
@@ -1142,14 +1132,16 @@ impl<'a> Parser<'a> {
1142
1132
return looker ( & self . token ) ;
1143
1133
}
1144
1134
1145
- let frame = & self . token_cursor . frame ;
1146
- if let Some ( ( delim, span) ) = frame. delim_sp && delim != Delimiter :: Invisible {
1135
+ let tree_cursor = & self . token_cursor . tree_cursor ;
1136
+ if let Some ( & ( _, delim, span) ) = self . token_cursor . stack . last ( )
1137
+ && delim != Delimiter :: Invisible
1138
+ {
1147
1139
let all_normal = ( 0 ..dist) . all ( |i| {
1148
- let token = frame . tree_cursor . look_ahead ( i) ;
1140
+ let token = tree_cursor. look_ahead ( i) ;
1149
1141
!matches ! ( token, Some ( TokenTree :: Delimited ( _, Delimiter :: Invisible , _) ) )
1150
1142
} ) ;
1151
1143
if all_normal {
1152
- return match frame . tree_cursor . look_ahead ( dist - 1 ) {
1144
+ return match tree_cursor. look_ahead ( dist - 1 ) {
1153
1145
Some ( tree) => match tree {
1154
1146
TokenTree :: Token ( token, _) => looker ( token) ,
1155
1147
TokenTree :: Delimited ( dspan, delim, _) => {
@@ -1310,10 +1302,10 @@ impl<'a> Parser<'a> {
1310
1302
pub ( crate ) fn parse_token_tree ( & mut self ) -> TokenTree {
1311
1303
match self . token . kind {
1312
1304
token:: OpenDelim ( ..) => {
1313
- // Grab the tokens from this frame .
1314
- let frame = & self . token_cursor . frame ;
1315
- let stream = frame . tree_cursor . stream . clone ( ) ;
1316
- let ( delim, span) = frame . delim_sp . unwrap ( ) ;
1305
+ // Grab the tokens within the delimiters .
1306
+ let tree_cursor = & self . token_cursor . tree_cursor ;
1307
+ let stream = tree_cursor. stream . clone ( ) ;
1308
+ let ( _ , delim, span) = * self . token_cursor . stack . last ( ) . unwrap ( ) ;
1317
1309
1318
1310
// Advance the token cursor through the entire delimited
1319
1311
// sequence. After getting the `OpenDelim` we are *within* the
0 commit comments