about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <me@lukaswirth.dev>2025-06-12 05:44:34 +0000
committerGitHub <noreply@github.com>2025-06-12 05:44:34 +0000
commit499e0dd622e885cf8c400ce40596f3acee90fc31 (patch)
treeb158aebf989fa4a61e74c1f48291984962a00838
parent75ab15bcdee2449e266935af51b8ddd2515e8b8f (diff)
parentac34cb4b4729114fe7f6dc3d1d0d6a00dc1322a6 (diff)
downloadrust-499e0dd622e885cf8c400ce40596f3acee90fc31.tar.gz
rust-499e0dd622e885cf8c400ce40596f3acee90fc31.zip
Merge pull request #19942 from ChayimFriedman2/faux
fix: Fix completion with some attribute macros
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/db.rs46
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs8
2 files changed, 26 insertions, 28 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
index 7cb1b6c0207..6fd9c497c1f 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs
@@ -13,7 +13,7 @@ use crate::{
     AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo,
     EagerExpander, EditionedFileId, ExpandError, ExpandResult, ExpandTo, HirFileId, MacroCallId,
     MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
-    attrs::{AttrId, collect_attrs},
+    attrs::{AttrId, AttrInput, RawAttrs, collect_attrs},
     builtin::pseudo_derive_attr_expansion,
     cfg_process,
     declarative::DeclarativeMacroExpander,
@@ -241,30 +241,36 @@ pub fn expand_speculative(
 
     let attr_arg = match loc.kind {
         MacroCallKind::Attr { invoc_attr_index, .. } => {
-            let attr = if loc.def.is_attribute_derive() {
+            if loc.def.is_attribute_derive() {
                 // for pseudo-derive expansion we actually pass the attribute itself only
-                ast::Attr::cast(speculative_args.clone())
+                ast::Attr::cast(speculative_args.clone()).and_then(|attr| attr.token_tree()).map(
+                    |token_tree| {
+                        let mut tree = syntax_node_to_token_tree(
+                            token_tree.syntax(),
+                            span_map,
+                            span,
+                            DocCommentDesugarMode::ProcMacro,
+                        );
+                        *tree.top_subtree_delimiter_mut() = tt::Delimiter::invisible_spanned(span);
+                        tree
+                    },
+                )
             } else {
                 // Attributes may have an input token tree, build the subtree and map for this as well
                 // then try finding a token id for our token if it is inside this input subtree.
                 let item = ast::Item::cast(speculative_args.clone())?;
-                collect_attrs(&item)
-                    .nth(invoc_attr_index.ast_index())
-                    .and_then(|x| Either::left(x.1))
-            }?;
-            match attr.token_tree() {
-                Some(token_tree) => {
-                    let mut tree = syntax_node_to_token_tree(
-                        token_tree.syntax(),
-                        span_map,
-                        span,
-                        DocCommentDesugarMode::ProcMacro,
-                    );
-                    *tree.top_subtree_delimiter_mut() = tt::Delimiter::invisible_spanned(span);
-
-                    Some(tree)
-                }
-                _ => None,
+                let attrs = RawAttrs::new_expanded(db, &item, span_map, loc.krate.cfg_options(db));
+                attrs.iter().find(|attr| attr.id == invoc_attr_index).and_then(|attr| {
+                    match attr.input.as_deref()? {
+                        AttrInput::TokenTree(tt) => {
+                            let mut attr_arg = tt.clone();
+                            attr_arg.top_subtree_delimiter_mut().kind =
+                                tt::DelimiterKind::Invisible;
+                            Some(attr_arg)
+                        }
+                        AttrInput::Literal(_) => None,
+                    }
+                })
             }
         }
         _ => None,
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index 953e2e7a025..47607a51d38 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -25,7 +25,6 @@ use hir_expand::{
     builtin::{BuiltinFnLikeExpander, EagerExpander},
     db::ExpandDatabase,
     files::{FileRangeWrapper, HirFileRange, InRealFile},
-    inert_attr_macro::find_builtin_attr_idx,
     mod_path::{ModPath, PathKind},
     name::AsName,
 };
@@ -969,13 +968,6 @@ impl<'db> SemanticsImpl<'db> {
             let Some(item) = ast::Item::cast(ancestor) else {
                 return false;
             };
-            // Optimization to skip the semantic check.
-            if item.attrs().all(|attr| {
-                attr.simple_name()
-                    .is_some_and(|attr| find_builtin_attr_idx(&Symbol::intern(&attr)).is_some())
-            }) {
-                return false;
-            }
             self.with_ctx(|ctx| {
                 if ctx.item_to_macro_call(token.with_value(&item)).is_some() {
                     return true;