Skip to content

Commit 7fa66d6

Browse files
Merge pull request #19862 from ChayimFriedman2/item-resolve-macro-hir
fix: Fix IDE resolution of item macros
2 parents f98b622 + 3e0ab72 commit 7fa66d6

File tree

6 files changed

+74
-29
lines changed

6 files changed

+74
-29
lines changed

crates/hir-def/src/db.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
422422
let makro = &item_tree[loc.id.value];
423423
MacroDefId {
424424
krate: loc.container.krate,
425+
block: loc.container.block.map(|block| salsa::plumbing::AsId::as_id(&block)),
425426
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
426427
local_inner: false,
427428
allow_internal_unsafe: loc.allow_internal_unsafe,
@@ -435,6 +436,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
435436
let makro = &item_tree[loc.id.value];
436437
MacroDefId {
437438
krate: loc.container.krate,
439+
block: loc.container.block.map(|block| salsa::plumbing::AsId::as_id(&block)),
438440
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
439441
local_inner: loc.flags.contains(MacroRulesLocFlags::LOCAL_INNER),
440442
allow_internal_unsafe: loc
@@ -450,6 +452,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
450452
let makro = &item_tree[loc.id.value];
451453
MacroDefId {
452454
krate: loc.container.krate,
455+
block: None,
453456
kind: MacroDefKind::ProcMacro(
454457
InFile::new(loc.id.file_id(), makro.ast_id),
455458
loc.expander,

crates/hir-def/src/resolver.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,15 @@ impl<'db> Resolver<'db> {
696696
&def_map[local_id].scope
697697
}
698698

699+
pub fn item_scopes(&self) -> impl Iterator<Item = &ItemScope> {
700+
self.scopes()
701+
.filter_map(move |scope| match scope {
702+
Scope::BlockScope(m) => Some(&m.def_map[m.module_id].scope),
703+
_ => None,
704+
})
705+
.chain(std::iter::once(&self.module_scope.def_map[self.module_scope.module_id].scope))
706+
}
707+
699708
pub fn krate(&self) -> Crate {
700709
self.module_scope.def_map.krate()
701710
}

crates/hir-expand/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ pub struct MacroCallLoc {
258258
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
259259
pub struct MacroDefId {
260260
pub krate: Crate,
261+
// FIXME: In `hir-expand` we can't refer to `BlockId`.
262+
pub block: Option<salsa::Id>,
261263
pub edition: Edition,
262264
pub kind: MacroDefKind,
263265
pub local_inner: bool,

crates/hir/src/semantics.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ impl<'db> SemanticsImpl<'db> {
411411
let sa = self.analyze_no_infer(macro_call.syntax())?;
412412

413413
let macro_call = InFile::new(sa.file_id, macro_call);
414-
let file_id = sa.expand(self.db, macro_call)?;
414+
let file_id = sa.expansion(self.db, macro_call)?;
415415

416416
let node = self.parse_or_expand(file_id.into());
417417
Some(InFile::new(file_id.into(), node))
@@ -437,7 +437,7 @@ impl<'db> SemanticsImpl<'db> {
437437
let sa = self.analyze_no_infer(macro_call.syntax())?;
438438

439439
let macro_call = InFile::new(sa.file_id, macro_call);
440-
let file_id = sa.expand(self.db, macro_call)?;
440+
let file_id = sa.expansion(self.db, macro_call)?;
441441
let macro_call = self.db.lookup_intern_macro_call(file_id);
442442

443443
let skip = matches!(
@@ -576,7 +576,7 @@ impl<'db> SemanticsImpl<'db> {
576576
) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> {
577577
let analyzer = self.analyze_no_infer(actual_macro_call.syntax())?;
578578
let macro_call = InFile::new(analyzer.file_id, actual_macro_call);
579-
let macro_file = analyzer.expansion(macro_call)?;
579+
let macro_file = analyzer.expansion(self.db, macro_call)?;
580580
hir_expand::db::expand_speculative(
581581
self.db,
582582
macro_file,
@@ -1106,7 +1106,7 @@ impl<'db> SemanticsImpl<'db> {
11061106
false,
11071107
)
11081108
})?
1109-
.expand(self.db, mcall.as_ref())?;
1109+
.expansion(self.db, mcall.as_ref())?;
11101110
m_cache.insert(mcall, it);
11111111
it
11121112
}
@@ -1565,7 +1565,7 @@ impl<'db> SemanticsImpl<'db> {
15651565
let sa = self.analyze(macro_call.syntax())?;
15661566
self.db
15671567
.parse_macro_expansion(
1568-
sa.expand(self.db, self.wrap_node_infile(macro_call.clone()).as_ref())?,
1568+
sa.expansion(self.db, self.wrap_node_infile(macro_call.clone()).as_ref())?,
15691569
)
15701570
.value
15711571
.1

crates/hir/src/source_analyzer.rs

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use hir_def::{
2626
},
2727
hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat},
2828
lang_item::LangItem,
29-
nameres::{MacroSubNs, crate_def_map},
29+
nameres::{MacroSubNs, block_def_map, crate_def_map},
3030
resolver::{HasResolver, Resolver, TypeNs, ValueNs, resolver_for_scope},
3131
type_ref::{Mutability, TypeRefId},
3232
};
@@ -218,8 +218,16 @@ impl<'db> SourceAnalyzer<'db> {
218218
})
219219
}
220220

221-
pub(crate) fn expansion(&self, node: InFile<&ast::MacroCall>) -> Option<MacroCallId> {
222-
self.store_sm()?.expansion(node)
221+
pub(crate) fn expansion(
222+
&self,
223+
db: &dyn HirDatabase,
224+
macro_call: InFile<&ast::MacroCall>,
225+
) -> Option<MacroCallId> {
226+
self.store_sm().and_then(|sm| sm.expansion(macro_call)).or_else(|| {
227+
let ast_id_map = db.ast_id_map(macro_call.file_id);
228+
let call_ast_id = macro_call.with_value(ast_id_map.ast_id(macro_call.value));
229+
self.resolver.item_scopes().find_map(|scope| scope.macro_invoc(call_ast_id))
230+
})
223231
}
224232

225233
fn trait_environment(&self, db: &'db dyn HirDatabase) -> Arc<TraitEnvironment> {
@@ -747,17 +755,16 @@ impl<'db> SourceAnalyzer<'db> {
747755

748756
pub(crate) fn resolve_macro_call(
749757
&self,
750-
db: &'db dyn HirDatabase,
758+
db: &dyn HirDatabase,
751759
macro_call: InFile<&ast::MacroCall>,
752760
) -> Option<Macro> {
753-
let bs = self.store_sm()?;
754-
bs.expansion(macro_call).and_then(|it| {
755-
// FIXME: Block def maps
761+
self.expansion(db, macro_call).and_then(|it| {
756762
let def = it.lookup(db).def;
757-
crate_def_map(db, def.krate)
758-
.macro_def_to_macro_id
759-
.get(&def.kind.erased_ast_id())
760-
.map(|it| (*it).into())
763+
let def_map = match def.block {
764+
Some(block) => block_def_map(db, base_db::salsa::plumbing::FromId::from_id(block)),
765+
None => crate_def_map(db, def.krate),
766+
};
767+
def_map.macro_def_to_macro_id.get(&def.kind.erased_ast_id()).map(|it| (*it).into())
761768
})
762769
}
763770

@@ -1292,18 +1299,6 @@ impl<'db> SourceAnalyzer<'db> {
12921299
.collect()
12931300
}
12941301

1295-
pub(crate) fn expand(
1296-
&self,
1297-
db: &'db dyn HirDatabase,
1298-
macro_call: InFile<&ast::MacroCall>,
1299-
) -> Option<MacroCallId> {
1300-
self.store_sm().and_then(|bs| bs.expansion(macro_call)).or_else(|| {
1301-
self.resolver.item_scope().macro_invoc(
1302-
macro_call.with_value(db.ast_id_map(macro_call.file_id).ast_id(macro_call.value)),
1303-
)
1304-
})
1305-
}
1306-
13071302
pub(crate) fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantId> {
13081303
let infer = self.infer()?;
13091304
let expr_id = self.expr_id(record_lit.into())?;

crates/ide-completion/src/tests/item.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! in [crate::completions::mod_].
55
use expect_test::expect;
66

7-
use crate::tests::{check_edit, check_with_base_items};
7+
use crate::tests::{check, check_edit, check_with_base_items};
88

99
#[test]
1010
fn target_type_or_trait_in_impl_block() {
@@ -308,3 +308,39 @@ fn bar() {
308308
"#]],
309309
);
310310
}
311+
312+
#[test]
313+
fn expression_in_item_macro() {
314+
check(
315+
r#"
316+
fn foo() -> u8 { 0 }
317+
318+
macro_rules! foo {
319+
($expr:expr) => {
320+
const BAR: u8 = $expr;
321+
};
322+
}
323+
324+
foo!(f$0);
325+
"#,
326+
expect![[r#"
327+
ct BAR u8
328+
fn foo() fn() -> u8
329+
ma foo!(…) macro_rules! foo
330+
bt u32 u32
331+
kw const
332+
kw crate::
333+
kw false
334+
kw for
335+
kw if
336+
kw if let
337+
kw loop
338+
kw match
339+
kw self::
340+
kw true
341+
kw unsafe
342+
kw while
343+
kw while let
344+
"#]],
345+
);
346+
}

0 commit comments

Comments
 (0)