From db49ac8734e7d6e26012d56b0786c7d80da82699 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 5 Jul 2022 11:28:47 +0200 Subject: [PATCH] internal: Record all macro definitions in ItemScope --- crates/hir-def/src/child_by_source.rs | 14 ++++++++------ crates/hir-def/src/item_scope.rs | 16 ++++++++-------- crates/hir-def/src/nameres/collector.rs | 13 +++++++++---- crates/hir-def/src/nameres/path_resolution.rs | 4 +++- crates/hir-def/src/resolver.rs | 9 +++++++-- crates/hir/src/lib.rs | 2 +- crates/hir/src/symbols.rs | 12 +++++++----- .../test_data/highlight_macros.html | 7 +++++++ crates/ide/src/syntax_highlighting/tests.rs | 7 +++++++ 9 files changed, 57 insertions(+), 27 deletions(-) diff --git a/crates/hir-def/src/child_by_source.rs b/crates/hir-def/src/child_by_source.rs index b1337ecc242..5b1435e8f44 100644 --- a/crates/hir-def/src/child_by_source.rs +++ b/crates/hir-def/src/child_by_source.rs @@ -102,13 +102,15 @@ fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: Hi res[keys::ATTR_MACRO_CALL].insert(ast_id.to_node(db.upcast()), call_id); }, ); - self.legacy_macros().for_each(|(_, id)| { - if let MacroId::MacroRulesId(id) = id { - let loc = id.lookup(db); - if loc.id.file_id() == file_id { - res[keys::MACRO_RULES].insert(loc.source(db).value, id); + self.legacy_macros().for_each(|(_, ids)| { + ids.iter().for_each(|&id| { + if let MacroId::MacroRulesId(id) = id { + let loc = id.lookup(db); + if loc.id.file_id() == file_id { + res[keys::MACRO_RULES].insert(loc.source(db).value, id); + } } - } + }) }); self.derive_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each( |(ast_id, calls)| { diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index ddccbbfef9c..609943ac244 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -61,7 +61,7 @@ pub struct ItemScope { /// Module scoped macros will be inserted into `items` instead of here. // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will // be all resolved to the last one defined if shadowing happens. - legacy_macros: FxHashMap, + legacy_macros: FxHashMap>, /// The derive macro invocations in this scope. attr_macros: FxHashMap, MacroCallId>, /// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes @@ -129,13 +129,13 @@ pub fn unnamed_consts(&self) -> impl Iterator + '_ { } /// Iterate over all module scoped macros - pub(crate) fn macros<'a>(&'a self) -> impl Iterator + 'a { + pub(crate) fn macros(&self) -> impl Iterator + '_ { self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_))) } /// Iterate over all legacy textual scoped macros visible at the end of the module - pub fn legacy_macros<'a>(&'a self) -> impl Iterator + 'a { - self.legacy_macros.iter().map(|(name, def)| (name, *def)) + pub fn legacy_macros(&self) -> impl Iterator + '_ { + self.legacy_macros.iter().map(|(name, def)| (name, &**def)) } /// Get a name from current module scope, legacy macros are not included @@ -180,8 +180,8 @@ pub(crate) fn declare(&mut self, def: ModuleDefId) { self.declarations.push(def) } - pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option { - self.legacy_macros.get(name).copied() + pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<&[MacroId]> { + self.legacy_macros.get(name).map(|it| &**it) } pub(crate) fn define_impl(&mut self, imp: ImplId) { @@ -193,7 +193,7 @@ pub(crate) fn define_unnamed_const(&mut self, konst: ConstId) { } pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroId) { - self.legacy_macros.insert(name, mac); + self.legacy_macros.entry(name).or_default().push(mac); } pub(crate) fn add_attr_macro_invoc(&mut self, item: AstId, call: MacroCallId) { @@ -322,7 +322,7 @@ pub(crate) fn resolutions<'a>(&'a self) -> impl Iterator, P ) } - pub(crate) fn collect_legacy_macros(&self) -> FxHashMap { + pub(crate) fn collect_legacy_macros(&self) -> FxHashMap> { self.legacy_macros.clone() } diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index ca0cb99b371..02f0d37dd82 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -1809,7 +1809,9 @@ fn push_child_module( let res = modules.alloc(ModuleData::new(origin, vis)); modules[res].parent = Some(self.module_id); for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() { - modules[res].scope.define_legacy_macro(name, mac) + for &mac in &mac { + modules[res].scope.define_legacy_macro(name.clone(), mac); + } } modules[self.module_id].children.insert(name.clone(), res); @@ -2027,7 +2029,8 @@ fn collect_macro_call(&mut self, mac: &MacroCall, container: ItemContainerId) { map[module] .scope .get_legacy_macro(name) - .map(|it| macro_id_to_def_id(self.def_collector.db, it.into())) + .and_then(|it| it.last()) + .map(|&it| macro_id_to_def_id(self.def_collector.db, it.into())) }, ) }) @@ -2080,8 +2083,10 @@ fn collect_macro_call(&mut self, mac: &MacroCall, container: ItemContainerId) { fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) { let macros = self.def_collector.def_map[module_id].scope.collect_legacy_macros(); - for (name, macro_) in macros { - self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_); + for (name, macs) in macros { + macs.last().map(|&mac| { + self.def_collector.define_legacy_macro(self.module_id, name.clone(), mac) + }); } } diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs index cc5fc0a52a1..c579bc9194c 100644 --- a/crates/hir-def/src/nameres/path_resolution.rs +++ b/crates/hir-def/src/nameres/path_resolution.rs @@ -381,7 +381,9 @@ fn resolve_name_in_module( let from_legacy_macro = self[module] .scope .get_legacy_macro(name) - .map_or_else(PerNs::none, |m| PerNs::macros(m.into(), Visibility::Public)); + // FIXME: shadowing + .and_then(|it| it.last()) + .map_or_else(PerNs::none, |&m| PerNs::macros(m.into(), Visibility::Public)); let from_scope = self[module].scope.get(name); let from_builtin = match self.block { Some(_) => { diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index f3dcdcfa4a1..c8d3052102f 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -508,8 +508,13 @@ fn process_names(&self, acc: &mut ScopeNames, db: &dyn DefDatabase) { m.def_map[m.module_id].scope.entries().for_each(|(name, def)| { acc.add_per_ns(name, def); }); - m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, mac)| { - acc.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac)))); + m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, macs)| { + macs.iter().for_each(|&mac| { + acc.add( + name, + ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac))), + ); + }) }); m.def_map.extern_prelude().for_each(|(name, &def)| { acc.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def))); diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index ef17f2a75e1..42b8d3ca202 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -559,7 +559,7 @@ pub fn declarations(self, db: &dyn HirDatabase) -> Vec { pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec { let def_map = self.id.def_map(db.upcast()); let scope = &def_map[self.id.local_id].scope; - scope.legacy_macros().map(|(_, it)| MacroId::from(it).into()).collect() + scope.legacy_macros().flat_map(|(_, it)| it).map(|&it| MacroId::from(it).into()).collect() } pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec { diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index bdb8c7552d3..3b84877dd36 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -176,11 +176,13 @@ fn collect_from_module(&mut self, module_id: ModuleId) { } for (_, id) in scope.legacy_macros() { - if id.module(self.db.upcast()) == module_id { - match id { - MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro), - MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro), - MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro), + for &id in id { + if id.module(self.db.upcast()) == module_id { + match id { + MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro), + MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro), + MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro), + } } } } diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html b/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html index b725c80565e..54d4279525d 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html @@ -68,6 +68,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } } +/// textually shadow previous definition +macro_rules! noop { + ($expr:expr) => { + $expr + } +} + macro_rules! keyword_frag { ($type:ty) => ($type) } diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 83bdca295da..6ba6153178d 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -63,6 +63,13 @@ macro_rules! noop { } } +/// textually shadow previous definition +macro_rules! noop { + ($expr:expr) => { + $expr + } +} + macro_rules! keyword_frag { ($type:ty) => ($type) }