Skip to content

[WIP] One more attempt to optimize module_children #110855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2266,13 +2266,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (candidates, globs): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|trait_did| {
if let Some(parent_did) = parent_map.get(trait_did) {
// If the item is re-exported as `_`, we should suggest a glob-import instead.
if *parent_did != self.tcx.parent(*trait_did)
&& self
.tcx
let tcx = self.tcx;
if *parent_did != tcx.parent(*trait_did)
&& tcx
.module_children(*parent_did)
.iter()
.filter(|child| child.res.opt_def_id() == Some(*trait_did))
.all(|child| child.ident.name == kw::Underscore)
.filter(|child| child.opt_def_id() == Some(*trait_did))
.all(|child| child.name(tcx) == kw::Underscore)
{
return false;
}
Expand Down
32 changes: 14 additions & 18 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}
use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc_hir::diagnostic_items::DiagnosticItems;
use rustc_index::{Idx, IndexVec};
use rustc_middle::metadata::ModChild;
use rustc_middle::metadata::{ModChild, ModChildData};
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use rustc_middle::ty::codec::TyDecoder;
Expand Down Expand Up @@ -904,15 +904,17 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let variants = if let ty::AdtKind::Enum = adt_kind {
self.root
.tables
.module_children_non_reexports
.module_children
.get(self, item_id)
.expect("variants are not encoded for an enum")
.decode(self)
.filter_map(|index| {
let kind = self.def_kind(index);
.filter_map(|child| {
let ModChild::Def(def_id) = child else { bug!() };
assert_eq!(def_id.krate, self.cnum);
let kind = self.def_kind(def_id.index);
match kind {
DefKind::Ctor(..) => None,
_ => Some(self.get_variant(&kind, index, did)),
_ => Some(self.get_variant(&kind, def_id.index, did)),
}
})
.collect()
Expand Down Expand Up @@ -988,12 +990,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
DiagnosticItems { id_to_name, name_to_id }
}

fn get_mod_child(self, id: DefIndex, sess: &Session) -> ModChild {
fn get_mod_child_data(self, id: DefIndex, sess: &Session) -> ModChildData {
let ident = self.item_ident(id, sess);
let res = Res::Def(self.def_kind(id), self.local_def_id(id));
let vis = self.get_visibility(id);

ModChild { ident, res, vis, reexport_chain: Default::default() }
ModChildData { ident, res, vis, reexport_chain: Default::default() }
}

/// Iterates over all named children of the given module,
Expand All @@ -1011,21 +1013,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
// the view of this crate as a proc macro crate.
if id == CRATE_DEF_INDEX {
for child_index in data.macros.decode(self) {
yield self.get_mod_child(child_index, sess);
yield ModChild::Def(self.local_def_id(child_index));
}
}
} else {
// Iterate over all children.
let non_reexports = self.root.tables.module_children_non_reexports.get(self, id);
for child_index in non_reexports.unwrap().decode(self) {
yield self.get_mod_child(child_index, sess);
}

let reexports = self.root.tables.module_children_reexports.get(self, id);
if !reexports.is_default() {
for reexport in reexports.decode((self, sess)) {
yield reexport;
}
for child in
self.root.tables.module_children.get(self, id).unwrap().decode((self, sess))
{
yield child;
}
}
})
Expand Down
16 changes: 10 additions & 6 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::metadata::ModChild;
use rustc_middle::metadata::{ModChild, ModChildData};
use rustc_middle::middle::exported_symbols::ExportedSymbol;
use rustc_middle::middle::stability::DeprecationEntry;
use rustc_middle::query::LocalCrate;
Expand Down Expand Up @@ -441,12 +441,12 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
}

