@@ -224,7 +224,7 @@ impl<'a> Drop for Parser<'a> {
224224#[ derive( Clone ) ]
225225struct TokenCursor {
226226 // 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
228228 // rather than via something like `stack.last().unwrap()` or
229229 // `stack[stack.len() - 1]`.
230230 frame : TokenCursorFrame ,
@@ -259,6 +259,7 @@ struct TokenCursor {
259259
260260#[ derive( Clone ) ]
261261struct TokenCursorFrame {
262+ // This is `None` only for the outermost frame.
262263 delim_sp : Option < ( Delimiter , DelimSpan ) > ,
263264 tree_cursor : tokenstream:: Cursor ,
264265}
@@ -285,7 +286,9 @@ impl TokenCursor {
285286 match tree {
286287 & TokenTree :: Token ( ref token, spacing) => match ( desugar_doc_comments, token) {
287288 ( 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.
289292 }
290293 _ => return ( token. clone ( ) , spacing) ,
291294 } ,
@@ -300,19 +303,22 @@ impl TokenCursor {
300303 }
301304 } ;
302305 } 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 {
305310 return ( Token :: new ( token:: CloseDelim ( delim) , span. close ) , Spacing :: Alone ) ;
306311 }
307- self . frame = frame;
308312 // No close delimiter to return; continue on to the next iteration.
309313 } else {
314+ // We have exhausted the outermost frame.
310315 return ( Token :: new ( token:: Eof , DUMMY_SP ) , Spacing :: Alone ) ;
311316 }
312317 }
313318 }
314319
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 > {
316322 // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
317323 // required to wrap the text. E.g.
318324 // - `abc d` is wrapped as `r"abc d"` (num_of_hashes = 0)
@@ -346,27 +352,15 @@ impl TokenCursor {
346352 . collect :: < TokenStream > ( ) ,
347353 ) ;
348354
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+ }
370364 }
371365}
372366
0 commit comments