Skip to content

Commit 766c5f0

Browse files
committedJul 16, 2022
Auto merge of rust-lang#12689 - Veykril:macro-rec, r=Veykril
internal: Record all macro definitions in ItemScope Fixes rust-lang/rust-analyzer#12100 Doesn't resolve the shadowing issues though, fixing those is gonna be really tricky I believe unless we can come up with a nice scheme to "order" item tree items (using syntax ranges and file ids would be a pain and also a bad idea since that'll require us to potentially reparse files in collection).
2 parents 01d2517 + db49ac8 commit 766c5f0

File tree

9 files changed

+57
-27
lines changed

9 files changed

+57
-27
lines changed
 

‎crates/hir-def/src/child_by_source.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,15 @@ impl ChildBySource for ItemScope {
102102
res[keys::ATTR_MACRO_CALL].insert(ast_id.to_node(db.upcast()), call_id);
103103
},
104104
);
105-
self.legacy_macros().for_each(|(_, id)| {
106-
if let MacroId::MacroRulesId(id) = id {
107-
let loc = id.lookup(db);
108-
if loc.id.file_id() == file_id {
109-
res[keys::MACRO_RULES].insert(loc.source(db).value, id);
105+
self.legacy_macros().for_each(|(_, ids)| {
106+
ids.iter().for_each(|&id| {
107+
if let MacroId::MacroRulesId(id) = id {
108+
let loc = id.lookup(db);
109+
if loc.id.file_id() == file_id {
110+
res[keys::MACRO_RULES].insert(loc.source(db).value, id);
111+
}
110112
}
111-
}
113+
})
112114
});
113115
self.derive_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each(
114116
|(ast_id, calls)| {

‎crates/hir-def/src/item_scope.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub struct ItemScope {
6161
/// Module scoped macros will be inserted into `items` instead of here.
6262
// FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
6363
// be all resolved to the last one defined if shadowing happens.
64-
legacy_macros: FxHashMap<Name, MacroId>,
64+
legacy_macros: FxHashMap<Name, SmallVec<[MacroId; 1]>>,
6565
/// The derive macro invocations in this scope.
6666
attr_macros: FxHashMap<AstId<ast::Item>, MacroCallId>,
6767
/// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes
@@ -129,13 +129,13 @@ impl ItemScope {
129129
}
130130

131131
/// Iterate over all module scoped macros
132-
pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroId)> + 'a {
132+
pub(crate) fn macros(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ {
133133
self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_)))
134134
}
135135

136136
/// Iterate over all legacy textual scoped macros visible at the end of the module
137-
pub fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroId)> + 'a {
138-
self.legacy_macros.iter().map(|(name, def)| (name, *def))
137+
pub fn legacy_macros(&self) -> impl Iterator<Item = (&Name, &[MacroId])> + '_ {
138+
self.legacy_macros.iter().map(|(name, def)| (name, &**def))
139139
}
140140

141141
/// Get a name from current module scope, legacy macros are not included
@@ -180,8 +180,8 @@ impl ItemScope {
180180
self.declarations.push(def)
181181
}
182182

183-
pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<MacroId> {
184-
self.legacy_macros.get(name).copied()
183+
pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<&[MacroId]> {
184+
self.legacy_macros.get(name).map(|it| &**it)
185185
}
186186

187187
pub(crate) fn define_impl(&mut self, imp: ImplId) {
@@ -193,7 +193,7 @@ impl ItemScope {
193193
}
194194

195195
pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroId) {
196-
self.legacy_macros.insert(name, mac);
196+
self.legacy_macros.entry(name).or_default().push(mac);
197197
}
198198

199199
pub(crate) fn add_attr_macro_invoc(&mut self, item: AstId<ast::Item>, call: MacroCallId) {
@@ -320,7 +320,7 @@ impl ItemScope {
320320
)
321321
}
322322

323-
pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroId> {
323+
pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, SmallVec<[MacroId; 1]>> {
324324
self.legacy_macros.clone()
325325
}
326326

‎crates/hir-def/src/nameres/collector.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -1806,7 +1806,9 @@ impl ModCollector<'_, '_> {
18061806
let res = modules.alloc(ModuleData::new(origin, vis));
18071807
modules[res].parent = Some(self.module_id);
18081808
for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() {
1809-
modules[res].scope.define_legacy_macro(name, mac)
1809+
for &mac in &mac {
1810+
modules[res].scope.define_legacy_macro(name.clone(), mac);
1811+
}
18101812
}
18111813
modules[self.module_id].children.insert(name.clone(), res);
18121814

@@ -2024,7 +2026,8 @@ impl ModCollector<'_, '_> {
20242026
map[module]
20252027
.scope
20262028
.get_legacy_macro(name)
2027-
.map(|it| macro_id_to_def_id(self.def_collector.db, it.into()))
2029+
.and_then(|it| it.last())
2030+
.map(|&it| macro_id_to_def_id(self.def_collector.db, it.into()))
20282031
},
20292032
)
20302033
})
@@ -2077,8 +2080,10 @@ impl ModCollector<'_, '_> {
20772080

20782081
fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
20792082
let macros = self.def_collector.def_map[module_id].scope.collect_legacy_macros();
2080-
for (name, macro_) in macros {
2081-
self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_);
2083+
for (name, macs) in macros {
2084+
macs.last().map(|&mac| {
2085+
self.def_collector.define_legacy_macro(self.module_id, name.clone(), mac)
2086+
});
20822087
}
20832088
}
20842089

‎crates/hir-def/src/nameres/path_resolution.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,9 @@ impl DefMap {
381381
let from_legacy_macro = self[module]
382382
.scope
383383
.get_legacy_macro(name)
384-
.map_or_else(PerNs::none, |m| PerNs::macros(m.into(), Visibility::Public));
384+
// FIXME: shadowing
385+
.and_then(|it| it.last())
386+
.map_or_else(PerNs::none, |&m| PerNs::macros(m.into(), Visibility::Public));
385387
let from_scope = self[module].scope.get(name);
386388
let from_builtin = match self.block {
387389
Some(_) => {

‎crates/hir-def/src/resolver.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,13 @@ impl Scope {
508508
m.def_map[m.module_id].scope.entries().for_each(|(name, def)| {
509509
acc.add_per_ns(name, def);
510510
});
511-
m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, mac)| {
512-
acc.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac))));
511+
m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, macs)| {
512+
macs.iter().for_each(|&mac| {
513+
acc.add(
514+
name,
515+
ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac))),
516+
);
517+
})
513518
});
514519
m.def_map.extern_prelude().for_each(|(name, &def)| {
515520
acc.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));

