From bdca349573c00542635848a16276272fb0c1acc9 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 1 Jun 2023 15:27:05 +0200 Subject: [PATCH] Arc DefMap::data so the block def maps can share it --- crates/hir-def/src/nameres.rs | 51 ++++++++-------- crates/hir-def/src/nameres/collector.rs | 77 +++++++++++++------------ 2 files changed, 68 insertions(+), 60 deletions(-) diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 86ba905203..e900de88dd 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -116,10 +116,10 @@ pub struct DefMap { diagnostics: Vec, // FIXME: Arc this so we can share it with block def maps - data: CrateData, + data: Arc, } -#[derive(Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] struct CrateData { /// Side table for resolving derive helpers. exported_derives: FxHashMap>, @@ -141,6 +141,28 @@ struct CrateData { edition: Edition, recursion_limit: Option, } +impl CrateData { + fn shrink_to_fit(&mut self) { + let Self { + exported_derives, + fn_proc_macro_mapping, + registered_attrs, + registered_tools, + unstable_features, + proc_macro_loading_error: _, + rustc_coherence_is_core: _, + no_core: _, + no_std: _, + edition: _, + recursion_limit: _, + } = self; + exported_derives.shrink_to_fit(); + fn_proc_macro_mapping.shrink_to_fit(); + registered_attrs.shrink_to_fit(); + registered_tools.shrink_to_fit(); + unstable_features.shrink_to_fit(); + } +} /// For `DefMap`s computed for a block expression, this stores its location in the parent map. #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -287,6 +309,7 @@ impl DefMap { ModuleData::new(ModuleOrigin::BlockExpr { block: block.ast_id }, visibility); let mut def_map = DefMap::empty(krate, parent_map.data.edition, module_data); + def_map.data = parent_map.data.clone(); def_map.block = Some(BlockInfo { block: block_id, parent: BlockRelativeModuleId { @@ -314,7 +337,7 @@ impl DefMap { prelude: None, modules, diagnostics: Vec::new(), - data: CrateData { + data: Arc::new(CrateData { recursion_limit: None, exported_derives: FxHashMap::default(), fn_proc_macro_mapping: FxHashMap::default(), @@ -326,7 +349,7 @@ impl DefMap { no_core: false, no_std: false, edition, - }, + }), } } @@ -558,32 +581,14 @@ impl DefMap { block: _, krate: _, prelude: _, - data: - CrateData { - exported_derives, - fn_proc_macro_mapping, - registered_attrs, - registered_tools, - unstable_features, - proc_macro_loading_error: _, - rustc_coherence_is_core: _, - no_core: _, - no_std: _, - edition: _, - recursion_limit: _, - }, + data: _, } = self; extern_prelude.shrink_to_fit(); macro_use_prelude.shrink_to_fit(); - exported_derives.shrink_to_fit(); diagnostics.shrink_to_fit(); modules.shrink_to_fit(); - registered_attrs.shrink_to_fit(); - registered_tools.shrink_to_fit(); - fn_proc_macro_mapping.shrink_to_fit(); derive_helpers_in_scope.shrink_to_fit(); - unstable_features.shrink_to_fit(); for (_, module) in modules.iter_mut() { module.children.shrink_to_fit(); module.scope.shrink_to_fit(); diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 53e1273341..9e35c47d4f 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -86,7 +86,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T let proc_macros = if is_proc_macro { match db.proc_macros().get(&def_map.krate) { Some(Ok(proc_macros)) => { - proc_macros + Ok(proc_macros .iter() .enumerate() .map(|(idx, it)| { @@ -95,20 +95,13 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T tt::Ident { text: it.name.clone(), span: tt::TokenId::unspecified() }; (name.as_name(), ProcMacroExpander::new(base_db::ProcMacroId(idx as u32))) }) - .collect() - } - Some(Err(e)) => { - def_map.data.proc_macro_loading_error = Some(e.clone().into_boxed_str()); - Vec::new() - } - None => { - def_map.data.proc_macro_loading_error = - Some("No proc-macros present for crate".to_owned().into_boxed_str()); - Vec::new() + .collect()) } + Some(Err(e)) => Err(e.clone().into_boxed_str()), + None => Err("No proc-macros present for crate".to_owned().into_boxed_str()), } } else { - vec![] + Ok(vec![]) }; let mut collector = DefCollector { @@ -263,7 +256,7 @@ struct DefCollector<'a> { /// built by the build system, and is the list of proc. macros we can actually expand. It is /// empty when proc. macro support is disabled (in which case we still do name resolution for /// them). - proc_macros: Vec<(Name, ProcMacroExpander)>, + proc_macros: Result, Box>, is_proc_macro: bool, from_glob_import: PerNsGlobImports, /// If we fail to resolve an attribute on a `ModItem`, we fall back to ignoring the attribute. @@ -290,6 +283,11 @@ impl DefCollector<'_> { let module_id = DefMap::ROOT; let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate); + let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap(); + + if let Err(e) = &self.proc_macros { + crate_data.proc_macro_loading_error = Some(e.clone()); + } // Process other crate-level attributes. for attr in &*attrs { @@ -306,7 +304,7 @@ impl DefCollector<'_> { if *attr_name == hir_expand::name![recursion_limit] { if let Some(limit) = attr.string_value() { if let Ok(limit) = limit.parse() { - self.def_map.data.recursion_limit = Some(limit); + crate_data.recursion_limit = Some(limit); } } continue; @@ -320,17 +318,17 @@ impl DefCollector<'_> { } if *attr_name == hir_expand::name![no_core] { - self.def_map.data.no_core = true; + crate_data.no_core = true; continue; } if *attr_name == hir_expand::name![no_std] { - self.def_map.data.no_std = true; + crate_data.no_std = true; continue; } if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") { - self.def_map.data.rustc_coherence_is_core = true; + crate_data.rustc_coherence_is_core = true; continue; } @@ -344,7 +342,7 @@ impl DefCollector<'_> { [name] => Some(name.to_smol_str()), _ => None, }); - self.def_map.data.unstable_features.extend(features); + crate_data.unstable_features.extend(features); } let attr_is_register_like = *attr_name == hir_expand::name![register_attr] @@ -359,14 +357,15 @@ impl DefCollector<'_> { }; if *attr_name == hir_expand::name![register_attr] { - self.def_map.data.registered_attrs.push(registered_name.to_smol_str()); + crate_data.registered_attrs.push(registered_name.to_smol_str()); cov_mark::hit!(register_attr); } else { - self.def_map.data.registered_tools.push(registered_name.to_smol_str()); + crate_data.registered_tools.push(registered_name.to_smol_str()); cov_mark::hit!(register_tool); } } + crate_data.shrink_to_fit(); self.inject_prelude(); ModCollector { @@ -598,24 +597,29 @@ impl DefCollector<'_> { def: ProcMacroDef, id: ItemTreeId, fn_id: FunctionId, - module_id: ModuleId, ) { + if self.def_map.block.is_some() { + return; + } + let crate_root = self.def_map.module_id(DefMap::ROOT); + let kind = def.kind.to_basedb_kind(); - let (expander, kind) = match self.proc_macros.iter().find(|(n, _)| n == &def.name) { - Some(&(_, expander)) => (expander, kind), - None => (ProcMacroExpander::dummy(), kind), - }; + let (expander, kind) = + match self.proc_macros.as_ref().map(|it| it.iter().find(|(n, _)| n == &def.name)) { + Ok(Some(&(_, expander))) => (expander, kind), + _ => (ProcMacroExpander::dummy(), kind), + }; let proc_macro_id = - ProcMacroLoc { container: module_id, id, expander, kind }.intern(self.db); + ProcMacroLoc { container: crate_root, id, expander, kind }.intern(self.db); self.define_proc_macro(def.name.clone(), proc_macro_id); + let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap(); if let ProcMacroKind::CustomDerive { helpers } = def.kind { - self.def_map - .data + crate_data .exported_derives .insert(macro_id_to_def_id(self.db, proc_macro_id.into()), helpers); } - self.def_map.data.fn_proc_macro_mapping.insert(fn_id, proc_macro_id); + crate_data.fn_proc_macro_mapping.insert(fn_id, proc_macro_id); } /// Define a macro with `macro_rules`. @@ -1639,12 +1643,10 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); if self.def_collector.is_proc_macro && self.module_id == DefMap::ROOT { if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) { - let crate_root = def_map.module_id(DefMap::ROOT); self.def_collector.export_proc_macro( proc_macro, ItemTreeId::new(self.tree_id, id), fn_id, - crate_root, ); } } @@ -2165,11 +2167,12 @@ impl ModCollector<'_, '_> { &self.item_tree[mac.visibility], ); if let Some(helpers) = helpers_opt { - self.def_collector - .def_map - .data - .exported_derives - .insert(macro_id_to_def_id(self.def_collector.db, macro_id.into()), helpers); + if self.def_collector.def_map.block.is_none() { + Arc::get_mut(&mut self.def_collector.def_map.data) + .unwrap() + .exported_derives + .insert(macro_id_to_def_id(self.def_collector.db, macro_id.into()), helpers); + } } } @@ -2277,7 +2280,7 @@ mod tests { unresolved_macros: Vec::new(), mod_dirs: FxHashMap::default(), cfg_options: &CfgOptions::default(), - proc_macros: Default::default(), + proc_macros: Ok(vec![]), from_glob_import: Default::default(), skip_attrs: Default::default(), is_proc_macro: false,