@@ -467,65 +467,73 @@ impl<'db> SemanticsImpl<'db> {
467
467
let mut queue = vec ! [ InFile :: new( sa. file_id, token) ] ;
468
468
let mut cache = self . expansion_info_cache . borrow_mut ( ) ;
469
469
let mut res = smallvec ! [ ] ;
470
+ // Remap the next token in the queue into a macro call its in, if it is not being remapped
471
+ // either due to not being in a macro-call or because its unused push it into the result vec,
472
+ // otherwise push the remapped tokens back into the queue as they can potentially be remapped again.
470
473
while let Some ( token) = queue. pop ( ) {
471
474
self . db . unwind_if_cancelled ( ) ;
472
475
473
476
let was_not_remapped = ( || {
474
477
for node in token. value . ancestors ( ) {
475
- match_ast ! {
476
- match node {
477
- ast:: MacroCall ( macro_call) => {
478
- let tt = macro_call. token_tree( ) ?;
479
- let l_delim = match tt. left_delimiter_token( ) {
480
- Some ( it) => it. text_range( ) . end( ) ,
481
- None => tt. syntax( ) . text_range( ) . start( )
482
- } ;
483
- let r_delim = match tt. right_delimiter_token( ) {
484
- Some ( it) => it. text_range( ) . start( ) ,
485
- None => tt. syntax( ) . text_range( ) . end( )
486
- } ;
487
- if !TextRange :: new( l_delim, r_delim) . contains_range( token. value. text_range( ) ) {
488
- return None ;
489
- }
490
- let file_id = sa. expand( self . db, token. with_value( & macro_call) ) ?;
491
- let tokens = cache
492
- . entry( file_id)
493
- . or_insert_with( || file_id. expansion_info( self . db. upcast( ) ) )
494
- . as_ref( ) ?
495
- . map_token_down( self . db. upcast( ) , None , token. as_ref( ) ) ?;
496
-
497
- let len = queue. len( ) ;
498
- queue. extend( tokens. inspect( |token| {
499
- if let Some ( parent) = token. value. parent( ) {
500
- self . cache( find_root( & parent) , token. file_id) ;
501
- }
502
- } ) ) ;
503
- return ( queue. len( ) != len) . then( || ( ) ) ;
504
- } ,
505
- ast:: Item ( item) => {
506
- if let Some ( call_id) = self . with_ctx( |ctx| ctx. item_to_macro_call( token. with_value( item. clone( ) ) ) ) {
507
- let file_id = call_id. as_file( ) ;
508
- let tokens = cache
509
- . entry( file_id)
510
- . or_insert_with( || file_id. expansion_info( self . db. upcast( ) ) )
511
- . as_ref( ) ?
512
- . map_token_down( self . db. upcast( ) , Some ( item) , token. as_ref( ) ) ?;
513
-
514
- let len = queue. len( ) ;
515
- queue. extend( tokens. inspect( |token| {
516
- if let Some ( parent) = token. value. parent( ) {
517
- self . cache( find_root( & parent) , token. file_id) ;
518
- }
519
- } ) ) ;
520
- return ( queue. len( ) != len) . then( || ( ) ) ;
478
+ if let Some ( macro_call) = ast:: MacroCall :: cast ( node. clone ( ) ) {
479
+ let tt = match macro_call. token_tree ( ) {
480
+ Some ( tt) => tt,
481
+ None => continue ,
482
+ } ;
483
+ let l_delim = match tt. left_delimiter_token ( ) {
484
+ Some ( it) => it. text_range ( ) . end ( ) ,
485
+ None => tt. syntax ( ) . text_range ( ) . start ( ) ,
486
+ } ;
487
+ let r_delim = match tt. right_delimiter_token ( ) {
488
+ Some ( it) => it. text_range ( ) . start ( ) ,
489
+ None => tt. syntax ( ) . text_range ( ) . end ( ) ,
490
+ } ;
491
+ if !TextRange :: new ( l_delim, r_delim)
492
+ . contains_range ( token. value . text_range ( ) )
493
+ {
494
+ continue ;
495
+ }
496
+ let file_id = match sa. expand ( self . db , token. with_value ( & macro_call) ) {
497
+ Some ( file_id) => file_id,
498
+ None => continue ,
499
+ } ;
500
+ let tokens = cache
501
+ . entry ( file_id)
502
+ . or_insert_with ( || file_id. expansion_info ( self . db . upcast ( ) ) )
503
+ . as_ref ( ) ?
504
+ . map_token_down ( self . db . upcast ( ) , None , token. as_ref ( ) ) ?;
505
+
506
+ let len = queue. len ( ) ;
507
+ queue. extend ( tokens. inspect ( |token| {
508
+ if let Some ( parent) = token. value . parent ( ) {
509
+ self . cache ( find_root ( & parent) , token. file_id ) ;
510
+ }
511
+ } ) ) ;
512
+ return ( queue. len ( ) != len) . then ( || ( ) ) ;
513
+ } else if let Some ( item) = ast:: Item :: cast ( node. clone ( ) ) {
514
+ if let Some ( call_id) = self
515
+ . with_ctx ( |ctx| ctx. item_to_macro_call ( token. with_value ( item. clone ( ) ) ) )
516
+ {
517
+ let file_id = call_id. as_file ( ) ;
518
+ let tokens = cache
519
+ . entry ( file_id)
520
+ . or_insert_with ( || file_id. expansion_info ( self . db . upcast ( ) ) )
521
+ . as_ref ( ) ?
522
+ . map_token_down ( self . db . upcast ( ) , Some ( item) , token. as_ref ( ) ) ?;
523
+
524
+ let len = queue. len ( ) ;
525
+ queue. extend ( tokens. inspect ( |token| {
526
+ if let Some ( parent) = token. value . parent ( ) {
527
+ self . cache ( find_root ( & parent) , token. file_id ) ;
521
528
}
522
- } ,
523
- _ => { }
529
+ } ) ) ;
530
+ return ( queue . len ( ) != len ) . then ( || ( ) ) ;
524
531
}
525
532
}
526
533
}
527
534
None
528
- } ) ( ) . is_none ( ) ;
535
+ } ) ( )
536
+ . is_none ( ) ;
529
537
if was_not_remapped {
530
538
res. push ( token. value )
531
539
}
0 commit comments