]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir/src/semantics.rs
internal: Record unresolved derive invocations in hir
[rust.git] / crates / hir / src / semantics.rs
index 2cf63efff82c9b1facccc9800eb8cb3ac7846923..645b10f8534e11fb0c173152aef7bd50c2ada83f 100644 (file)
@@ -10,7 +10,7 @@
     resolver::{self, HasResolver, Resolver, TypeNs},
     AsMacroCall, FunctionId, TraitId, VariantId,
 };
-use hir_expand::{name::AsName, ExpansionInfo, MacroCallLoc};
+use hir_expand::{name::AsName, ExpansionInfo, MacroCallId};
 use hir_ty::{associated_type_shorthand_candidates, Interner};
 use itertools::Itertools;
 use rustc_hash::{FxHashMap, FxHashSet};
@@ -160,7 +160,7 @@ pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
         self.imp.expand_attr_macro(item)
     }
 
-    pub fn resolve_derive_macro(&self, derive: &ast::Attr) -> Option<Vec<MacroDef>> {
+    pub fn resolve_derive_macro(&self, derive: &ast::Attr) -> Option<Vec<Option<MacroDef>>> {
         self.imp.resolve_derive_macro(derive)
     }
 
@@ -447,47 +447,37 @@ fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
         Some(node)
     }
 
-    fn resolve_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<MacroDef>> {
-        let item = attr.syntax().parent().and_then(ast::Item::cast)?;
-        let file_id = self.find_file(item.syntax()).file_id;
-        let item = InFile::new(file_id, &item);
-        let src = InFile::new(file_id, attr.clone());
-        self.with_ctx(|ctx| {
-            let macro_call_ids = ctx.attr_to_derive_macro_call(item, src)?;
-
-            let res = macro_call_ids
-                .iter()
-                .map(|&call| {
-                    let loc: MacroCallLoc = self.db.lookup_intern_macro_call(call);
-                    MacroDef { id: loc.def }
-                })
-                .collect();
-            Some(res)
-        })
+    fn resolve_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<Option<MacroDef>>> {
+        let res = self
+            .derive_macro_calls(attr)?
+            .into_iter()
+            .map(|call| Some(MacroDef { id: self.db.lookup_intern_macro_call(call?).def }))
+            .collect();
+        Some(res)
     }
 
     fn expand_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<SyntaxNode>> {
+        let res: Vec<_> = self
+            .derive_macro_calls(attr)?
+            .into_iter()
+            .flat_map(|call| {
+                let file_id = call?.as_file();
+                let node = self.db.parse_or_expand(file_id)?;
+                self.cache(node.clone(), file_id);
+                Some(node)
+            })
+            .collect();
+        Some(res)
+    }
+
+    fn derive_macro_calls(&self, attr: &ast::Attr) -> Option<Vec<Option<MacroCallId>>> {
         let item = attr.syntax().parent().and_then(ast::Item::cast)?;
         let file_id = self.find_file(item.syntax()).file_id;
         let item = InFile::new(file_id, &item);
         let src = InFile::new(file_id, attr.clone());
         self.with_ctx(|ctx| {
-            let macro_call_ids = ctx.attr_to_derive_macro_call(item, src)?;
-
-            let expansions: Vec<_> = macro_call_ids
-                .iter()
-                .map(|call| call.as_file())
-                .flat_map(|file_id| {
-                    let node = self.db.parse_or_expand(file_id)?;
-                    self.cache(node.clone(), file_id);
-                    Some(node)
-                })
-                .collect();
-            if expansions.is_empty() {
-                None
-            } else {
-                Some(expansions)
-            }
+            let res = ctx.attr_to_derive_macro_call(item, src)?;
+            Some(res.to_vec())
         })
     }