@@ -22,9 +22,11 @@ use hir_expand::{
2222 builtin:: { BuiltinFnLikeExpander , EagerExpander } ,
2323 db:: ExpandDatabase ,
2424 files:: InRealFile ,
25+ inert_attr_macro:: find_builtin_attr_idx,
2526 name:: AsName ,
2627 FileRange , InMacroFile , MacroCallId , MacroFileId , MacroFileIdExt ,
2728} ;
29+ use intern:: Symbol ;
2830use itertools:: Itertools ;
2931use rustc_hash:: { FxHashMap , FxHashSet } ;
3032use smallvec:: { smallvec, SmallVec } ;
@@ -666,8 +668,29 @@ impl<'db> SemanticsImpl<'db> {
666668 res
667669 }
668670
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+
669689 /// Descend the token into its macro call if it is part of one, returning the tokens in the
670690 /// 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.
671694 pub fn descend_into_macros (
672695 & self ,
673696 mode : DescendPreference ,
@@ -678,6 +701,11 @@ impl<'db> SemanticsImpl<'db> {
678701 SameKind ( SyntaxKind ) ,
679702 None ,
680703 }
704+
705+ if !Self :: is_inside_macro_call ( & token) {
706+ return smallvec ! [ token] ;
707+ }
708+
681709 let fetch_kind = |token : & SyntaxToken | match token. parent ( ) {
682710 Some ( node) => match node. kind ( ) {
683711 kind @ ( SyntaxKind :: NAME | SyntaxKind :: NAME_REF ) => kind,
@@ -713,6 +741,8 @@ impl<'db> SemanticsImpl<'db> {
713741 res
714742 }
715743
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.
716746 pub fn descend_into_macros_single (
717747 & self ,
718748 mode : DescendPreference ,
@@ -723,6 +753,11 @@ impl<'db> SemanticsImpl<'db> {
723753 SameKind ( SyntaxKind ) ,
724754 None ,
725755 }
756+
757+ if !Self :: is_inside_macro_call ( & token) {
758+ return token;
759+ }
760+
726761 let fetch_kind = |token : & SyntaxToken | match token. parent ( ) {
727762 Some ( node) => match node. kind ( ) {
728763 kind @ ( SyntaxKind :: NAME | SyntaxKind :: NAME_REF ) => kind,
0 commit comments