@@ -208,7 +208,12 @@ impl<'a> Drop for Parser<'a> {
208208
209209#[ derive( Clone ) ]
210210struct TokenCursor {
211+ // The current (innermost) frame. `frame` and `stack` could be combined,
212+ // but it's faster to have them separately to access `frame` directly
213+ // rather than via something like `stack.last().unwrap()` or
214+ // `stack[stack.len() - 1]`.
211215 frame : TokenCursorFrame ,
216+ // Additional frames that enclose `frame`.
212217 stack : Vec < TokenCursorFrame > ,
213218 desugar_doc_comments : bool ,
214219 // Counts the number of calls to `{,inlined_}next`.
@@ -242,17 +247,11 @@ struct TokenCursorFrame {
242247 delim : token:: DelimToken ,
243248 span : DelimSpan ,
244249 tree_cursor : tokenstream:: Cursor ,
245- need_to_produce_close_delim : bool ,
246250}
247251
248252impl TokenCursorFrame {
249253 fn new ( span : DelimSpan , delim : DelimToken , tts : TokenStream ) -> Self {
250- TokenCursorFrame {
251- delim,
252- span,
253- tree_cursor : tts. into_trees ( ) ,
254- need_to_produce_close_delim : delim != DelimToken :: NoDelim ,
255- }
254+ TokenCursorFrame { delim, span, tree_cursor : tts. into_trees ( ) }
256255 }
257256}
258257
@@ -265,6 +264,9 @@ impl TokenCursor {
265264 #[ inline( always) ]
266265 fn inlined_next ( & mut self , desugar_doc_comments : bool ) -> ( Token , Spacing ) {
267266 loop {
267+ // FIXME: we currently don't return `NoDelim` open/close delims. To fix #67062 we will
268+ // need to, whereupon the `delim != DelimToken::NoDelim` conditions below can be
269+ // removed, as well as the loop.
268270 if let Some ( ( tree, spacing) ) = self . frame . tree_cursor . next_with_spacing ( ) {
269271 match tree {
270272 TokenTree :: Token ( token) => match ( desugar_doc_comments, & token) {
@@ -283,15 +285,14 @@ impl TokenCursor {
283285 // No open delimeter to return; continue on to the next iteration.
284286 }
285287 } ;
286- } else if self . frame . need_to_produce_close_delim {
287- self . frame . need_to_produce_close_delim = false ;
288- return (
289- Token :: new ( token:: CloseDelim ( self . frame . delim ) , self . frame . span . close ) ,
290- Spacing :: Alone ,
291- ) ;
292288 } else if let Some ( frame) = self . stack . pop ( ) {
289+ let delim = self . frame . delim ;
290+ let span = self . frame . span ;
293291 self . frame = frame;
294- // Back to the parent frame; continue on to the next iteration.
292+ if delim != DelimToken :: NoDelim {
293+ return ( Token :: new ( token:: CloseDelim ( delim) , span. close ) , Spacing :: Alone ) ;
294+ }
295+ // No close delimiter to return; continue on to the next iteration.
295296 } else {
296297 return ( Token :: new ( token:: Eof , DUMMY_SP ) , Spacing :: Alone ) ;
297298 }
@@ -430,6 +431,8 @@ impl<'a> Parser<'a> {
430431 desugar_doc_comments : bool ,
431432 subparser_name : Option < & ' static str > ,
432433 ) -> Self {
434+ // Note: because of the way `TokenCursor::inlined_next` is structured, the `span` and
435+ // `delim` arguments here are never used.
433436 let start_frame = TokenCursorFrame :: new ( DelimSpan :: dummy ( ) , token:: NoDelim , tokens) ;
434437
435438 let mut parser = Parser {
@@ -1192,24 +1195,28 @@ impl<'a> Parser<'a> {
11921195 pub ( crate ) fn parse_token_tree ( & mut self ) -> TokenTree {
11931196 match self . token . kind {
11941197 token:: OpenDelim ( ..) => {
1195- let depth = self . token_cursor . stack . len ( ) ;
1198+ // Grab the tokens from this frame.
1199+ let frame = & self . token_cursor . frame ;
1200+ let stream = frame. tree_cursor . stream . clone ( ) ;
1201+ let span = frame. span ;
1202+ let delim = frame. delim ;
11961203
1197- // We keep advancing the token cursor until we hit
1198- // the matching `CloseDelim` token.
1199- while !( depth == self . token_cursor . stack . len ( )
1200- && matches ! ( self . token. kind, token:: CloseDelim ( _) ) )
1201- {
1204+ // Advance the token cursor through the entire delimited
1205+ // sequence. After getting the `OpenDelim` we are *within* the
1206+ // delimited sequence, i.e. at depth `d`. After getting the
1207+ // matching `CloseDelim` we are *after* the delimited sequence,
1208+ // i.e. at depth `d - 1`.
1209+ let target_depth = self . token_cursor . stack . len ( ) - 1 ;
1210+ loop {
12021211 // Advance one token at a time, so `TokenCursor::next()`
12031212 // can capture these tokens if necessary.
12041213 self . bump ( ) ;
1214+ if self . token_cursor . stack . len ( ) == target_depth {
1215+ debug_assert ! ( matches!( self . token. kind, token:: CloseDelim ( _) ) ) ;
1216+ break ;
1217+ }
12051218 }
1206- // We are still inside the frame corresponding
1207- // to the delimited stream we captured, so grab
1208- // the tokens from this frame.
1209- let frame = & self . token_cursor . frame ;
1210- let stream = frame. tree_cursor . stream . clone ( ) ;
1211- let span = frame. span ;
1212- let delim = frame. delim ;
1219+
12131220 // Consume close delimiter
12141221 self . bump ( ) ;
12151222 TokenTree :: Delimited ( span, delim, stream)
0 commit comments