Skip to content

Commit e19ca1d

Browse files
committed
Auto merge of #92086 - petrochenkov:modchild, r=jackh726
rustc_metadata: Optimize and document module children decoding The first commit limits the item in the `item_children`/`each_child_of_item` query to modules (in name resolution sense) and adds a corresponding assertion. The `associated_item_def_ids` query collecting children of traits and impls specifically now uses a simplified implementation not decoding unnecessary data instead of `each_child_of_item`, this gives a nice performance improvement. The second commit does some renaming that clarifies the terminology used for all items in a module vs `use` items only.
2 parents 02fe61b + 4b03fd9 commit e19ca1d

File tree

27 files changed

+137
-118
lines changed

27 files changed

+137
-118
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+30-21
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
2121
use rustc_hir::diagnostic_items::DiagnosticItems;
2222
use rustc_hir::lang_items;
2323
use rustc_index::vec::{Idx, IndexVec};
24-
use rustc_middle::hir::exports::Export;
24+
use rustc_middle::metadata::ModChild;
2525
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
2626
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
2727
use rustc_middle::mir::{self, Body, Promoted};
@@ -1074,33 +1074,38 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10741074
}
10751075
}
10761076

1077-
/// Iterates over each child of the given item.
1078-
fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), sess: &Session) {
1077+
/// Iterates over all named children of the given module,
1078+
/// including both proper items and reexports.
1079+
/// Module here is understood in name resolution sense - it can be a `mod` item,
1080+
/// or a crate root, or an enum, or a trait.
1081+
fn for_each_module_child(
1082+
&self,
1083+
id: DefIndex,
1084+
mut callback: impl FnMut(ModChild),
1085+
sess: &Session,
1086+
) {
10791087
if let Some(data) = &self.root.proc_macro_data {
1080-
/* If we are loading as a proc macro, we want to return the view of this crate
1081-
* as a proc macro crate.
1082-
*/
1088+
// If we are loading as a proc macro, we want to return
1089+
// the view of this crate as a proc macro crate.
10831090
if id == CRATE_DEF_INDEX {
1084-
let macros = data.macros.decode(self);
1085-
for def_index in macros {
1091+
for def_index in data.macros.decode(self) {
10861092
let raw_macro = self.raw_proc_macro(def_index);
10871093
let res = Res::Def(
10881094
DefKind::Macro(macro_kind(raw_macro)),
10891095
self.local_def_id(def_index),
10901096
);
10911097
let ident = self.item_ident(def_index, sess);
1092-
callback(Export { ident, res, vis: ty::Visibility::Public, span: ident.span });
1098+
callback(ModChild {
1099+
ident,
1100+
res,
1101+
vis: ty::Visibility::Public,
1102+
span: ident.span,
1103+
});
10931104
}
10941105
}
10951106
return;
10961107
}
10971108

1098-
// Find the item.
1099-
let kind = match self.maybe_kind(id) {
1100-
None => return,
1101-
Some(kind) => kind,
1102-
};
1103-
11041109
// Iterate over all children.
11051110
if let Some(children) = self.root.tables.children.get(self, id) {
11061111
for child_index in children.decode((self, sess)) {
@@ -1116,7 +1121,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11161121
let vis = self.get_visibility(child_index);
11171122
let span = self.get_span(child_index, sess);
11181123

1119-
callback(Export { ident, res, vis, span });
1124+
callback(ModChild { ident, res, vis, span });
11201125

11211126
// For non-re-export structs and variants add their constructors to children.
11221127
// Re-export lists automatically contain constructors when necessary.
@@ -1128,7 +1133,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11281133
let ctor_res =
11291134
Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
11301135
let vis = self.get_visibility(ctor_def_id.index);
1131-
callback(Export { res: ctor_res, vis, ident, span });
1136+
callback(ModChild { ident, res: ctor_res, vis, span });
11321137
}
11331138
}
11341139
DefKind::Variant => {
@@ -1153,18 +1158,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11531158
vis = ty::Visibility::Restricted(crate_def_id);
11541159
}
11551160
}
1156-
callback(Export { res: ctor_res, ident, vis, span });
1161+
callback(ModChild { ident, res: ctor_res, vis, span });
11571162
}
11581163
_ => {}
11591164
}
11601165
}
11611166
}
11621167
}
11631168

