@@ -467,65 +467,73 @@ impl<'db> SemanticsImpl<'db> {
467467 let mut queue = vec ! [ InFile :: new( sa. file_id, token) ] ;
468468 let mut cache = self . expansion_info_cache . borrow_mut ( ) ;
469469 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.
470473 while let Some ( token) = queue. pop ( ) {
471474 self . db . unwind_if_cancelled ( ) ;
472475
473476 let was_not_remapped = ( || {
474477 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 ) ;
521528 }
522- } ,
523- _ => { }
529+ } ) ) ;
530+ return ( queue . len ( ) != len ) . then ( || ( ) ) ;
524531 }
525532 }
526533 }
527534 None
528- } ) ( ) . is_none ( ) ;
535+ } ) ( )
536+ . is_none ( ) ;
529537 if was_not_remapped {
530538 res. push ( token. value )
531539 }
0 commit comments