@@ -178,10 +178,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
178178 self . imp . speculative_expand_attr ( actual_macro_call, speculative_args, token_to_map)
179179 }
180180
181+ /// Descend the token into macrocalls to its first mapped counterpart.
181182 pub fn descend_into_macros_single ( & self , token : SyntaxToken ) -> SyntaxToken {
182- self . imp . descend_into_macros ( token) . pop ( ) . unwrap ( )
183+ self . imp . descend_into_macros_single ( token)
183184 }
184185
186+ /// Descend the token into macrocalls to all its mapped counterparts.
185187 pub fn descend_into_macros ( & self , token : SyntaxToken ) -> SmallVec < [ SyntaxToken ; 1 ] > {
186188 self . imp . descend_into_macros ( token)
187189 }
@@ -509,47 +511,70 @@ impl<'db> SemanticsImpl<'db> {
509511 } ;
510512
511513 if first == last {
512- self . descend_into_macros_impl ( first, |InFile { value, .. } | {
513- if let Some ( node) = value. ancestors ( ) . find_map ( N :: cast) {
514- res. push ( node)
515- }
516- } ) ;
514+ self . descend_into_macros_impl (
515+ first,
516+ |InFile { value, .. } | {
517+ if let Some ( node) = value. ancestors ( ) . find_map ( N :: cast) {
518+ res. push ( node)
519+ }
520+ } ,
521+ false ,
522+ ) ;
517523 } else {
518524 // Descend first and last token, then zip them to look for the node they belong to
519525 let mut scratch: SmallVec < [ _ ; 1 ] > = smallvec ! [ ] ;
520- self . descend_into_macros_impl ( first, |token| {
521- scratch. push ( token) ;
522- } ) ;
526+ self . descend_into_macros_impl (
527+ first,
528+ |token| {
529+ scratch. push ( token) ;
530+ } ,
531+ false ,
532+ ) ;
523533
524534 let mut scratch = scratch. into_iter ( ) ;
525- self . descend_into_macros_impl ( last, |InFile { value : last, file_id : last_fid } | {
526- if let Some ( InFile { value : first, file_id : first_fid } ) = scratch. next ( ) {
527- if first_fid == last_fid {
528- if let Some ( p) = first. parent ( ) {
529- let range = first. text_range ( ) . cover ( last. text_range ( ) ) ;
530- let node = find_root ( & p)
531- . covering_element ( range)
532- . ancestors ( )
533- . take_while ( |it| it. text_range ( ) == range)
534- . find_map ( N :: cast) ;
535- if let Some ( node) = node {
536- res. push ( node) ;
535+ self . descend_into_macros_impl (
536+ last,
537+ |InFile { value : last, file_id : last_fid } | {
538+ if let Some ( InFile { value : first, file_id : first_fid } ) = scratch. next ( ) {
539+ if first_fid == last_fid {
540+ if let Some ( p) = first. parent ( ) {
541+ let range = first. text_range ( ) . cover ( last. text_range ( ) ) ;
542+ let node = find_root ( & p)
543+ . covering_element ( range)
544+ . ancestors ( )
545+ . take_while ( |it| it. text_range ( ) == range)
546+ . find_map ( N :: cast) ;
547+ if let Some ( node) = node {
548+ res. push ( node) ;
549+ }
537550 }
538551 }
539552 }
540- }
541- } ) ;
553+ } ,
554+ false ,
555+ ) ;
542556 }
543557 res
544558 }
545559
546560 fn descend_into_macros ( & self , token : SyntaxToken ) -> SmallVec < [ SyntaxToken ; 1 ] > {
547561 let mut res = smallvec ! [ ] ;
548- self . descend_into_macros_impl ( token, |InFile { value, .. } | res. push ( value) ) ;
562+ self . descend_into_macros_impl ( token, |InFile { value, .. } | res. push ( value) , false ) ;
563+ res
564+ }
565+
566+ fn descend_into_macros_single ( & self , token : SyntaxToken ) -> SyntaxToken {
567+ let mut res = token. clone ( ) ;
568+ self . descend_into_macros_impl ( token, |InFile { value, .. } | res = value, true ) ;
549569 res
550570 }
551571
552- fn descend_into_macros_impl ( & self , token : SyntaxToken , mut f : impl FnMut ( InFile < SyntaxToken > ) ) {
572+ fn descend_into_macros_impl (
573+ & self ,
574+ token : SyntaxToken ,
575+ mut f : impl FnMut ( InFile < SyntaxToken > ) ,
576+ single : bool ,
577+ ) {
553578 let _p = profile:: span ( "descend_into_macros" ) ;
554579 let parent = match token. parent ( ) {
555580 Some ( it) => it,
@@ -572,11 +597,16 @@ impl<'db> SemanticsImpl<'db> {
572597 self . cache ( value, file_id) ;
573598 }
574599
575- let mapped_tokens = expansion_info. map_token_down ( self . db . upcast ( ) , item, token) ?;
600+ let mut mapped_tokens =
601+ expansion_info. map_token_down ( self . db . upcast ( ) , item, token) ?;
576602
577603 let len = stack. len ( ) ;
578604 // requeue the tokens we got from mapping our current token down
579- stack. extend ( mapped_tokens) ;
605+ if single {
606+ stack. extend ( mapped_tokens. next ( ) ) ;
607+ } else {
608+ stack. extend ( mapped_tokens) ;
609+ }
580610 // if the length changed we have found a mapping for the token
581611 ( stack. len ( ) != len) . then ( || ( ) )
582612 } ;
0 commit comments