@@ -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 , AttrId , ByRef , Const , CoroutineKind , DUMMY_NODE_ID ,
@@ -273,21 +271,48 @@ struct CaptureState {
273
271
seen_attrs : IntervalSet < AttrId > ,
274
272
}
275
273
276
- /// Iterator over a `TokenStream` that produces `Token`s. It's a bit odd that
274
+ #[ derive( Clone , Debug ) ]
275
+ struct TokenTreeCursor {
276
+ stream : TokenStream ,
277
+ /// Points to the current token tree in the stream. In `TokenCursor::curr`,
278
+ /// this can be any token tree. In `TokenCursor::stack`, this is always a
279
+ /// `TokenTree::Delimited`.
280
+ index : usize ,
281
+ }
282
+
283
+ impl TokenTreeCursor {
284
+ #[ inline]
285
+ fn new ( stream : TokenStream ) -> Self {
286
+ TokenTreeCursor { stream, index : 0 }
287
+ }
288
+
289
+ #[ inline]
290
+ fn curr ( & self ) -> Option < & TokenTree > {
291
+ self . stream . get ( self . index )
292
+ }
293
+
294
+ #[ inline]
295
+ fn bump ( & mut self ) {
296
+ self . index += 1 ;
297
+ }
298
+ }
299
+
300
+ /// A `TokenStream` cursor that produces `Token`s. It's a bit odd that
277
301
/// we (a) lex tokens into a nice tree structure (`TokenStream`), and then (b)
278
302
/// use this type to emit them as a linear sequence. But a linear sequence is
279
303
/// what the parser expects, for the most part.
280
304
#[ derive( Clone , Debug ) ]
281
305
struct TokenCursor {
282
- // Cursor for the current (innermost) token stream. The delimiters for this
283
- // token stream are found in `self.stack.last()`; when that is `None` then
284
- // we are in the outermost token stream which never has delimiters.
285
- tree_cursor : TokenTreeCursor ,
286
-
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 ) > ,
306
+ // Cursor for the current (innermost) token stream. The index within the
307
+ // cursor can point to any token tree in the stream (or one past the end).
308
+ // The delimiters for this token stream are found in `self.stack.last()`;
309
+ // if that is `None` we are in the outermost token stream which never has
310
+ // delimiters.
311
+ curr : TokenTreeCursor ,
312
+
313
+ // Token streams surrounding the current one. The index within each cursor
314
+ // always points to a `TokenTree::Delimited`.
315
+ stack : Vec < TokenTreeCursor > ,
291
316
}
292
317
293
318
impl TokenCursor {
@@ -302,32 +327,33 @@ impl TokenCursor {
302
327
// FIXME: we currently don't return `Delimiter::Invisible` open/close delims. To fix
303
328
// #67062 we will need to, whereupon the `delim != Delimiter::Invisible` conditions
304
329
// below can be removed.
305
- if let Some ( tree) = self . tree_cursor . next_ref ( ) {
330
+ if let Some ( tree) = self . curr . curr ( ) {
306
331
match tree {
307
332
& TokenTree :: Token ( ref token, spacing) => {
308
333
debug_assert ! ( !matches!(
309
334
token. kind,
310
335
token:: OpenDelim ( _) | token:: CloseDelim ( _)
311
336
) ) ;
312
- return ( token. clone ( ) , spacing) ;
337
+ let res = ( token. clone ( ) , spacing) ;
338
+ self . curr . bump ( ) ;
339
+ return res;
313
340
}
314
341
& 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
- ) ) ;
342
+ let trees = TokenTreeCursor :: new ( tts. clone ( ) ) ;
343
+ self . stack . push ( mem:: replace ( & mut self . curr , trees) ) ;
322
344
if !delim. skip ( ) {
323
345
return ( Token :: new ( token:: OpenDelim ( delim) , sp. open ) , spacing. open ) ;
324
346
}
325
347
// No open delimiter to return; continue on to the next iteration.
326
348
}
327
349
} ;
328
- } else if let Some ( ( tree_cursor , span , spacing , delim ) ) = self . stack . pop ( ) {
350
+ } else if let Some ( parent ) = self . stack . pop ( ) {
329
351
// We have exhausted this token stream. Move back to its parent token stream.
330
- self . tree_cursor = tree_cursor;
352
+ let Some ( & TokenTree :: Delimited ( span, spacing, delim, _) ) = parent. curr ( ) else {
353
+ panic ! ( "parent should be Delimited" )
354
+ } ;
355
+ self . curr = parent;
356
+ self . curr . bump ( ) ; // move past the `Delimited`
331
357
if !delim. skip ( ) {
332
358
return ( Token :: new ( token:: CloseDelim ( delim) , span. close ) , spacing. close ) ;
333
359
}
@@ -466,7 +492,7 @@ impl<'a> Parser<'a> {
466
492
capture_cfg : false ,
467
493
restrictions : Restrictions :: empty ( ) ,
468
494
expected_tokens : Vec :: new ( ) ,
469
- token_cursor : TokenCursor { tree_cursor : stream . into_trees ( ) , stack : Vec :: new ( ) } ,
495
+ token_cursor : TokenCursor { curr : TokenTreeCursor :: new ( stream ) , stack : Vec :: new ( ) } ,
470
496
num_bump_calls : 0 ,
471
497
break_last_token : 0 ,
472
498
unmatched_angle_bracket_count : 0 ,
@@ -1192,7 +1218,7 @@ impl<'a> Parser<'a> {
1192
1218
if dist == 1 {
1193
1219
// The index is zero because the tree cursor's index always points
1194
1220
// to the next token to be gotten.
1195
- match self . token_cursor . tree_cursor . look_ahead ( 0 ) {
1221
+ match self . token_cursor . curr . curr ( ) {
1196
1222
Some ( tree) => {
1197
1223
// Indexing stayed within the current token tree.
1198
1224
match tree {
@@ -1202,12 +1228,13 @@ impl<'a> Parser<'a> {
1202
1228
return looker ( & Token :: new ( token:: OpenDelim ( delim) , dspan. open ) ) ;
1203
1229
}
1204
1230
}
1205
- } ;
1231
+ }
1206
1232
}
1207
1233
None => {
1208
1234
// The tree cursor lookahead went (one) past the end of the
1209
1235
// current token tree. Try to return a close delimiter.
1210
- if let Some ( & ( _, span, _, delim) ) = self . token_cursor . stack . last ( )
1236
+ if let Some ( last) = self . token_cursor . stack . last ( )
1237
+ && let Some ( & TokenTree :: Delimited ( span, _, delim, _) ) = last. curr ( )
1211
1238
&& !delim. skip ( )
1212
1239
{
1213
1240
// We are not in the outermost token stream, so we have
@@ -1399,9 +1426,10 @@ impl<'a> Parser<'a> {
1399
1426
pub fn parse_token_tree ( & mut self ) -> TokenTree {
1400
1427
match self . token . kind {
1401
1428
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 ( ) ;
1429
+ // Clone the `TokenTree::Delimited` that we are currently
1430
+ // within. That's what we are going to return.
1431
+ let tree = self . token_cursor . stack . last ( ) . unwrap ( ) . curr ( ) . unwrap ( ) . clone ( ) ;
1432
+ debug_assert_matches ! ( tree, TokenTree :: Delimited ( ..) ) ;
1405
1433
1406
1434
// Advance the token cursor through the entire delimited
1407
1435
// sequence. After getting the `OpenDelim` we are *within* the
@@ -1421,7 +1449,7 @@ impl<'a> Parser<'a> {
1421
1449
1422
1450
// Consume close delimiter
1423
1451
self . bump ( ) ;
1424
- TokenTree :: Delimited ( span , spacing , delim , stream )
1452
+ tree
1425
1453
}
1426
1454
token:: CloseDelim ( _) | token:: Eof => unreachable ! ( ) ,
1427
1455
_ => {
0 commit comments