From 3484b5a11607d09f88e73f956f7037386696791b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 16 Jun 2023 18:41:06 +0200 Subject: [PATCH] internal: Do not allocate unnecessarily when importing macros from parent modules --- crates/hir-def/src/item_scope.rs | 4 --- crates/hir-def/src/nameres/collector.rs | 44 +++++++++++++++++++++---- lib/la-arena/src/lib.rs | 6 ++++ 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index 3ed321d189..2001fb29a9 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -334,10 +334,6 @@ impl ItemScope { ) } - pub(crate) fn collect_legacy_macros(&self) -> FxHashMap> { - self.legacy_macros.clone() - } - /// Marks everything that is not a procedural macro as private to `this_module`. pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) { self.types diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 97481ea7df..62fb3c7882 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -3,7 +3,7 @@ //! `DefCollector::collect` contains the fixed-point iteration loop which //! resolves imports and expands macros. -use std::{iter, mem}; +use std::{cmp::Ordering, iter, mem}; use base_db::{CrateId, Dependency, Edition, FileId}; use cfg::{CfgExpr, CfgOptions}; @@ -1928,9 +1928,13 @@ impl ModCollector<'_, '_> { let modules = &mut def_map.modules; 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() { - for &mac in &mac { - modules[res].scope.define_legacy_macro(name.clone(), mac); + + if let Some((target, source)) = Self::borrow_modules(modules.as_mut(), res, self.module_id) + { + for (name, macs) in source.scope.legacy_macros() { + for &mac in macs { + target.scope.define_legacy_macro(name.clone(), mac); + } } } modules[self.module_id].children.insert(name.clone(), res); @@ -2226,14 +2230,40 @@ impl ModCollector<'_, '_> { } 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, macs) in macros { + let Some((source, target)) = Self::borrow_modules(self.def_collector.def_map.modules.as_mut(), module_id, self.module_id) else { + return + }; + + for (name, macs) in source.scope.legacy_macros() { macs.last().map(|&mac| { - self.def_collector.define_legacy_macro(self.module_id, name.clone(), mac) + target.scope.define_legacy_macro(name.clone(), mac); }); } } + /// Mutably borrow two modules at once, retu + fn borrow_modules( + modules: &mut [ModuleData], + a: LocalModuleId, + b: LocalModuleId, + ) -> Option<(&mut ModuleData, &mut ModuleData)> { + let a = a.into_raw().into_u32() as usize; + let b = b.into_raw().into_u32() as usize; + + let (a, b) = match a.cmp(&b) { + Ordering::Equal => return None, + Ordering::Less => { + let (prefix, b) = modules.split_at_mut(b); + (&mut prefix[a], &mut b[0]) + } + Ordering::Greater => { + let (prefix, a) = modules.split_at_mut(a); + (&mut a[0], &mut prefix[b]) + } + }; + Some((a, b)) + } + fn is_cfg_enabled(&self, cfg: &CfgExpr) -> bool { self.def_collector.cfg_options.check(cfg) != Some(false) } diff --git a/lib/la-arena/src/lib.rs b/lib/la-arena/src/lib.rs index 5107f29439..f39c3a3e4c 100644 --- a/lib/la-arena/src/lib.rs +++ b/lib/la-arena/src/lib.rs @@ -451,6 +451,12 @@ impl Arena { } } +impl AsMut<[T]> for Arena { + fn as_mut(&mut self) -> &mut [T] { + self.data.as_mut() + } +} + impl Default for Arena { fn default() -> Arena { Arena { data: Vec::new() }