Skip to content

Commit 46a1ecc

Browse files
When descending into macros, first check if there is a need to - i.e. if we are inside a macro call
This avoids the need to analyze the file when we are not inside a macro call. This is especially important for the optimization in the next commit(s), as there the common case will be to descent into macros but then not analyze.
1 parent fa00326 commit 46a1ecc

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

crates/hir/src/semantics.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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;
2830
use itertools::Itertools;
2931
use rustc_hash::{FxHashMap, FxHashSet};
3032
use 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

Comments
 (0)