@@ -22,9 +22,11 @@ use hir_expand::{
22
22
builtin:: { BuiltinFnLikeExpander , EagerExpander } ,
23
23
db:: ExpandDatabase ,
24
24
files:: InRealFile ,
25
+ inert_attr_macro:: find_builtin_attr_idx,
25
26
name:: AsName ,
26
27
FileRange , InMacroFile , MacroCallId , MacroFileId , MacroFileIdExt ,
27
28
} ;
29
+ use intern:: Symbol ;
28
30
use itertools:: Itertools ;
29
31
use rustc_hash:: { FxHashMap , FxHashSet } ;
30
32
use smallvec:: { smallvec, SmallVec } ;
@@ -666,8 +668,29 @@ impl<'db> SemanticsImpl<'db> {
666
668
res
667
669
}
668
670
671
+ fn is_inside_macro_call ( token : & SyntaxToken ) -> bool {
672
+ token. parent_ancestors ( ) . any ( |ancestor| {
673
+ if ast:: MacroCall :: can_cast ( ancestor. kind ( ) ) {
674
+ return true ;
675
+ }
676
+ // Check if it is an item (only items can have macro attributes) that has a non-builtin attribute.
677
+ let Some ( item) = ast:: Item :: cast ( ancestor) else { return false } ;
678
+ item. attrs ( ) . any ( |attr| {
679
+ let Some ( meta) = attr. meta ( ) else { return false } ;
680
+ let Some ( path) = meta. path ( ) else { return false } ;
681
+ let Some ( attr_name) = path. as_single_name_ref ( ) else { return true } ;
682
+ let attr_name = attr_name. text ( ) ;
683
+ let attr_name = attr_name. as_str ( ) ;
684
+ attr_name == "derive" || find_builtin_attr_idx ( & Symbol :: intern ( attr_name) ) . is_none ( )
685
+ } )
686
+ } )
687
+ }
688
+
669
689
/// Descend the token into its macro call if it is part of one, returning the tokens in the
670
690
/// expansion that it is associated with.
691
+ ///
692
+ /// Don't call this with a `SyntaxNode` from macro expansion, only one that the user wrote, because
693
+ /// this implements a shortcut by checking if the token is syntactically within a macro call.
671
694
pub fn descend_into_macros (
672
695
& self ,
673
696
mode : DescendPreference ,
@@ -678,6 +701,11 @@ impl<'db> SemanticsImpl<'db> {
678
701
SameKind ( SyntaxKind ) ,
679
702
None ,
680
703
}
704
+
705
+ if !Self :: is_inside_macro_call ( & token) {
706
+ return smallvec ! [ token] ;
707
+ }
708
+
681
709
let fetch_kind = |token : & SyntaxToken | match token. parent ( ) {
682
710
Some ( node) => match node. kind ( ) {
683
711
kind @ ( SyntaxKind :: NAME | SyntaxKind :: NAME_REF ) => kind,
@@ -713,6 +741,8 @@ impl<'db> SemanticsImpl<'db> {
713
741
res
714
742
}
715
743
744
+ /// Don't call this with a `SyntaxNode` from macro expansion, only one that the user wrote, because
745
+ /// this implements a shortcut by checking if the token is syntactically within a macro call.
716
746
pub fn descend_into_macros_single (
717
747
& self ,
718
748
mode : DescendPreference ,
@@ -723,6 +753,11 @@ impl<'db> SemanticsImpl<'db> {
723
753
SameKind ( SyntaxKind ) ,
724
754
None ,
725
755
}
756
+
757
+ if !Self :: is_inside_macro_call ( & token) {
758
+ return token;
759
+ }
760
+
726
761
let fetch_kind = |token : & SyntaxToken | match token. parent ( ) {
727
762
Some ( node) => match node. kind ( ) {
728
763
kind @ ( SyntaxKind :: NAME | SyntaxKind :: NAME_REF ) => kind,
0 commit comments