@@ -24,9 +24,7 @@ use rustc_ast::ptr::P;
2424use rustc_ast:: token:: {
2525 self , Delimiter , IdentIsRaw , InvisibleOrigin , MetaVarKind , Nonterminal , Token , TokenKind ,
2626} ;
27- use rustc_ast:: tokenstream:: {
28- AttrsTarget , DelimSpacing , DelimSpan , Spacing , TokenStream , TokenTree , TokenTreeCursor ,
29- } ;
27+ use rustc_ast:: tokenstream:: { AttrsTarget , Spacing , TokenStream , TokenTree } ;
3028use rustc_ast:: util:: case:: Case ;
3129use rustc_ast:: {
3230 self as ast, AnonConst , AttrArgs , AttrId , ByRef , Const , CoroutineKind , DUMMY_NODE_ID ,
@@ -273,21 +271,48 @@ struct CaptureState {
273271 seen_attrs : IntervalSet < AttrId > ,
274272}
275273
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
277301/// we (a) lex tokens into a nice tree structure (`TokenStream`), and then (b)
278302/// use this type to emit them as a linear sequence. But a linear sequence is
279303/// what the parser expects, for the most part.
280304#[ derive( Clone , Debug ) ]
281305struct 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 > ,
291316}
292317
293318impl TokenCursor {
@@ -302,32 +327,33 @@ impl TokenCursor {
302327 // FIXME: we currently don't return `Delimiter::Invisible` open/close delims. To fix
303328 // #67062 we will need to, whereupon the `delim != Delimiter::Invisible` conditions
304329 // below can be removed.
305- if let Some ( tree) = self . tree_cursor . next_ref ( ) {
330+ if let Some ( tree) = self . curr . curr ( ) {
306331 match tree {
307332 & TokenTree :: Token ( ref token, spacing) => {
308333 debug_assert ! ( !matches!(
309334 token. kind,
310335 token:: OpenDelim ( _) | token:: CloseDelim ( _)
311336 ) ) ;
312- return ( token. clone ( ) , spacing) ;
337+ let res = ( token. clone ( ) , spacing) ;
338+ self . curr . bump ( ) ;
339+ return res;
313340 }
314341 & 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) ) ;
322344 if !delim. skip ( ) {
323345 return ( Token :: new ( token:: OpenDelim ( delim) , sp. open ) , spacing. open ) ;
324346 }
325347 // No open delimiter to return; continue on to the next iteration.
326348 }
327349 } ;
328- } else if let Some ( ( tree_cursor , span , spacing , delim ) ) = self . stack . pop ( ) {
350+ } else if let Some ( parent ) = self . stack . pop ( ) {
329351 // 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`
331357 if !delim. skip ( ) {
332358 return ( Token :: new ( token:: CloseDelim ( delim) , span. close ) , spacing. close ) ;
333359 }
@@ -466,7 +492,7 @@ impl<'a> Parser<'a> {
466492 capture_cfg : false ,
467493 restrictions : Restrictions :: empty ( ) ,
468494 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 ( ) } ,
470496 num_bump_calls : 0 ,
471497 break_last_token : 0 ,
472498 unmatched_angle_bracket_count : 0 ,
@@ -1192,7 +1218,7 @@ impl<'a> Parser<'a> {
11921218 if dist == 1 {
11931219 // The index is zero because the tree cursor's index always points
11941220 // to the next token to be gotten.
1195- match self . token_cursor . tree_cursor . look_ahead ( 0 ) {
1221+ match self . token_cursor . curr . curr ( ) {
11961222 Some ( tree) => {
11971223 // Indexing stayed within the current token tree.
11981224 match tree {
@@ -1202,12 +1228,13 @@ impl<'a> Parser<'a> {
12021228 return looker ( & Token :: new ( token:: OpenDelim ( delim) , dspan. open ) ) ;
12031229 }
12041230 }
1205- } ;
1231+ }
12061232 }
12071233 None => {
12081234 // The tree cursor lookahead went (one) past the end of the
12091235 // 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 ( )
12111238 && !delim. skip ( )
12121239 {
12131240 // We are not in the outermost token stream, so we have
@@ -1399,9 +1426,10 @@ impl<'a> Parser<'a> {
13991426 pub fn parse_token_tree ( & mut self ) -> TokenTree {
14001427 match self . token . kind {
14011428 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 ( ..) ) ;
14051433
14061434 // Advance the token cursor through the entire delimited
14071435 // sequence. After getting the `OpenDelim` we are *within* the
@@ -1421,7 +1449,7 @@ impl<'a> Parser<'a> {
14211449
14221450 // Consume close delimiter
14231451 self . bump ( ) ;
1424- TokenTree :: Delimited ( span , spacing , delim , stream )
1452+ tree
14251453 }
14261454 token:: CloseDelim ( _) | token:: Eof => unreachable ! ( ) ,
14271455 _ => {
0 commit comments