@@ -178,10 +178,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
178
178
self . imp . speculative_expand_attr ( actual_macro_call, speculative_args, token_to_map)
179
179
}
180
180
181
+ /// Descend the token into macrocalls to its first mapped counterpart.
181
182
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)
183
184
}
184
185
186
+ /// Descend the token into macrocalls to all its mapped counterparts.
185
187
pub fn descend_into_macros ( & self , token : SyntaxToken ) -> SmallVec < [ SyntaxToken ; 1 ] > {
186
188
self . imp . descend_into_macros ( token)
187
189
}
@@ -509,47 +511,70 @@ impl<'db> SemanticsImpl<'db> {
509
511
} ;
510
512
511
513
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
+ ) ;
517
523
} else {
518
524
// Descend first and last token, then zip them to look for the node they belong to
519
525
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
+ ) ;
523
533
524
534
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
+ }
537
550
}
538
551
}
539
552
}
540
- }
541
- } ) ;
553
+ } ,
554
+ false ,
555
+ ) ;
542
556
}
543
557
res
544
558
}
545
559
546
560
fn descend_into_macros ( & self , token : SyntaxToken ) -> SmallVec < [ SyntaxToken ; 1 ] > {
547
561
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 ) ;
549
569
res
550
570
}
551
571
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
+ ) {
553
578
let _p = profile:: span ( "descend_into_macros" ) ;
554
579
let parent = match token. parent ( ) {
555
580
Some ( it) => it,
@@ -572,11 +597,16 @@ impl<'db> SemanticsImpl<'db> {
572
597
self . cache ( value, file_id) ;
573
598
}
574
599
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) ?;
576
602
577
603
let len = stack. len ( ) ;
578
604
// 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
+ }
580
610
// if the length changed we have found a mapping for the token
581
611
( stack. len ( ) != len) . then ( || ( ) )
582
612
} ;
0 commit comments