Skip to content
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

rustc_metadata: Optimize and document module children decoding #92086

Merged
merged 3 commits into from
Jan 9, 2022
Merged
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
51 changes: 30 additions & 21 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc_hir::diagnostic_items::DiagnosticItems;
use rustc_hir::lang_items;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::hir::exports::Export;
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use rustc_middle::mir::{self, Body, Promoted};
Expand Down Expand Up @@ -1075,33 +1075,38 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
}

/// Iterates over each child of the given item.
fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), sess: &Session) {
/// Iterates over all named children of the given module,
/// including both proper items and reexports.
/// Module here is understood in name resolution sense - it can be a `mod` item,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overloading of the term Module is definitely confusing....

/// or a crate root, or an enum, or a trait.
fn for_each_module_child(
&self,
id: DefIndex,
mut callback: impl FnMut(ModChild),
sess: &Session,
) {
if let Some(data) = &self.root.proc_macro_data {
/* If we are loading as a proc macro, we want to return the view of this crate
* as a proc macro crate.
*/
// If we are loading as a proc macro, we want to return
// the view of this crate as a proc macro crate.
if id == CRATE_DEF_INDEX {
let macros = data.macros.decode(self);
for def_index in macros {
for def_index in data.macros.decode(self) {
let raw_macro = self.raw_proc_macro(def_index);
let res = Res::Def(
DefKind::Macro(macro_kind(raw_macro)),
self.local_def_id(def_index),
);
let ident = self.item_ident(def_index, sess);
callback(Export { ident, res, vis: ty::Visibility::Public, span: ident.span });
callback(ModChild {
ident,
res,
vis: ty::Visibility::Public,
span: ident.span,
});
}
}
return;
}

// Find the item.
let kind = match self.maybe_kind(id) {
None => return,
Some(kind) => kind,
};

// Iterate over all children.
if let Some(children) = self.root.tables.children.get(self, id) {
for child_index in children.decode((self, sess)) {
Expand All @@ -1117,7 +1122,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let vis = self.get_visibility(child_index);
let span = self.get_span(child_index, sess);

callback(Export { ident, res, vis, span });
callback(ModChild { ident, res, vis, span });

// For non-re-export structs and variants add their constructors to children.
// Re-export lists automatically contain constructors when necessary.
Expand All @@ -1129,7 +1134,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let ctor_res =
Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
let vis = self.get_visibility(ctor_def_id.index);
callback(Export { res: ctor_res, vis, ident, span });
callback(ModChild { ident, res: ctor_res, vis, span });
}
}
DefKind::Variant => {
Expand All @@ -1154,18 +1159,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
vis = ty::Visibility::Restricted(crate_def_id);
}
}
callback(Export { res: ctor_res, ident, vis, span });
callback(ModChild { ident, res: ctor_res, vis, span });
}
_ => {}
}
}
}
}

if let EntryKind::Mod(exports) = kind {
for exp in exports.decode((self, sess)) {
callback(exp);
match self.kind(id) {
EntryKind::Mod(exports) => {
for exp in exports.decode((self, sess)) {
callback(exp);
}
}
EntryKind::Enum(..) | EntryKind::Trait(..) => {}
_ => bug!("`for_each_module_child` is called on a non-module: {:?}", self.def_kind(id)),
}
}

Expand Down
35 changes: 20 additions & 15 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use crate::native_libs;

use rustc_ast as ast;
use rustc_data_structures::stable_map::FxHashMap;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
use rustc_middle::hir::exports::Export;
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::exported_symbols::ExportedSymbol;
use rustc_middle::middle::stability::DeprecationEntry;
use rustc_middle::ty::query::{ExternProviders, Providers};
Expand Down Expand Up @@ -196,9 +196,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
let r = *cdata.dep_kind.lock();
r
}
item_children => {
module_children => {
let mut result = SmallVec::<[_; 8]>::new();
cdata.each_child_of_item(def_id.index, |child| result.push(child), tcx.sess);
cdata.for_each_module_child(def_id.index, |child| result.push(child), tcx.sess);
tcx.arena.alloc_slice(&result)
}
defined_lib_features => { cdata.get_lib_features(tcx) }
Expand Down Expand Up @@ -309,35 +309,40 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
bfs_queue.push_back(DefId { krate: cnum, index: CRATE_DEF_INDEX });
}

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

