about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir-def/src/lib.rs21
-rw-r--r--crates/hir-def/src/nameres/collector.rs39
2 files changed, 39 insertions, 21 deletions
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index fdab7382d37..e8187e05ada 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -1083,7 +1083,7 @@ pub trait AsMacroCall {
         &self,
         db: &dyn ExpandDatabase,
         krate: CrateId,
-        resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
+        resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
     ) -> Option<MacroCallId> {
         self.as_call_id_with_errors(db, krate, resolver).ok()?.value
     }
@@ -1092,7 +1092,7 @@ pub trait AsMacroCall {
         &self,
         db: &dyn ExpandDatabase,
         krate: CrateId,
-        resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
+        resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
     ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>;
 }
 
@@ -1101,7 +1101,7 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
         &self,
         db: &dyn ExpandDatabase,
         krate: CrateId,
-        resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
+        resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
     ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
         let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
         let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
@@ -1112,12 +1112,13 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
             return Ok(ExpandResult::only_err(ExpandError::other("malformed macro invocation")));
         };
 
-        macro_call_as_call_id_(
+        macro_call_as_call_id_with_eager(
             db,
             &AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
             expands_to,
             krate,
             resolver,
+            resolver,
         )
     }
 }
@@ -1140,17 +1141,19 @@ fn macro_call_as_call_id(
     call: &AstIdWithPath<ast::MacroCall>,
     expand_to: ExpandTo,
     krate: CrateId,
-    resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
+    resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
 ) -> Result<Option<MacroCallId>, UnresolvedMacro> {
-    macro_call_as_call_id_(db, call, expand_to, krate, resolver).map(|res| res.value)
+    macro_call_as_call_id_with_eager(db, call, expand_to, krate, resolver, resolver)
+        .map(|res| res.value)
 }
 
-fn macro_call_as_call_id_(
+fn macro_call_as_call_id_with_eager(
     db: &dyn ExpandDatabase,
     call: &AstIdWithPath<ast::MacroCall>,
     expand_to: ExpandTo,
     krate: CrateId,
-    resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
+    resolver: impl FnOnce(path::ModPath) -> Option<MacroDefId>,
+    eager_resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
 ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
     let def =
         resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
@@ -1159,7 +1162,7 @@ fn macro_call_as_call_id_(
         MacroDefKind::BuiltInEager(..) => {
             let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db));
             expand_eager_macro_input(db, krate, macro_call, def, &|path| {
-                resolver(path).filter(MacroDefId::is_fn_like)
+                eager_resolver(path).filter(MacroDefId::is_fn_like)
             })
         }
         _ if def.is_fn_like() => ExpandResult {
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index c048716d740..61915504b6c 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -38,7 +38,7 @@ use crate::{
         self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
         MacroCall, MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId,
     },
-    macro_call_as_call_id, macro_id_to_def_id,
+    macro_call_as_call_id, macro_call_as_call_id_with_eager, macro_id_to_def_id,
     nameres::{
         diagnostics::DefDiagnostic,
         mod_resolution::ModDir,
@@ -2187,7 +2187,7 @@ impl ModCollector<'_, '_> {
         // scopes without eager expansion.
 
         // Case 1: try to resolve macro calls with single-segment name and expand macro_rules
-        if let Ok(res) = macro_call_as_call_id(
+        if let Ok(res) = macro_call_as_call_id_with_eager(
             db.upcast(),
             &ast_id,
             mac.expand_to,
@@ -2210,19 +2210,34 @@ impl ModCollector<'_, '_> {
                         .map(|it| macro_id_to_def_id(self.def_collector.db, it))
                 })
             },
-        ) {
-            // Legacy macros need to be expanded immediately, so that any macros they produce
-            // are in scope.
-            if let Some(val) = res {
-                self.def_collector.collect_macro_expansion(
+            |path| {
+                let resolved_res = self.def_collector.def_map.resolve_path_fp_with_macro(
+                    db,
+                    ResolveMode::Other,
                     self.module_id,
-                    val,
-                    self.macro_depth + 1,
-                    container,
+                    &path,
+                    BuiltinShadowMode::Module,
+                    Some(MacroSubNs::Bang),
                 );
-            }
+                resolved_res.resolved_def.take_macros().map(|it| macro_id_to_def_id(db, it))
+            },
+        ) {
+            // FIXME: if there were errors, this mightve been in the eager expansion from an
+            // unresolved macro, so we need to push this into late macro resolution. see fixme above
+            if res.err.is_none() {
+                // Legacy macros need to be expanded immediately, so that any macros they produce
+                // are in scope.
+                if let Some(val) = res.value {
+                    self.def_collector.collect_macro_expansion(
+                        self.module_id,
+                        val,
+                        self.macro_depth + 1,
+                        container,
+                    );
+                }
 
-            return;
+                return;
+            }
         }
 
         // Case 2: resolve in module scope, expand during name resolution.