resolve: Pre-compute non-reexport module children

Instead of repeating the same logic by walking HIR during metadata encoding.

The only difference is that we are no longer encoding `macro_rules` items, but we never currently need them as a part of this list.
They can be encoded separately if this need ever arises.

`module_reexports` is also un-querified, because I don't see any reasons to make it a query, only overhead.
This commit is contained in:
Vadim Petrochenkov
2023-04-10 19:07:57 +03:00
parent 9be9b5e09a
commit 7c40a6fb34
16 changed files with 72 additions and 99 deletions

View File

@@ -1,6 +1,7 @@
// Decoding metadata from a single crate's metadata
use crate::creader::{CStore, CrateMetadataRef};
use crate::rmeta::table::IsDefault;
use crate::rmeta::*;
use rustc_ast as ast;
@@ -995,17 +996,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
fn get_mod_child(self, id: DefIndex, sess: &Session) -> ModChild {
let ident = self.item_ident(id, sess);
let kind = self.def_kind(id);
let def_id = self.local_def_id(id);
let res = Res::Def(kind, def_id);
let res = Res::Def(self.def_kind(id), self.local_def_id(id));
let vis = self.get_visibility(id);
let span = self.get_span(id, sess);
let macro_rules = match kind {
DefKind::Macro(..) => self.root.tables.is_macro_rules.get(self, id),
_ => false,
};
ModChild { ident, res, vis, span, macro_rules, reexport_chain: Default::default() }
ModChild { ident, res, vis, span, reexport_chain: Default::default() }
}
/// Iterates over all named children of the given module,
@@ -1029,12 +1024,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} else {
// Iterate over all children.
for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) {
// FIXME: Do not encode RPITITs as a part of this list.
if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() {
yield self.get_mod_child(child_index, sess);
}
}
if let Some(reexports) = self.root.tables.module_reexports.get(self, id) {
let reexports = self.root.tables.module_children_reexports.get(self, id);
if !reexports.is_default() {
for reexport in reexports.decode((self, sess)) {
yield reexport;
}

View File

@@ -43,7 +43,6 @@ use std::borrow::Borrow;
use std::collections::hash_map::Entry;
use std::hash::Hash;
use std::io::{Read, Seek, Write};
use std::iter;
use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};
@@ -456,7 +455,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
fn encode_info_for_items(&mut self) {
self.encode_info_for_mod(CRATE_DEF_ID, self.tcx.hir().root_module());
self.encode_info_for_mod(CRATE_DEF_ID);
// Proc-macro crates only export proc-macro items, which are looked
// up using `proc_macro_data`
@@ -1324,7 +1323,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id));
}
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
self.encode_info_for_adt(def_id);
self.encode_info_for_adt(local_id);
}
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
@@ -1357,7 +1356,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
#[instrument(level = "trace", skip(self))]
fn encode_info_for_adt(&mut self, def_id: DefId) {
fn encode_info_for_adt(&mut self, local_def_id: LocalDefId) {
let def_id = local_def_id.to_def_id();
let tcx = self.tcx;
let adt_def = tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr());
@@ -1366,15 +1366,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.params_in_repr[def_id] <- params_in_repr);
if adt_def.is_enum() {
record_array!(self.tables.children[def_id] <- iter::from_generator(||
for variant in tcx.adt_def(def_id).variants() {
yield variant.def_id.index;
// Encode constructors which take a separate slot in value namespace.
if let Some(ctor_def_id) = variant.ctor_def_id() {
yield ctor_def_id.index;
}
}
));
let module_children = tcx.module_children_non_reexports(local_def_id);
record_array!(self.tables.children[def_id] <-
module_children.iter().map(|def_id| def_id.local_def_index));
} else {
// For non-enum, there is only one variant, and its def_id is the adt's.
debug_assert_eq!(adt_def.variants().len(), 1);
@@ -1406,7 +1400,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
fn encode_info_for_mod(&mut self, local_def_id: LocalDefId, md: &hir::Mod<'_>) {
fn encode_info_for_mod(&mut self, local_def_id: LocalDefId) {
let tcx = self.tcx;
let def_id = local_def_id.to_def_id();
debug!("EncodeContext::encode_info_for_mod({:?})", def_id);
@@ -1420,38 +1414,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encode this here because we don't do it in encode_def_ids.
record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
} else {
record_array!(self.tables.children[def_id] <- iter::from_generator(|| {
for item_id in md.item_ids {
match tcx.hir().item(*item_id).kind {
// Foreign items are planted into their parent modules
// from name resolution point of view.
hir::ItemKind::ForeignMod { items, .. } => {
for foreign_item in items {
yield foreign_item.id.owner_id.def_id.local_def_index;
}
}
// Only encode named non-reexport children, reexports are encoded
// separately and unnamed items are not used by name resolution.
hir::ItemKind::ExternCrate(..) => continue,
hir::ItemKind::Struct(ref vdata, _) => {
yield item_id.owner_id.def_id.local_def_index;
// Encode constructors which take a separate slot in value namespace.
if let Some(ctor_def_id) = vdata.ctor_def_id() {
yield ctor_def_id.local_def_index;
}
}
_ if tcx.def_key(item_id.owner_id.to_def_id()).get_opt_name().is_some() => {
yield item_id.owner_id.def_id.local_def_index;
}
_ => continue,
}
}
}));
let non_reexports = tcx.module_children_non_reexports(local_def_id);
record_array!(self.tables.children[def_id] <-
non_reexports.iter().map(|def_id| def_id.local_def_index));
let reexports = tcx.module_reexports(local_def_id);
if !reexports.is_empty() {
record_array!(self.tables.module_reexports[def_id] <- reexports);
}
record_defaulted_array!(self.tables.module_children_reexports[def_id] <-
tcx.module_children_reexports(local_def_id));
}
}
@@ -1668,8 +1636,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.tables.is_macro_rules.set(def_id.index, macro_def.macro_rules);
record!(self.tables.macro_definition[def_id] <- &*macro_def.body);
}
hir::ItemKind::Mod(ref m) => {
self.encode_info_for_mod(item.owner_id.def_id, m);
hir::ItemKind::Mod(..) => {
self.encode_info_for_mod(item.owner_id.def_id);
}
hir::ItemKind::OpaqueTy(ref opaque) => {
self.encode_explicit_item_bounds(def_id);

View File

@@ -357,6 +357,7 @@ define_tables! {
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
unused_generic_params: Table<DefIndex, UnusedGenericParams>,
module_children_reexports: Table<DefIndex, LazyArray<ModChild>>,
- optional:
attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
@@ -414,7 +415,6 @@ define_tables! {
assoc_container: Table<DefIndex, ty::AssocItemContainer>,
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
proc_macro: Table<DefIndex, MacroKind>,
module_reexports: Table<DefIndex, LazyArray<ModChild>>,
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
doc_link_resolutions: Table<DefIndex, LazyValue<DocLinkResMap>>,