@@ -190,20 +190,13 @@ fn convert_tokens<C: TokenConverter>(conv: &mut C) -> tt::Subtree {
190
190
191
191
let kind = token. kind ( conv) ;
192
192
if kind == COMMENT {
193
- if let Some ( tokens) = conv. convert_doc_comment ( & token) {
194
- // FIXME: There has to be a better way to do this
195
- // Add the comments token id to the converted doc string
193
+ // Since `convert_doc_comment` can fail, we need to peek the next id, so that we can
194
+ // figure out which token id to use for the doc comment, if it is converted successfully.
195
+ let next_id = conv. id_alloc ( ) . peek_next_id ( ) ;
196
+ if let Some ( tokens) = conv. convert_doc_comment ( & token, next_id) {
196
197
let id = conv. id_alloc ( ) . alloc ( range, synth_id) ;
197
- result. extend ( tokens. into_iter ( ) . map ( |mut tt| {
198
- if let tt:: TokenTree :: Subtree ( sub) = & mut tt {
199
- if let Some ( tt:: TokenTree :: Leaf ( tt:: Leaf :: Literal ( lit) ) ) =
200
- sub. token_trees . get_mut ( 2 )
201
- {
202
- lit. span = id
203
- }
204
- }
205
- tt
206
- } ) ) ;
198
+ debug_assert_eq ! ( id, next_id) ;
199
+ result. extend ( tokens) ;
207
200
}
208
201
continue ;
209
202
}
@@ -382,49 +375,46 @@ fn doc_comment_text(comment: &ast::Comment) -> SmolStr {
382
375
text. into ( )
383
376
}
384
377
385
- fn convert_doc_comment ( token : & syntax:: SyntaxToken ) -> Option < Vec < tt:: TokenTree > > {
378
+ fn convert_doc_comment (
379
+ token : & syntax:: SyntaxToken ,
380
+ span : tt:: TokenId ,
381
+ ) -> Option < Vec < tt:: TokenTree > > {
386
382
cov_mark:: hit!( test_meta_doc_comments) ;
387
383
let comment = ast:: Comment :: cast ( token. clone ( ) ) ?;
388
384
let doc = comment. kind ( ) . doc ?;
389
385
390
386
// Make `doc="\" Comments\""
391
- let meta_tkns = vec ! [ mk_ident( "doc" ) , mk_punct( '=' ) , mk_doc_literal( & comment) ] ;
387
+ let meta_tkns =
388
+ vec ! [ mk_ident( "doc" , span) , mk_punct( '=' , span) , mk_doc_literal( & comment, span) ] ;
392
389
393
390
// Make `#![]`
394
391
let mut token_trees = Vec :: with_capacity ( 3 ) ;
395
- token_trees. push ( mk_punct ( '#' ) ) ;
392
+ token_trees. push ( mk_punct ( '#' , span ) ) ;
396
393
if let ast:: CommentPlacement :: Inner = doc {
397
- token_trees. push ( mk_punct ( '!' ) ) ;
394
+ token_trees. push ( mk_punct ( '!' , span ) ) ;
398
395
}
399
396
token_trees. push ( tt:: TokenTree :: from ( tt:: Subtree {
400
- delimiter : tt:: Delimiter {
401
- open : tt:: TokenId :: UNSPECIFIED ,
402
- close : tt:: TokenId :: UNSPECIFIED ,
403
- kind : tt:: DelimiterKind :: Bracket ,
404
- } ,
397
+ delimiter : tt:: Delimiter { open : span, close : span, kind : tt:: DelimiterKind :: Bracket } ,
405
398
token_trees : meta_tkns,
406
399
} ) ) ;
407
400
408
401
return Some ( token_trees) ;
409
402
410
403
// Helper functions
411
- fn mk_ident ( s : & str ) -> tt:: TokenTree {
412
- tt:: TokenTree :: from ( tt:: Leaf :: from ( tt:: Ident {
413
- text : s. into ( ) ,
414
- span : tt:: TokenId :: unspecified ( ) ,
415
- } ) )
404
+ fn mk_ident ( s : & str , span : tt:: TokenId ) -> tt:: TokenTree {
405
+ tt:: TokenTree :: from ( tt:: Leaf :: from ( tt:: Ident { text : s. into ( ) , span } ) )
416
406
}
417
407
418
- fn mk_punct ( c : char ) -> tt:: TokenTree {
408
+ fn mk_punct ( c : char , span : tt :: TokenId ) -> tt:: TokenTree {
419
409
tt:: TokenTree :: from ( tt:: Leaf :: from ( tt:: Punct {
420
410
char : c,
421
411
spacing : tt:: Spacing :: Alone ,
422
- span : tt :: TokenId :: unspecified ( ) ,
412
+ span,
423
413
} ) )
424
414
}
425
415
426
- fn mk_doc_literal ( comment : & ast:: Comment ) -> tt:: TokenTree {
427
- let lit = tt:: Literal { text : doc_comment_text ( comment) , span : tt :: TokenId :: unspecified ( ) } ;
416
+ fn mk_doc_literal ( comment : & ast:: Comment , span : tt :: TokenId ) -> tt:: TokenTree {
417
+ let lit = tt:: Literal { text : doc_comment_text ( comment) , span } ;
428
418
429
419
tt:: TokenTree :: from ( tt:: Leaf :: from ( lit) )
430
420
}
@@ -480,6 +470,10 @@ impl TokenIdAlloc {
480
470
}
481
471
}
482
472
}
473
+
474
+ fn peek_next_id ( & self ) -> tt:: TokenId {
475
+ tt:: TokenId ( self . next_id )
476
+ }
483
477
}
484
478
485
479
/// A raw token (straight from lexer) converter
@@ -502,7 +496,11 @@ trait SrcToken<Ctx>: std::fmt::Debug {
502
496
trait TokenConverter : Sized {
503
497
type Token : SrcToken < Self > ;
504
498
505
- fn convert_doc_comment ( & self , token : & Self :: Token ) -> Option < Vec < tt:: TokenTree > > ;
499
+ fn convert_doc_comment (
500
+ & self ,
501
+ token : & Self :: Token ,
502
+ span : tt:: TokenId ,
503
+ ) -> Option < Vec < tt:: TokenTree > > ;
506
504
507
505
fn bump ( & mut self ) -> Option < ( Self :: Token , TextRange ) > ;
508
506
@@ -532,9 +530,9 @@ impl<'a> SrcToken<RawConverter<'a>> for usize {
532
530
impl < ' a > TokenConverter for RawConverter < ' a > {
533
531
type Token = usize ;
534
532
535
- fn convert_doc_comment ( & self , & token: & usize ) -> Option < Vec < tt:: TokenTree > > {
533
+ fn convert_doc_comment ( & self , & token: & usize , span : tt :: TokenId ) -> Option < Vec < tt:: TokenTree > > {
536
534
let text = self . lexed . text ( token) ;
537
- convert_doc_comment ( & doc_comment ( text) )
535
+ convert_doc_comment ( & doc_comment ( text) , span )
538
536
}
539
537
540
538
fn bump ( & mut self ) -> Option < ( Self :: Token , TextRange ) > {
@@ -681,8 +679,12 @@ impl SrcToken<Converter> for SynToken {
681
679
682
680
impl TokenConverter for Converter {
683
681
type Token = SynToken ;
684
- fn convert_doc_comment ( & self , token : & Self :: Token ) -> Option < Vec < tt:: TokenTree > > {
685
- convert_doc_comment ( token. token ( ) ?)
682
+ fn convert_doc_comment (
683
+ & self ,
684
+ token : & Self :: Token ,
685
+ span : tt:: TokenId ,
686
+ ) -> Option < Vec < tt:: TokenTree > > {
687
+ convert_doc_comment ( token. token ( ) ?, span)
686
688
}
687
689
688
690
fn bump ( & mut self ) -> Option < ( Self :: Token , TextRange ) > {
0 commit comments