Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/semantics.rs')
-rw-r--r--crates/hir/src/semantics.rs31
1 files changed, 31 insertions, 0 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 3d6c985043..763f53031e 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -23,9 +23,11 @@ use hir_expand::{
builtin::{BuiltinFnLikeExpander, EagerExpander},
db::ExpandDatabase,
files::InRealFile,
+ inert_attr_macro::find_builtin_attr_idx,
name::AsName,
FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt,
};
+use intern::Symbol;
use itertools::Itertools;
use rustc_hash::{FxHashMap, FxHashSet};
use smallvec::{smallvec, SmallVec};
@@ -674,6 +676,35 @@ impl<'db> SemanticsImpl<'db> {
res
}
+ fn is_inside_macro_call(token: &SyntaxToken) -> bool {
+ token.parent_ancestors().any(|ancestor| {
+ if ast::MacroCall::can_cast(ancestor.kind()) {
+ return true;
+ }
+ // Check if it is an item (only items can have macro attributes) that has a non-builtin attribute.
+ let Some(item) = ast::Item::cast(ancestor) else { return false };
+ item.attrs().any(|attr| {
+ let Some(meta) = attr.meta() else { return false };
+ let Some(path) = meta.path() else { return false };
+ let Some(attr_name) = path.as_single_name_ref() else { return true };
+ let attr_name = attr_name.text();
+ let attr_name = attr_name.as_str();
+ attr_name == "derive" || find_builtin_attr_idx(&Symbol::intern(attr_name)).is_none()
+ })
+ })
+ }
+
+ pub fn descend_into_macros_exact_if_in_macro(
+ &self,
+ token: SyntaxToken,
+ ) -> SmallVec<[SyntaxToken; 1]> {
+ if Self::is_inside_macro_call(&token) {
+ self.descend_into_macros_exact(token)
+ } else {
+ smallvec![token]
+ }
+ }
+
pub fn descend_into_macros_cb(
&self,
token: SyntaxToken,