let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &ModChild, parent: DefId| {
if !child.vis.is_public() {
if !child.vis(tcx).is_public() {
return;
}

if let Some(def_id) = child.res.opt_def_id() {
if child.ident.name == kw::Underscore {
if let Some(def_id) = child.opt_def_id() {
if child.name(tcx) == kw::Underscore {
fallback_map.push((def_id, parent));
return;
}
Expand All @@ -467,7 +467,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
Entry::Vacant(entry) => {
entry.insert(parent);
if matches!(
child.res,
child.res(tcx),
Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, _)
) {
bfs_queue.push_back(def_id);
Expand All @@ -478,7 +478,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
};

while let Some(def) = bfs_queue.pop_front() {
for child in tcx.module_children(def).iter() {
for child in tcx.module_children(def) {
add_child(bfs_queue, child, def);
}
}
Expand Down Expand Up @@ -512,6 +512,10 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
}

impl CStore {
pub fn mod_child_data_untracked(&self, def_id: DefId, sess: &Session) -> ModChildData {
self.get_crate_data(def_id.krate).get_mod_child_data(def_id.index, sess)
}

pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> {
self.get_crate_data(def.krate).get_ctor(def.index)
}
Expand Down
18 changes: 6 additions & 12 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1364,9 +1364,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.params_in_repr[def_id] <- params_in_repr);

if adt_def.is_enum() {
let module_children = tcx.module_children_non_reexports(local_def_id);
record_array!(self.tables.module_children_non_reexports[def_id] <-
module_children.iter().map(|def_id| def_id.local_def_index));
record_array!(self.tables.module_children[def_id] <-
tcx.module_children_local(local_def_id));
} 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);
Expand Down Expand Up @@ -1412,12 +1411,8 @@ 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 {
let non_reexports = tcx.module_children_non_reexports(local_def_id);
record_array!(self.tables.module_children_non_reexports[def_id] <-
non_reexports.iter().map(|def_id| def_id.local_def_index));

record_defaulted_array!(self.tables.module_children_reexports[def_id] <-
tcx.module_children_reexports(local_def_id));
record_array!(self.tables.module_children[def_id] <-
tcx.module_children_local(local_def_id));
}
}

Expand Down Expand Up @@ -1676,9 +1671,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
hir::ItemKind::Trait(..) => {
record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));

let module_children = tcx.module_children_non_reexports(item.owner_id.def_id);
record_array!(self.tables.module_children_non_reexports[def_id] <-
module_children.iter().map(|def_id| def_id.local_def_index));
record_array!(self.tables.module_children[def_id] <-
tcx.module_children_local(item.owner_id.def_id));

let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
record_associated_item_def_ids(self, associated_item_def_ids);
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,11 +357,10 @@ 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>>,
module_children_non_reexports: Table<DefIndex, LazyArray<DefIndex>>,
module_children: Table<DefIndex, LazyArray<ModChild>>,
associated_item_or_field_def_ids: Table<DefIndex, LazyArray<DefIndex>>,
opt_def_kind: Table<DefIndex, DefKind>,
visibility: Table<DefIndex, LazyValue<ty::Visibility<DefIndex>>>,
Expand Down
57 changes: 55 additions & 2 deletions compiler/rustc_middle/src/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::ty;

use crate::ty::TyCtxt;
use rustc_hir::def::Res;
use rustc_macros::HashStable;
use rustc_span::def_id::DefId;
use rustc_span::symbol::Ident;
use rustc_span::symbol::{Ident, Symbol};
use smallvec::SmallVec;

/// A simplified version of `ImportKind` from resolve.
Expand Down Expand Up @@ -32,7 +33,7 @@ impl Reexport {
/// Module child can be either a proper item or a reexport (including private imports).
/// In case of reexport all the fields describe the reexport item itself, not what it refers to.
#[derive(Debug, TyEncodable, TyDecodable, HashStable)]
pub struct ModChild {
pub struct ModChildData {
/// Name of the item.
pub ident: Ident,
/// Resolution result corresponding to the item.
Expand All @@ -44,3 +45,55 @@ pub struct ModChild {
/// Empty if the module child is a proper item.
pub reexport_chain: SmallVec<[Reexport; 2]>,
}

#[derive(Debug, TyEncodable, TyDecodable, HashStable)]
pub enum ModChild {
Def(DefId),
Reexport(ModChildData),
}

impl ModChild {
pub fn res(&self, tcx: TyCtxt<'_>) -> Res<!> {
match self {
ModChild::Def(def_id) => Res::Def(tcx.def_kind(*def_id), *def_id),
ModChild::Reexport(child) => child.res,
}
}

pub fn opt_def_id(&self) -> Option<DefId> {
match self {
ModChild::Def(def_id) => Some(*def_id),
ModChild::Reexport(child) => child.res.opt_def_id(),
}
}

pub fn vis(&self, tcx: TyCtxt<'_>) -> ty::Visibility<DefId> {
match self {
ModChild::Def(def_id) => tcx.visibility(*def_id),
ModChild::Reexport(child) => child.vis,
}
}

pub fn name(&self, tcx: TyCtxt<'_>) -> Symbol {
match self {
ModChild::Def(def_id) => tcx.item_name(*def_id),
ModChild::Reexport(child) => child.ident.name,
}
}

// FIXME: `opt_item_ident` is buggy and doesn't decode hygiene correctly,
// figure out what happens.
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
match self {
ModChild::Def(def_id) => tcx.opt_item_ident(*def_id).unwrap(),
ModChild::Reexport(child) => child.ident,
}
}

pub fn reexport_chain(&self) -> &[Reexport] {
match self {
ModChild::Def(_) => &[],
ModChild::Reexport(child) => &child.reexport_chain,
}
}
}
22 changes: 2 additions & 20 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2437,26 +2437,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

/// Named module children from all items except `use` and `extern crate` imports.
///
/// In addition to regular items this list also includes struct or variant constructors, and
/// items inside `extern {}` blocks because all of them introduce names into parent module.
/// For non-reexported children every such name is associated with a separate `DefId`.
///
/// Module here is understood in name resolution sense - it can be a `mod` item,
/// or a crate root, or an enum, or a trait.
pub fn module_children_non_reexports(self, def_id: LocalDefId) -> &'tcx [LocalDefId] {
self.resolutions(()).module_children_non_reexports.get(&def_id).map_or(&[], |v| &v[..])
}

/// Named module children from `use` and `extern crate` imports.
///
/// Reexported names are not associated with individual `DefId`s,
/// e.g. a glob import can introduce a lot of names, all with the same `DefId`.
/// That's why the list needs to contain `ModChild` structures describing all the names
/// individually instead of `DefId`s.
pub fn module_children_reexports(self, def_id: LocalDefId) -> &'tcx [ModChild] {
self.resolutions(()).module_children_reexports.get(&def_id).map_or(&[], |v| &v[..])
pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
}
}

Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,7 @@ pub struct ResolverGlobalCtxt {
pub effective_visibilities: EffectiveVisibilities,
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
pub module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>,
pub module_children_reexports: LocalDefIdMap<Vec<ModChild>>,
pub module_children: LocalDefIdMap<Vec<ModChild>>,
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
pub main_def: Option<MainDefinition>,
pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
Expand Down
Loading