Move extern prelude into CrateData

This commit is contained in:
Lukas Wirth 2023-06-01 15:49:05 +02:00
parent bdca349573
commit 1e6406e223
3 changed files with 43 additions and 31 deletions

View File

@ -103,8 +103,6 @@ pub struct DefMap {
/// but that attribute is nightly and when used in a block, it affects resolution globally /// but that attribute is nightly and when used in a block, it affects resolution globally
/// so we aren't handling this correctly anyways). /// so we aren't handling this correctly anyways).
prelude: Option<ModuleId>, prelude: Option<ModuleId>,
/// The extern prelude is only populated for non-block DefMaps
extern_prelude: FxHashMap<Name, ModuleId>,
/// `macro_use` prelude that contains macros from `#[macro_use]`'d external crates. Note that /// `macro_use` prelude that contains macros from `#[macro_use]`'d external crates. Note that
/// this contains all kinds of macro, not just `macro_rules!` macro. /// this contains all kinds of macro, not just `macro_rules!` macro.
macro_use_prelude: FxHashMap<Name, MacroId>, macro_use_prelude: FxHashMap<Name, MacroId>,
@ -115,12 +113,13 @@ pub struct DefMap {
diagnostics: Vec<DefDiagnostic>, diagnostics: Vec<DefDiagnostic>,
// FIXME: Arc this so we can share it with block def maps
data: Arc<CrateData>, data: Arc<CrateData>,
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
struct CrateData { struct CrateData {
extern_prelude: FxHashMap<Name, ModuleId>,
/// Side table for resolving derive helpers. /// Side table for resolving derive helpers.
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>, exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
fn_proc_macro_mapping: FxHashMap<FunctionId, ProcMacroId>, fn_proc_macro_mapping: FxHashMap<FunctionId, ProcMacroId>,
@ -141,9 +140,11 @@ struct CrateData {
edition: Edition, edition: Edition,
recursion_limit: Option<u32>, recursion_limit: Option<u32>,
} }
impl CrateData { impl CrateData {
fn shrink_to_fit(&mut self) { fn shrink_to_fit(&mut self) {
let Self { let Self {
extern_prelude,
exported_derives, exported_derives,
fn_proc_macro_mapping, fn_proc_macro_mapping,
registered_attrs, registered_attrs,
@ -156,6 +157,7 @@ fn shrink_to_fit(&mut self) {
edition: _, edition: _,
recursion_limit: _, recursion_limit: _,
} = self; } = self;
extern_prelude.shrink_to_fit();
exported_derives.shrink_to_fit(); exported_derives.shrink_to_fit();
fn_proc_macro_mapping.shrink_to_fit(); fn_proc_macro_mapping.shrink_to_fit();
registered_attrs.shrink_to_fit(); registered_attrs.shrink_to_fit();
@ -181,7 +183,11 @@ struct BlockRelativeModuleId {
impl BlockRelativeModuleId { impl BlockRelativeModuleId {
fn def_map(self, db: &dyn DefDatabase, krate: CrateId) -> Arc<DefMap> { fn def_map(self, db: &dyn DefDatabase, krate: CrateId) -> Arc<DefMap> {
ModuleId { krate, block: self.block, local_id: self.local_id }.def_map(db) self.into_module(krate).def_map(db)
}
fn into_module(self, krate: CrateId) -> ModuleId {
ModuleId { krate, block: self.block, local_id: self.local_id }
} }
} }
@ -330,15 +336,14 @@ fn empty(krate: CrateId, edition: Edition, module_data: ModuleData) -> DefMap {
DefMap { DefMap {
_c: Count::new(), _c: Count::new(),
block: None, block: None,
modules,
krate, krate,
extern_prelude: FxHashMap::default(), prelude: None,
macro_use_prelude: FxHashMap::default(), macro_use_prelude: FxHashMap::default(),
derive_helpers_in_scope: FxHashMap::default(), derive_helpers_in_scope: FxHashMap::default(),
prelude: None,
modules,
diagnostics: Vec::new(), diagnostics: Vec::new(),
data: Arc::new(CrateData { data: Arc::new(CrateData {
recursion_limit: None, extern_prelude: FxHashMap::default(),
exported_derives: FxHashMap::default(), exported_derives: FxHashMap::default(),
fn_proc_macro_mapping: FxHashMap::default(), fn_proc_macro_mapping: FxHashMap::default(),
proc_macro_loading_error: None, proc_macro_loading_error: None,
@ -349,6 +354,7 @@ fn empty(krate: CrateId, edition: Edition, module_data: ModuleData) -> DefMap {
no_core: false, no_core: false,
no_std: false, no_std: false,
edition, edition,
recursion_limit: None,
}), }),
} }
} }
@ -412,7 +418,7 @@ pub(crate) fn prelude(&self) -> Option<ModuleId> {
} }
pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ { pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ {
self.extern_prelude.iter().map(|(name, def)| (name, *def)) self.data.extern_prelude.iter().map(|(name, def)| (name, *def))
} }
pub(crate) fn macro_use_prelude(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ { pub(crate) fn macro_use_prelude(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ {
@ -573,7 +579,6 @@ fn shrink_to_fit(&mut self) {
// Exhaustive match to require handling new fields. // Exhaustive match to require handling new fields.
let Self { let Self {
_c: _, _c: _,
extern_prelude,
macro_use_prelude, macro_use_prelude,
diagnostics, diagnostics,
modules, modules,
@ -584,7 +589,6 @@ fn shrink_to_fit(&mut self) {
data: _, data: _,
} = self; } = self;
extern_prelude.shrink_to_fit();
macro_use_prelude.shrink_to_fit(); macro_use_prelude.shrink_to_fit();
diagnostics.shrink_to_fit(); diagnostics.shrink_to_fit();
modules.shrink_to_fit(); modules.shrink_to_fit();

View File

@ -5,7 +5,7 @@
use std::{iter, mem}; use std::{iter, mem};
use base_db::{CrateId, Edition, FileId}; use base_db::{CrateId, Dependency, Edition, FileId};
use cfg::{CfgExpr, CfgOptions}; use cfg::{CfgExpr, CfgOptions};
use either::Either; use either::Either;
use hir_expand::{ use hir_expand::{
@ -62,7 +62,7 @@
static EXPANSION_DEPTH_LIMIT: Limit = Limit::new(128); static EXPANSION_DEPTH_LIMIT: Limit = Limit::new(128);
static FIXED_POINT_LIMIT: Limit = Limit::new(8192); static FIXED_POINT_LIMIT: Limit = Limit::new(8192);
pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: TreeId) -> DefMap { pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeId) -> DefMap {
let crate_graph = db.crate_graph(); let crate_graph = db.crate_graph();
let mut deps = FxHashMap::default(); let mut deps = FxHashMap::default();
@ -70,14 +70,8 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
let krate = &crate_graph[def_map.krate]; let krate = &crate_graph[def_map.krate];
for dep in &krate.dependencies { for dep in &krate.dependencies {
tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
let dep_def_map = db.crate_def_map(dep.crate_id);
let dep_root = dep_def_map.module_id(DefMap::ROOT);
deps.insert(dep.as_name(), dep_root); deps.insert(dep.as_name(), dep.clone());
if dep.is_prelude() && !tree_id.is_block() {
def_map.extern_prelude.insert(dep.as_name(), dep_root);
}
} }
let cfg_options = &krate.cfg_options; let cfg_options = &krate.cfg_options;
@ -245,7 +239,7 @@ enum MacroDirectiveKind {
struct DefCollector<'a> { struct DefCollector<'a> {
db: &'a dyn DefDatabase, db: &'a dyn DefDatabase,
def_map: DefMap, def_map: DefMap,
deps: FxHashMap<Name, ModuleId>, deps: FxHashMap<Name, Dependency>,
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>, glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
unresolved_imports: Vec<ImportDirective>, unresolved_imports: Vec<ImportDirective>,
indeterminate_imports: Vec<ImportDirective>, indeterminate_imports: Vec<ImportDirective>,
@ -289,6 +283,15 @@ fn seed_with_top_level(&mut self) {
crate_data.proc_macro_loading_error = Some(e.clone()); crate_data.proc_macro_loading_error = Some(e.clone());
} }
for (name, dep) in &self.deps {
if dep.is_prelude() {
crate_data.extern_prelude.insert(
name.clone(),
ModuleId { krate: dep.crate_id, block: None, local_id: DefMap::ROOT },
);
}
}
// Process other crate-level attributes. // Process other crate-level attributes.
for attr in &*attrs { for attr in &*attrs {
if let Some(cfg) = attr.cfg() { if let Some(cfg) = attr.cfg() {
@ -832,15 +835,16 @@ fn resolve_extern_crate(&self, name: &Name) -> Option<ModuleId> {
if *name == name!(self) { if *name == name!(self) {
cov_mark::hit!(extern_crate_self_as); cov_mark::hit!(extern_crate_self_as);
let root = match self.def_map.block { let root = match self.def_map.block {
Some(_) => { Some(_) => self.def_map.crate_root(self.db),
let def_map = self.def_map.crate_root(self.db).def_map(self.db);
def_map.module_id(DefMap::ROOT)
}
None => self.def_map.module_id(DefMap::ROOT), None => self.def_map.module_id(DefMap::ROOT),
}; };
Some(root) Some(root)
} else { } else {
self.deps.get(name).copied() self.deps.get(name).map(|dep| ModuleId {
krate: dep.crate_id,
block: None,
local_id: DefMap::ROOT,
})
} }
} }
@ -883,7 +887,10 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
{ {
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name) if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
{ {
self.def_map.extern_prelude.insert(name.clone(), def); Arc::get_mut(&mut self.def_map.data)
.unwrap()
.extern_prelude
.insert(name.clone(), def);
} }
} }

View File

@ -80,8 +80,8 @@ pub(super) fn resolve_name_in_extern_prelude(
name: &Name, name: &Name,
) -> Option<ModuleId> { ) -> Option<ModuleId> {
match self.block { match self.block {
Some(_) => self.crate_root(db).def_map(db).extern_prelude.get(name).copied(), Some(_) => self.crate_root(db).def_map(db).data.extern_prelude.get(name).copied(),
None => self.extern_prelude.get(name).copied(), None => self.data.extern_prelude.get(name).copied(),
} }
} }
@ -304,7 +304,7 @@ pub(super) fn resolve_path_fp_with_macro_single(
Some((_, segment)) => segment, Some((_, segment)) => segment,
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
}; };
if let Some(&def) = self.extern_prelude.get(segment) { if let Some(&def) = self.data.extern_prelude.get(segment) {
tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def); tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def);
PerNs::types(def.into(), Visibility::Public) PerNs::types(def.into(), Visibility::Public)
} else { } else {
@ -453,7 +453,8 @@ fn resolve_name_in_module(
}; };
let extern_prelude = || { let extern_prelude = || {
self.extern_prelude self.data
.extern_prelude
.get(name) .get(name)
.map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public)) .map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public))
}; };