if let Some(child) = export.res.opt_def_id() {
if export.ident.name == kw::Underscore {
fallback_map.insert(child, parent);
if let Some(def_id) = child.res.opt_def_id() {
if child.ident.name == kw::Underscore {
fallback_map.insert(def_id, parent);
return;
}

match visible_parent_map.entry(child) {
match visible_parent_map.entry(def_id) {
Entry::Occupied(mut entry) => {
// If `child` is defined in crate `cnum`, ensure
// that it is mapped to a parent in `cnum`.
if child.is_local() && entry.get().is_local() {
if def_id.is_local() && entry.get().is_local() {
entry.insert(parent);
}
}
Entry::Vacant(entry) => {
entry.insert(parent);
bfs_queue.push_back(child);
if matches!(
child.res,
Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, _)
) {
bfs_queue.push_back(def_id);
}
}
}
}
};

while let Some(def) = bfs_queue.pop_front() {
for child in tcx.item_children(def).iter() {
for child in tcx.module_children(def).iter() {
add_child(bfs_queue, child, def);
}
}
Expand Down Expand Up @@ -383,9 +388,9 @@ impl CStore {
self.get_crate_data(def.krate).get_visibility(def.index)
}

pub fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec<Export> {
pub fn module_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec<ModChild> {
let mut result = vec![];
self.get_crate_data(def_id.krate).each_child_of_item(
self.get_crate_data(def_id.krate).for_each_module_child(
def_id.index,
|child| result.push(child),
sess,
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1094,7 +1094,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// code uses it). However, we skip encoding anything relating to child
// items - we encode information about proc-macros later on.
let reexports = if !self.is_proc_macro {
match tcx.module_exports(local_def_id) {
match tcx.module_reexports(local_def_id) {
Some(exports) => self.lazy(exports),
_ => Lazy::empty(),
}
Expand All @@ -1104,7 +1104,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {

record!(self.tables.kind[def_id] <- EntryKind::Mod(reexports));
if self.is_proc_macro {
record!(self.tables.children[def_id] <- &[]);
// 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 {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_hir::def_id::{DefId, DefIndex, DefPathHash, StableCrateId};
use rustc_hir::definitions::DefKey;
use rustc_hir::lang_items;
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
use rustc_middle::hir::exports::Export;
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use rustc_middle::mir;
use rustc_middle::thir;
Expand Down Expand Up @@ -350,7 +350,7 @@ enum EntryKind {
Union(Lazy<VariantData>, ReprOptions),
Fn(Lazy<FnData>),
ForeignFn(Lazy<FnData>),
Mod(Lazy<[Export]>),
Mod(Lazy<[ModChild]>),
MacroDef(Lazy<MacroDef>),
ProcMacro(MacroKind),
Closure,
Expand Down
28 changes: 0 additions & 28 deletions compiler/rustc_middle/src/hir/exports.rs

This file was deleted.

1 change: 0 additions & 1 deletion compiler/rustc_middle/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html

pub mod exports;
pub mod map;
pub mod place;

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ pub mod dep_graph;
pub mod hir;
pub mod infer;
pub mod lint;
pub mod metadata;
pub mod middle;
pub mod mir;
pub mod thir;
Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_middle/src/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::ty;

use rustc_hir::def::Res;
use rustc_macros::HashStable;
use rustc_span::symbol::Ident;
use rustc_span::Span;

/// This structure is supposed to keep enough data to re-create `NameBinding`s for other crates
/// during name resolution. Right now the bindings are not recreated entirely precisely so we may
/// need to add more data in the future to correctly support macros 2.0, for example.
/// 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(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
pub struct ModChild {
/// Name of the item.
pub ident: Ident,
/// Resolution result corresponding to the item.
/// Local variables cannot be exported, so this `Res` doesn't need the ID parameter.
pub res: Res<!>,
/// Visibility of the item.
pub vis: ty::Visibility,
/// Span of the item.
pub span: Span,
}
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1300,8 +1300,8 @@ rustc_queries! {
desc { "traits in scope at a block" }
}

query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export]> {
desc { |tcx| "looking up items exported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
query module_reexports(def_id: LocalDefId) -> Option<&'tcx [ModChild]> {
desc { |tcx| "looking up reexports of module `{}`", tcx.def_path_str(def_id.to_def_id()) }
}

query impl_defaultness(def_id: DefId) -> hir::Defaultness {
Expand Down Expand Up @@ -1528,8 +1528,8 @@ rustc_queries! {
desc { "fetching what a crate is named" }
separate_provide_extern
}
query item_children(def_id: DefId) -> &'tcx [Export] {
desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) }
query module_children(def_id: DefId) -> &'tcx [ModChild] {
desc { |tcx| "collecting child items of module `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
}
query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2820,7 +2820,8 @@ pub fn provide(providers: &mut ty::query::Providers) {
providers.in_scope_traits_map =
|tcx, id| tcx.hir_crate(()).owners[id].as_ref().map(|owner_info| &owner_info.trait_map);
providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
providers.module_exports = |tcx, id| tcx.resolutions(()).export_map.get(&id).map(|v| &v[..]);
providers.module_reexports =
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
providers.crate_name = |tcx, id| {
assert_eq!(id, LOCAL_CRATE);
tcx.crate_name
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use assoc::*;
pub use generics::*;
pub use vtable::*;

use crate::hir::exports::ExportMap;
use crate::metadata::ModChild;
use crate::mir::{Body, GeneratorLayout};
use crate::traits::{self, Reveal};
use crate::ty;
Expand Down Expand Up @@ -126,7 +126,7 @@ pub struct ResolverOutputs {
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
pub export_map: ExportMap,
pub reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
/// Extern prelude entries. The value is `true` if the entry was introduced
/// via `extern crate` item and not `--extern` option or compiler built-in.
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ pub trait PrettyPrinter<'tcx>:
// that's public and whose identifier isn't `_`.
let reexport = self
.tcx()
.item_children(visible_parent)
.module_children(visible_parent)
.iter()
.filter(|child| child.res.opt_def_id() == Some(def_id))
.find(|child| child.vis.is_public() && child.ident.name != kw::Underscore)
Expand Down Expand Up @@ -2602,7 +2602,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N

// Iterate external crate defs but be mindful about visibility
while let Some(def) = queue.pop() {
for child in tcx.item_children(def).iter() {
for child in tcx.module_children(def).iter() {
if !child.vis.is_public() {
continue;
}
Expand All @@ -2615,7 +2615,9 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
collect_fn(&child.ident, ns, def_id);
}

if seen_defs.insert(def_id) {
if matches!(defkind, DefKind::Mod | DefKind::Enum | DefKind::Trait)
&& seen_defs.insert(def_id)
{
queue.push(def_id);
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/query.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::dep_graph;
use crate::hir::exports::Export;
use crate::infer::canonical::{self, Canonical};
use crate::lint::LintLevelMap;
use crate::metadata::ModChild;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use crate::middle::lib_features::LibFeatures;
Expand Down
Loading