@@ -224,7 +224,7 @@ impl<'a> Drop for Parser<'a> {
224
224
#[ derive( Clone ) ]
225
225
struct TokenCursor {
226
226
// The current (innermost) frame. `frame` and `stack` could be combined,
227
- // but it's faster to have them separately to access `frame` directly
227
+ // but it's faster to keep them separate and access `frame` directly
228
228
// rather than via something like `stack.last().unwrap()` or
229
229
// `stack[stack.len() - 1]`.
230
230
frame : TokenCursorFrame ,
@@ -259,6 +259,7 @@ struct TokenCursor {
259
259
260
260
#[ derive( Clone ) ]
261
261
struct TokenCursorFrame {
262
+ // This is `None` only for the outermost frame.
262
263
delim_sp : Option < ( Delimiter , DelimSpan ) > ,
263
264
tree_cursor : tokenstream:: Cursor ,
264
265
}
@@ -285,7 +286,9 @@ impl TokenCursor {
285
286
match tree {
286
287
& TokenTree :: Token ( ref token, spacing) => match ( desugar_doc_comments, token) {
287
288
( true , & Token { kind : token:: DocComment ( _, attr_style, data) , span } ) => {
288
- return self . desugar ( attr_style, data, span) ;
289
+ let desugared = self . desugar ( attr_style, data, span) ;
290
+ self . frame . tree_cursor . replace_prev_and_rewind ( desugared) ;
291
+ // Continue to get the first token of the desugared doc comment.
289
292
}
290
293
_ => return ( token. clone ( ) , spacing) ,
291
294
} ,
@@ -300,19 +303,22 @@ impl TokenCursor {
300
303
}
301
304
} ;
302
305
} else if let Some ( frame) = self . stack . pop ( ) {
303
- if let Some ( ( delim, span) ) = self . frame . delim_sp && delim != Delimiter :: Invisible {
304
- self . frame = frame;
306
+ // We have exhausted this frame. Move back to its parent frame.
307
+ let ( delim, span) = self . frame . delim_sp . unwrap ( ) ;
308
+ self . frame = frame;
309
+ if delim != Delimiter :: Invisible {
305
310
return ( Token :: new ( token:: CloseDelim ( delim) , span. close ) , Spacing :: Alone ) ;
306
311
}
307
- self . frame = frame;
308
312
// No close delimiter to return; continue on to the next iteration.
309
313
} else {
314
+ // We have exhausted the outermost frame.
310
315
return ( Token :: new ( token:: Eof , DUMMY_SP ) , Spacing :: Alone ) ;
311
316
}
312
317
}
313
318
}
314
319
315
- fn desugar ( & mut self , attr_style : AttrStyle , data : Symbol , span : Span ) -> ( Token , Spacing ) {
320
+ // Desugar a doc comment into something like `#[doc = r"foo"]`.
321
+ fn desugar ( & mut self , attr_style : AttrStyle , data : Symbol , span : Span ) -> Vec < TokenTree > {
316
322
// Searches for the occurrences of `"#*` and returns the minimum number of `#`s
317
323
// required to wrap the text. E.g.
318
324
// - `abc d` is wrapped as `r"abc d"` (num_of_hashes = 0)
@@ -346,27 +352,15 @@ impl TokenCursor {
346
352
. collect :: < TokenStream > ( ) ,
347
353
) ;
348
354
349
- self . stack . push ( mem:: replace (
350
- & mut self . frame ,
351
- TokenCursorFrame :: new (
352
- None ,
353
- if attr_style == AttrStyle :: Inner {
354
- [
355
- TokenTree :: token_alone ( token:: Pound , span) ,
356
- TokenTree :: token_alone ( token:: Not , span) ,
357
- body,
358
- ]
359
- . into_iter ( )
360
- . collect :: < TokenStream > ( )
361
- } else {
362
- [ TokenTree :: token_alone ( token:: Pound , span) , body]
363
- . into_iter ( )
364
- . collect :: < TokenStream > ( )
365
- } ,
366
- ) ,
367
- ) ) ;
368
-
369
- self . next ( /* desugar_doc_comments */ false )
355
+ if attr_style == AttrStyle :: Inner {
356
+ vec ! [
357
+ TokenTree :: token_alone( token:: Pound , span) ,
358
+ TokenTree :: token_alone( token:: Not , span) ,
359
+ body,
360
+ ]
361
+ } else {
362
+ vec ! [ TokenTree :: token_alone( token:: Pound , span) , body]
363
+ }
370
364
}
371
365
}
372
366
0 commit comments