1164-
if let EntryKind::Mod(exports) = kind {
1165-
for exp in exports.decode((self, sess)) {
1166-
callback(exp);
1169+
match self.kind(id) {
1170+
EntryKind::Mod(exports) => {
1171+
for exp in exports.decode((self, sess)) {
1172+
callback(exp);
1173+
}
11671174
}
1175+
EntryKind::Enum(..) | EntryKind::Trait(..) => {}
1176+
_ => bug!("`for_each_module_child` is called on a non-module: {:?}", self.def_kind(id)),
11681177
}
11691178
}
11701179

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+20-15
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use crate::native_libs;
44

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

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

317-
if let Some(child) = export.res.opt_def_id() {
318-
if export.ident.name == kw::Underscore {
319-
fallback_map.insert(child, parent);
317+
if let Some(def_id) = child.res.opt_def_id() {
318+
if child.ident.name == kw::Underscore {
319+
fallback_map.insert(def_id, parent);
320320
return;
321321
}
322322

323-
match visible_parent_map.entry(child) {
323+
match visible_parent_map.entry(def_id) {
324324
Entry::Occupied(mut entry) => {
325325
// If `child` is defined in crate `cnum`, ensure
326326
// that it is mapped to a parent in `cnum`.
327-
if child.is_local() && entry.get().is_local() {
327+
if def_id.is_local() && entry.get().is_local() {
328328
entry.insert(parent);
329329
}
330330
}
331331
Entry::Vacant(entry) => {
332332
entry.insert(parent);
333-
bfs_queue.push_back(child);
333+
if matches!(
334+
child.res,
335+
Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, _)
336+
) {
337+
bfs_queue.push_back(def_id);
338+
}
334339
}
335340
}
336341
}
337342
};
338343

339344
while let Some(def) = bfs_queue.pop_front() {
340-
for child in tcx.item_children(def).iter() {
345+
for child in tcx.module_children(def).iter() {
341346
add_child(bfs_queue, child, def);
342347
}
343348
}
@@ -383,9 +388,9 @@ impl CStore {
383388
self.get_crate_data(def.krate).get_visibility(def.index)
384389
}
385390

386-
pub fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec<Export> {
391+
pub fn module_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec<ModChild> {
387392
let mut result = vec![];
388-
self.get_crate_data(def_id.krate).each_child_of_item(
393+
self.get_crate_data(def_id.krate).for_each_module_child(
389394
def_id.index,
390395
|child| result.push(child),
391396
sess,

compiler/rustc_metadata/src/rmeta/encoder.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
10941094
// code uses it). However, we skip encoding anything relating to child
10951095
// items - we encode information about proc-macros later on.
10961096
let reexports = if !self.is_proc_macro {
1097-
match tcx.module_exports(local_def_id) {
1097+
match tcx.module_reexports(local_def_id) {
10981098
Some(exports) => self.lazy(exports),
10991099
_ => Lazy::empty(),
11001100
}
@@ -1104,7 +1104,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
11041104

11051105
record!(self.tables.kind[def_id] <- EntryKind::Mod(reexports));
11061106
if self.is_proc_macro {
1107-
record!(self.tables.children[def_id] <- &[]);
11081107
// Encode this here because we don't do it in encode_def_ids.
11091108
record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
11101109
} else {

compiler/rustc_metadata/src/rmeta/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_hir::def_id::{DefId, DefIndex, DefPathHash, StableCrateId};
1212
use rustc_hir::definitions::DefKey;
1313
use rustc_hir::lang_items;
1414
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
15-
use rustc_middle::hir::exports::Export;
15+
use rustc_middle::metadata::ModChild;
1616
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
1717
use rustc_middle::mir;
1818
use rustc_middle::thir;
@@ -336,7 +336,7 @@ enum EntryKind {
336336
Union(Lazy<VariantData>, ReprOptions),
337337
Fn(Lazy<FnData>),
338338
ForeignFn(Lazy<FnData>),
339-
Mod(Lazy<[Export]>),
339+
Mod(Lazy<[ModChild]>),
340340
MacroDef(Lazy<MacroDef>),
341341
ProcMacro(MacroKind),
342342
Closure,

compiler/rustc_middle/src/hir/exports.rs

-28
This file was deleted.

compiler/rustc_middle/src/hir/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//!
33
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
44
5-
pub mod exports;
65
pub mod map;
76
pub mod place;
87

compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ pub mod dep_graph;
8484
pub mod hir;
8585
pub mod infer;
8686
pub mod lint;
87+
pub mod metadata;
8788
pub mod middle;
8889
pub mod mir;
8990
pub mod thir;

compiler/rustc_middle/src/metadata.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use crate::ty;
2+
3+
use rustc_hir::def::Res;
4+
use rustc_macros::HashStable;
5+
use rustc_span::symbol::Ident;
6+
use rustc_span::Span;
7+
8+
/// This structure is supposed to keep enough data to re-create `NameBinding`s for other crates
9+
/// during name resolution. Right now the bindings are not recreated entirely precisely so we may
10+
/// need to add more data in the future to correctly support macros 2.0, for example.
11+
/// Module child can be either a proper item or a reexport (including private imports).
12+
/// In case of reexport all the fields describe the reexport item itself, not what it refers to.
13+
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
14+
pub struct ModChild {
15+
/// Name of the item.
16+
pub ident: Ident,
17+
/// Resolution result corresponding to the item.
18+
/// Local variables cannot be exported, so this `Res` doesn't need the ID parameter.
19+
pub res: Res<!>,
20+
/// Visibility of the item.
21+
pub vis: ty::Visibility,
22+
/// Span of the item.
23+
pub span: Span,
24+
}

compiler/rustc_middle/src/query/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1300,8 +1300,8 @@ rustc_queries! {
13001300
desc { "traits in scope at a block" }
13011301
}
13021302

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

13071307
query impl_defaultness(def_id: DefId) -> hir::Defaultness {
@@ -1528,8 +1528,8 @@ rustc_queries! {
15281528
desc { "fetching what a crate is named" }
15291529
separate_provide_extern
15301530
}
1531-
query item_children(def_id: DefId) -> &'tcx [Export] {
1532-
desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) }
1531+
query module_children(def_id: DefId) -> &'tcx [ModChild] {
1532+
desc { |tcx| "collecting child items of module `{}`", tcx.def_path_str(def_id) }
15331533
separate_provide_extern
15341534
}
15351535
query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {

compiler/rustc_middle/src/ty/context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2820,7 +2820,8 @@ pub fn provide(providers: &mut ty::query::Providers) {
28202820
providers.in_scope_traits_map =
28212821
|tcx, id| tcx.hir_crate(()).owners[id].as_ref().map(|owner_info| &owner_info.trait_map);
28222822
providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
2823-
providers.module_exports = |tcx, id| tcx.resolutions(()).export_map.get(&id).map(|v| &v[..]);
2823+
providers.module_reexports =
2824+
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
28242825
providers.crate_name = |tcx, id| {
28252826
assert_eq!(id, LOCAL_CRATE);
28262827
tcx.crate_name

compiler/rustc_middle/src/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub use assoc::*;
1919
pub use generics::*;
2020
pub use vtable::*;
2121

22-
use crate::hir::exports::ExportMap;
22+
use crate::metadata::ModChild;
2323
use crate::mir::{Body, GeneratorLayout};
2424
use crate::traits::{self, Reveal};
2525
use crate::ty;
@@ -126,7 +126,7 @@ pub struct ResolverOutputs {
126126
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
127127
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
128128
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
129-
pub export_map: ExportMap,
129+
pub reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
130130
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
131131
/// Extern prelude entries. The value is `true` if the entry was introduced
132132
/// via `extern crate` item and not `--extern` option or compiler built-in.

compiler/rustc_middle/src/ty/print/pretty.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ pub trait PrettyPrinter<'tcx>:
458458
// that's public and whose identifier isn't `_`.
459459
let reexport = self
460460
.tcx()
461-
.item_children(visible_parent)
461+
.module_children(visible_parent)
462462
.iter()
463463
.filter(|child| child.res.opt_def_id() == Some(def_id))
464464
.find(|child| child.vis.is_public() && child.ident.name != kw::Underscore)
@@ -2602,7 +2602,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
26022602

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

2618-
if seen_defs.insert(def_id) {
2618+
if matches!(defkind, DefKind::Mod | DefKind::Enum | DefKind::Trait)
2619+
&& seen_defs.insert(def_id)
2620+
{
26192621
queue.push(def_id);
26202622
}
26212623
}

compiler/rustc_middle/src/ty/query.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::dep_graph;
2-
use crate::hir::exports::Export;
32
use crate::infer::canonical::{self, Canonical};
43
use crate::lint::LintLevelMap;
4+
use crate::metadata::ModChild;
55
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
66
use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
77
use crate::middle::lib_features::LibFeatures;

0 commit comments

Comments
 (0)