‎crates/hir/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ impl Module {
560560
pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec<Macro> {
561561
let def_map = self.id.def_map(db.upcast());
562562
let scope = &def_map[self.id.local_id].scope;
563-
scope.legacy_macros().map(|(_, it)| MacroId::from(it).into()).collect()
563+
scope.legacy_macros().flat_map(|(_, it)| it).map(|&it| MacroId::from(it).into()).collect()
564564
}
565565

566566
pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> {

‎crates/hir/src/symbols.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,13 @@ impl<'a> SymbolCollector<'a> {
176176
}
177177

178178
for (_, id) in scope.legacy_macros() {
179-
if id.module(self.db.upcast()) == module_id {
180-
match id {
181-
MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro),
182-
MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro),
183-
MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro),
179+
for &id in id {
180+
if id.module(self.db.upcast()) == module_id {
181+
match id {
182+
MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro),
183+
MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro),
184+
MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro),
185+
}
184186
}
185187
}
186188
}

‎crates/ide/src/syntax_highlighting/test_data/highlight_macros.html

+7
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@
6868
<span class="brace">}</span>
6969
<span class="brace">}</span>
7070

71+
<span class="comment documentation">/// textually shadow previous definition</span>
72+
<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">noop</span> <span class="brace">{</span>
73+
<span class="parenthesis">(</span><span class="punctuation">$</span>expr<span class="colon">:</span>expr<span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span>
74+
<span class="punctuation">$</span>expr
75+
<span class="brace">}</span>
76+
<span class="brace">}</span>
77+
7178
<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">keyword_frag</span> <span class="brace">{</span>
7279
<span class="parenthesis">(</span><span class="punctuation">$</span>type<span class="colon">:</span>ty<span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="punctuation">$</span>type<span class="parenthesis">)</span>
7380
<span class="brace">}</span>

‎crates/ide/src/syntax_highlighting/tests.rs

+7
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ macro_rules! noop {
6363
}
6464
}
6565
66+
/// textually shadow previous definition
67+
macro_rules! noop {
68+
($expr:expr) => {
69+
$expr
70+
}
71+
}
72+
6673
macro_rules! keyword_frag {
6774
($type:ty) => ($type)
6875
}

0 commit comments

Comments
 (0)
Please sign in to comment.