@@ -24,9 +24,7 @@ use rustc_ast::ptr::P;
24
24
use rustc_ast:: token:: {
25
25
self , Delimiter , IdentIsRaw , InvisibleOrigin , MetaVarKind , Nonterminal , Token , TokenKind ,
26
26
} ;
27
- use rustc_ast:: tokenstream:: {
28
- AttrsTarget , DelimSpacing , DelimSpan , Spacing , TokenStream , TokenTree , TokenTreeCursor ,
29
- } ;
27
+ use rustc_ast:: tokenstream:: { AttrsTarget , Spacing , TokenStream , TokenTree } ;
30
28
use rustc_ast:: util:: case:: Case ;
31
29
use rustc_ast:: {
32
30
self as ast, AnonConst , AttrArgs , AttrArgsEq , AttrId , ByRef , Const , CoroutineKind ,
@@ -273,6 +271,29 @@ struct CaptureState {
273
271
seen_attrs : IntervalSet < AttrId > ,
274
272
}
275
273
274
+ #[ derive( Clone , Debug ) ]
275
+ struct TokenTreeCursor {
276
+ stream : TokenStream ,
277
+ index : usize ,
278
+ }
279
+
280
+ impl TokenTreeCursor {
281
+ #[ inline]
282
+ fn new ( stream : TokenStream ) -> Self {
283
+ TokenTreeCursor { stream, index : 0 }
284
+ }
285
+
286
+ #[ inline]
287
+ fn get ( & self ) -> Option < & TokenTree > {
288
+ self . stream . get ( self . index )
289
+ }
290
+
291
+ #[ inline]
292
+ fn bump ( & mut self ) {
293
+ self . index += 1 ;
294
+ }
295
+ }
296
+
276
297
/// Iterator over a `TokenStream` that produces `Token`s. It's a bit odd that
277
298
/// we (a) lex tokens into a nice tree structure (`TokenStream`), and then (b)
278
299
/// use this type to emit them as a linear sequence. But a linear sequence is
@@ -282,12 +303,12 @@ struct TokenCursor {
282
303
// Cursor for the current (innermost) token stream. The delimiters for this
283
304
// token stream are found in `self.stack.last()`; when that is `None` then
284
305
// we are in the outermost token stream which never has delimiters.
285
- tree_cursor : TokenTreeCursor ,
306
+ curr : TokenTreeCursor ,
286
307
287
- // Token streams surrounding the current one. The delimiters for stack[n]'s
288
- // tokens are in `stack[n-1]`. `stack[0]` (when present) has no delimiters
289
- // because it's the outermost token stream which never has delimiters .
290
- stack : Vec < ( TokenTreeCursor , DelimSpan , DelimSpacing , Delimiter ) > ,
308
+ // Token streams surrounding the current one. The current position in each
309
+ // of these cursors is always a `TokenTree::Delimited`, never a
310
+ // `TokenTree::Token` .
311
+ stack : Vec < TokenTreeCursor > ,
291
312
}
292
313
293
314
impl TokenCursor {
@@ -302,32 +323,33 @@ impl TokenCursor {
302
323
// FIXME: we currently don't return `Delimiter::Invisible` open/close delims. To fix
303
324
// #67062 we will need to, whereupon the `delim != Delimiter::Invisible` conditions
304
325
// below can be removed.
305
- if let Some ( tree) = self . tree_cursor . next_ref ( ) {
326
+ if let Some ( tree) = self . curr . get ( ) {
306
327
match tree {
307
328
& TokenTree :: Token ( ref token, spacing) => {
308
329
debug_assert ! ( !matches!(
309
330
token. kind,
310
331
token:: OpenDelim ( _) | token:: CloseDelim ( _)
311
332
) ) ;
312
- return ( token. clone ( ) , spacing) ;
333
+ let res = ( token. clone ( ) , spacing) ;
334
+ self . curr . bump ( ) ;
335
+ return res;
313
336
}
314
337
& TokenTree :: Delimited ( sp, spacing, delim, ref tts) => {
315
- let trees = tts. clone ( ) . into_trees ( ) ;
316
- self . stack . push ( (
317
- mem:: replace ( & mut self . tree_cursor , trees) ,
318
- sp,
319
- spacing,
320
- delim,
321
- ) ) ;
338
+ let trees = TokenTreeCursor :: new ( tts. clone ( ) ) ;
339
+ self . stack . push ( mem:: replace ( & mut self . curr , trees) ) ;
322
340
if !delim. skip ( ) {
323
341
return ( Token :: new ( token:: OpenDelim ( delim) , sp. open ) , spacing. open ) ;
324
342
}
325
343
// No open delimiter to return; continue on to the next iteration.
326
344
}
327
345
} ;
328
- } else if let Some ( ( tree_cursor , span , spacing , delim ) ) = self . stack . pop ( ) {
346
+ } else if let Some ( parent ) = self . stack . pop ( ) {
329
347
// We have exhausted this token stream. Move back to its parent token stream.
330
- self . tree_cursor = tree_cursor;
348
+ let Some ( & TokenTree :: Delimited ( span, spacing, delim, _) ) = parent. get ( ) else {
349
+ panic ! ( "parent should be Delimited" )
350
+ } ;
351
+ self . curr = parent;
352
+ self . curr . bump ( ) ; // move past the `Delimited`
331
353
if !delim. skip ( ) {
332
354
return ( Token :: new ( token:: CloseDelim ( delim) , span. close ) , spacing. close ) ;
333
355
}
@@ -466,7 +488,7 @@ impl<'a> Parser<'a> {
466
488
capture_cfg : false ,
467
489
restrictions : Restrictions :: empty ( ) ,
468
490
expected_tokens : Vec :: new ( ) ,
469
- token_cursor : TokenCursor { tree_cursor : stream . into_trees ( ) , stack : Vec :: new ( ) } ,
491
+ token_cursor : TokenCursor { curr : TokenTreeCursor :: new ( stream ) , stack : Vec :: new ( ) } ,
470
492
num_bump_calls : 0 ,
471
493
break_last_token : 0 ,
472
494
unmatched_angle_bracket_count : 0 ,
@@ -1192,7 +1214,7 @@ impl<'a> Parser<'a> {
1192
1214
if dist == 1 {
1193
1215
// The index is zero because the tree cursor's index always points
1194
1216
// to the next token to be gotten.
1195
- match self . token_cursor . tree_cursor . look_ahead ( 0 ) {
1217
+ match self . token_cursor . curr . get ( ) {
1196
1218
Some ( tree) => {
1197
1219
// Indexing stayed within the current token tree.
1198
1220
match tree {
@@ -1207,7 +1229,8 @@ impl<'a> Parser<'a> {
1207
1229
None => {
1208
1230
// The tree cursor lookahead went (one) past the end of the
1209
1231
// current token tree. Try to return a close delimiter.
1210
- if let Some ( & ( _, span, _, delim) ) = self . token_cursor . stack . last ( )
1232
+ if let Some ( last) = self . token_cursor . stack . last ( )
1233
+ && let Some ( & TokenTree :: Delimited ( span, _, delim, _) ) = last. get ( )
1211
1234
&& !delim. skip ( )
1212
1235
{
1213
1236
// We are not in the outermost token stream, so we have
@@ -1399,9 +1422,10 @@ impl<'a> Parser<'a> {
1399
1422
pub fn parse_token_tree ( & mut self ) -> TokenTree {
1400
1423
match self . token . kind {
1401
1424
token:: OpenDelim ( ..) => {
1402
- // Grab the tokens within the delimiters.
1403
- let stream = self . token_cursor . tree_cursor . stream . clone ( ) ;
1404
- let ( _, span, spacing, delim) = * self . token_cursor . stack . last ( ) . unwrap ( ) ;
1425
+ // Clone the `TokenTree::Delimited` that we are currently
1426
+ // within. That's what we are going to return.
1427
+ let tree = self . token_cursor . stack . last ( ) . unwrap ( ) . get ( ) . unwrap ( ) . clone ( ) ;
1428
+ debug_assert_matches ! ( tree, TokenTree :: Delimited ( ..) ) ;
1405
1429
1406
1430
// Advance the token cursor through the entire delimited
1407
1431
// sequence. After getting the `OpenDelim` we are *within* the
@@ -1421,7 +1445,7 @@ impl<'a> Parser<'a> {
1421
1445
1422
1446
// Consume close delimiter
1423
1447
self . bump ( ) ;
1424
- TokenTree :: Delimited ( span , spacing , delim , stream )
1448
+ tree
1425
1449
}
1426
1450
token:: CloseDelim ( _) | token:: Eof => unreachable ! ( ) ,
1427
1451
_ => {
0 commit comments