Skip to content

Commit 7a78c4f

Browse files
committed
Auto merge of rust-lang#110160 - petrochenkov:notagain2, r=cjgillot
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.
2 parents 367661b + 7c40a6f commit 7a78c4f

File tree

16 files changed

+72
-99
lines changed

16 files changed

+72
-99
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Decoding metadata from a single crate's metadata
22

33
use crate::creader::{CStore, CrateMetadataRef};
4+
use crate::rmeta::table::IsDefault;
45
use crate::rmeta::*;
56

67
use rustc_ast as ast;
@@ -995,17 +996,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
995996

996997
fn get_mod_child(self, id: DefIndex, sess: &Session) -> ModChild {
997998
let ident = self.item_ident(id, sess);
998-
let kind = self.def_kind(id);
999-
let def_id = self.local_def_id(id);
1000-
let res = Res::Def(kind, def_id);
999+
let res = Res::Def(self.def_kind(id), self.local_def_id(id));
10011000
let vis = self.get_visibility(id);
10021001
let span = self.get_span(id, sess);
1003-
let macro_rules = match kind {
1004-
DefKind::Macro(..) => self.root.tables.is_macro_rules.get(self, id),
1005-
_ => false,
1006-
};
10071002

1008-
ModChild { ident, res, vis, span, macro_rules, reexport_chain: Default::default() }
1003+
ModChild { ident, res, vis, span, reexport_chain: Default::default() }
10091004
}
10101005

10111006
/// Iterates over all named children of the given module,
@@ -1029,12 +1024,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10291024
} else {
10301025
// Iterate over all children.
10311026
for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) {
1027+
// FIXME: Do not encode RPITITs as a part of this list.
10321028
if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() {
10331029
yield self.get_mod_child(child_index, sess);
10341030
}
10351031
}
10361032

1037-
if let Some(reexports) = self.root.tables.module_reexports.get(self, id) {
1033+
let reexports = self.root.tables.module_children_reexports.get(self, id);
1034+
if !reexports.is_default() {
10381035
for reexport in reexports.decode((self, sess)) {
10391036
yield reexport;
10401037
}

compiler/rustc_metadata/src/rmeta/encoder.rs

+15-47
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ use std::borrow::Borrow;
4343
use std::collections::hash_map::Entry;
4444
use std::hash::Hash;
4545
use std::io::{Read, Seek, Write};
46-
use std::iter;
4746
use std::num::NonZeroUsize;
4847
use std::path::{Path, PathBuf};
4948

@@ -456,7 +455,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
456455
}
457456

458457
fn encode_info_for_items(&mut self) {
459-
self.encode_info_for_mod(CRATE_DEF_ID, self.tcx.hir().root_module());
458+
self.encode_info_for_mod(CRATE_DEF_ID);
460459

461460
// Proc-macro crates only export proc-macro items, which are looked
462461
// up using `proc_macro_data`
@@ -1324,7 +1323,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13241323
record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id));
13251324
}
13261325
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
1327-
self.encode_info_for_adt(def_id);
1326+
self.encode_info_for_adt(local_id);
13281327
}
13291328
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
13301329
&& 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> {
13571356
}
13581357

13591358
#[instrument(level = "trace", skip(self))]
1360-
fn encode_info_for_adt(&mut self, def_id: DefId) {
1359+
fn encode_info_for_adt(&mut self, local_def_id: LocalDefId) {
1360+
let def_id = local_def_id.to_def_id();
13611361
let tcx = self.tcx;
13621362
let adt_def = tcx.adt_def(def_id);
13631363
record!(self.tables.repr_options[def_id] <- adt_def.repr());
@@ -1366,15 +1366,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13661366
record!(self.tables.params_in_repr[def_id] <- params_in_repr);
13671367

13681368
if adt_def.is_enum() {
1369-
record_array!(self.tables.children[def_id] <- iter::from_generator(||
1370-
for variant in tcx.adt_def(def_id).variants() {
1371-
yield variant.def_id.index;
1372-
// Encode constructors which take a separate slot in value namespace.
1373-
if let Some(ctor_def_id) = variant.ctor_def_id() {
1374-
yield ctor_def_id.index;
1375-
}
1376-
}
1377-
));
1369+
let module_children = tcx.module_children_non_reexports(local_def_id);
1370+
record_array!(self.tables.children[def_id] <-
1371+
module_children.iter().map(|def_id| def_id.local_def_index));
13781372
} else {
13791373
// For non-enum, there is only one variant, and its def_id is the adt's.
13801374
debug_assert_eq!(adt_def.variants().len(), 1);
@@ -1406,7 +1400,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14061400
}
14071401
}
14081402

1409-
fn encode_info_for_mod(&mut self, local_def_id: LocalDefId, md: &hir::Mod<'_>) {
1403+
fn encode_info_for_mod(&mut self, local_def_id: LocalDefId) {
14101404
let tcx = self.tcx;
14111405
let def_id = local_def_id.to_def_id();
14121406
debug!("EncodeContext::encode_info_for_mod({:?})", def_id);
@@ -1420,38 +1414,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14201414
// Encode this here because we don't do it in encode_def_ids.
14211415
record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
14221416
} else {
1423-
record_array!(self.tables.children[def_id] <- iter::from_generator(|| {
1424-
for item_id in md.item_ids {
1425-
match tcx.hir().item(*item_id).kind {
1426-
// Foreign items are planted into their parent modules
1427-
// from name resolution point of view.
1428-
hir::ItemKind::ForeignMod { items, .. } => {
1429-
for foreign_item in items {
1430-
yield foreign_item.id.owner_id.def_id.local_def_index;
1431-
}
1432-
}
1433-
// Only encode named non-reexport children, reexports are encoded
1434-
// separately and unnamed items are not used by name resolution.
1435-
hir::ItemKind::ExternCrate(..) => continue,
1436-
hir::ItemKind::Struct(ref vdata, _) => {
1437-
yield item_id.owner_id.def_id.local_def_index;
1438-
// Encode constructors which take a separate slot in value namespace.
1439-
if let Some(ctor_def_id) = vdata.ctor_def_id() {
1440-
yield ctor_def_id.local_def_index;
1441-
}
1442-
}
1443-
_ if tcx.def_key(item_id.owner_id.to_def_id()).get_opt_name().is_some() => {
1444-
yield item_id.owner_id.def_id.local_def_index;
1445-
}
1446-
_ => continue,
1447-
}
1448-
}
1449-
}));
1417+
let non_reexports = tcx.module_children_non_reexports(local_def_id);
1418+
record_array!(self.tables.children[def_id] <-
1419+
non_reexports.iter().map(|def_id| def_id.local_def_index));
14501420

1451-
let reexports = tcx.module_reexports(local_def_id);
1452-
if !reexports.is_empty() {
1453-
record_array!(self.tables.module_reexports[def_id] <- reexports);
1454-
}
1421+
record_defaulted_array!(self.tables.module_children_reexports[def_id] <-
1422+
tcx.module_children_reexports(local_def_id));
14551423
}
14561424
}
14571425

@@ -1668,8 +1636,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
16681636
self.tables.is_macro_rules.set(def_id.index, macro_def.macro_rules);
16691637
record!(self.tables.macro_definition[def_id] <- &*macro_def.body);
16701638
}
1671-
hir::ItemKind::Mod(ref m) => {
1672-
self.encode_info_for_mod(item.owner_id.def_id, m);
1639+
hir::ItemKind::Mod(..) => {
1640+
self.encode_info_for_mod(item.owner_id.def_id);
16731641
}
16741642
hir::ItemKind::OpaqueTy(ref opaque) => {
16751643
self.encode_explicit_item_bounds(def_id);

compiler/rustc_metadata/src/rmeta/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ define_tables! {
357357
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
358358
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
359359
unused_generic_params: Table<DefIndex, UnusedGenericParams>,
360+
module_children_reexports: Table<DefIndex, LazyArray<ModChild>>,
360361

361362
- optional:
362363
attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
@@ -414,7 +415,6 @@ define_tables! {
414415
assoc_container: Table<DefIndex, ty::AssocItemContainer>,
415416
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
416417
proc_macro: Table<DefIndex, MacroKind>,
417-
module_reexports: Table<DefIndex, LazyArray<ModChild>>,
418418
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
419419
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
420420
doc_link_resolutions: Table<DefIndex, LazyValue<DocLinkResMap>>,

compiler/rustc_middle/src/metadata.rs

-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ pub struct ModChild {
4343
pub vis: ty::Visibility<DefId>,
4444
/// Span of the item.
4545
pub span: Span,
46-
/// A proper `macro_rules` item (not a reexport).
47-
pub macro_rules: bool,
4846
/// Reexport chain linking this module child to its original reexported item.
4947
/// Empty if the module child is a proper item.
5048
pub reexport_chain: SmallVec<[Reexport; 2]>,

compiler/rustc_middle/src/query/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1516,10 +1516,6 @@ rustc_queries! {
15161516
desc { "getting traits in scope at a block" }
15171517
}
15181518

1519-
query module_reexports(def_id: LocalDefId) -> &'tcx [ModChild] {
1520-
desc { |tcx| "looking up reexports of module `{}`", tcx.def_path_str(def_id.to_def_id()) }
1521-
}
1522-
15231519
query impl_defaultness(def_id: DefId) -> hir::Defaultness {
15241520
desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) }
15251521
cache_on_disk_if { def_id.is_local() }

compiler/rustc_middle/src/ty/context.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::arena::Arena;
88
use crate::dep_graph::{DepGraph, DepKindStruct};
99
use crate::infer::canonical::CanonicalVarInfo;
1010
use crate::lint::struct_lint_level;
11+
use crate::metadata::ModChild;
1112
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
1213
use crate::middle::resolve_bound_vars;
1314
use crate::middle::stability;
@@ -2459,6 +2460,28 @@ impl<'tcx> TyCtxt<'tcx> {
24592460
self.def_kind(def_id) == DefKind::ImplTraitPlaceholder
24602461
}
24612462
}
2463+
2464+
/// Named module children from all items except `use` and `extern crate` imports.
2465+
///
2466+
/// In addition to regular items this list also includes struct or variant constructors, and
2467+
/// items inside `extern {}` blocks because all of them introduce names into parent module.
2468+
/// For non-reexported children every such name is associated with a separate `DefId`.
2469+
///
2470+
/// Module here is understood in name resolution sense - it can be a `mod` item,
2471+
/// or a crate root, or an enum, or a trait.
2472+
pub fn module_children_non_reexports(self, def_id: LocalDefId) -> &'tcx [LocalDefId] {
2473+
self.resolutions(()).module_children_non_reexports.get(&def_id).map_or(&[], |v| &v[..])
2474+
}
2475+
2476+
/// Named module children from `use` and `extern crate` imports.
2477+
///
2478+
/// Reexported names are not associated with individual `DefId`s,
2479+
/// e.g. a glob import can introduce a lot of names, all with the same `DefId`.
2480+
/// That's why the list needs to contain `ModChild` structures describing all the names
2481+
/// individually instead of `DefId`s.
2482+
pub fn module_children_reexports(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2483+
self.resolutions(()).module_children_reexports.get(&def_id).map_or(&[], |v| &v[..])
2484+
}
24622485
}
24632486

24642487
impl<'tcx> TyCtxtAt<'tcx> {
@@ -2501,8 +2524,6 @@ pub struct DeducedParamAttrs {
25012524
}
25022525

25032526
pub fn provide(providers: &mut ty::query::Providers) {
2504-
providers.module_reexports =
2505-
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map_or(&[], |v| &v[..]);
25062527
providers.maybe_unused_trait_imports =
25072528
|tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
25082529
providers.names_imported_by_glob_use = |tcx, id| {

compiler/rustc_middle/src/ty/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ pub struct ResolverGlobalCtxt {
166166
pub effective_visibilities: EffectiveVisibilities,
167167
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
168168
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
169-
pub reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
169+
pub module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>,
170+
pub module_children_reexports: LocalDefIdMap<Vec<ModChild>>,
170171
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
171172
pub main_def: Option<MainDefinition>,
172173
pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,

compiler/rustc_privacy/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
515515
let vis = self.tcx.local_visibility(item_id.owner_id.def_id);
516516
self.update_macro_reachable_def(item_id.owner_id.def_id, def_kind, vis, defining_mod);
517517
}
518-
for export in self.tcx.module_reexports(module_def_id) {
518+
for export in self.tcx.module_children_reexports(module_def_id) {
519519
if export.vis.is_accessible_from(defining_mod, self.tcx)
520520
&& let Res::Def(def_kind, def_id) = export.res
521521
&& let Some(def_id) = def_id.as_local() {

compiler/rustc_resolve/src/build_reduced_graph.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
931931
/// Builds the reduced graph for a single item in an external crate.
932932
fn build_reduced_graph_for_external_crate_res(&mut self, child: ModChild) {
933933
let parent = self.parent_scope.module;
934-
let ModChild { ident, res, vis, span, macro_rules, .. } = child;
934+
let ModChild { ident, res, vis, span, .. } = child;
935935
let res = res.expect_non_local();
936936
let expansion = self.parent_scope.expansion;
937937
// Record primary definitions.
@@ -964,9 +964,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
964964
_,
965965
) => self.r.define(parent, ident, ValueNS, (res, vis, span, expansion)),
966966
Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
967-
if !macro_rules {
968-
self.r.define(parent, ident, MacroNS, (res, vis, span, expansion))
969-
}
967+
self.r.define(parent, ident, MacroNS, (res, vis, span, expansion))
970968
}
971969
Res::Def(
972970
DefKind::TyParam

compiler/rustc_resolve/src/imports.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -1261,10 +1261,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12611261
*module.globs.borrow_mut() = Vec::new();
12621262

12631263
if let Some(def_id) = module.opt_def_id() {
1264+
let mut non_reexports = Vec::new();
12641265
let mut reexports = Vec::new();
12651266

12661267
module.for_each_child(self, |this, ident, _, binding| {
1267-
if let Some(res) = this.is_reexport(binding) {
1268+
let res = binding.res().expect_non_local();
1269+
if !binding.is_import() {
1270+
non_reexports.push(res.def_id().expect_local());
1271+
} else if res != def::Res::Err && !binding.is_ambiguity() {
12681272
let mut reexport_chain = SmallVec::new();
12691273
let mut next_binding = binding;
12701274
while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
@@ -1277,16 +1281,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12771281
res,
12781282
vis: binding.vis,
12791283
span: binding.span,
1280-
macro_rules: false,
12811284
reexport_chain,
12821285
});
12831286
}
12841287
});
12851288

1289+
// Should be fine because this code is only called for local modules.
1290+
let def_id = def_id.expect_local();
1291+
if !non_reexports.is_empty() {
1292+
self.module_children_non_reexports.insert(def_id, non_reexports);
1293+
}
12861294
if !reexports.is_empty() {
1287-
// Call to `expect_local` should be fine because current
1288-
// code is only called for local modules.
1289-
self.reexport_map.insert(def_id.expect_local(), reexports);
1295+
self.module_children_reexports.insert(def_id, reexports);
12901296
}
12911297
}
12921298
}

compiler/rustc_resolve/src/lib.rs

+6-18
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,8 @@ pub struct Resolver<'a, 'tcx> {
909909

910910
/// `CrateNum` resolutions of `extern crate` items.
911911
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
912-
reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
912+
module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>,
913+
module_children_reexports: LocalDefIdMap<Vec<ModChild>>,
913914
trait_map: NodeMap<Vec<TraitCandidate>>,
914915

915916
/// A map from nodes to anonymous modules.
@@ -1259,7 +1260,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12591260
lifetimes_res_map: Default::default(),
12601261
extra_lifetime_params_map: Default::default(),
12611262
extern_crate_map: Default::default(),
1262-
reexport_map: FxHashMap::default(),
1263+
module_children_non_reexports: Default::default(),
1264+
module_children_reexports: Default::default(),
12631265
trait_map: NodeMap::default(),
12641266
underscore_disambiguator: 0,
12651267
empty_module,
@@ -1386,7 +1388,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
13861388
let visibilities = self.visibilities;
13871389
let has_pub_restricted = self.has_pub_restricted;
13881390
let extern_crate_map = self.extern_crate_map;
1389-
let reexport_map = self.reexport_map;
13901391
let maybe_unused_trait_imports = self.maybe_unused_trait_imports;
13911392
let glob_map = self.glob_map;
13921393
let main_def = self.main_def;
@@ -1398,7 +1399,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
13981399
has_pub_restricted,
13991400
effective_visibilities,
14001401
extern_crate_map,
1401-
reexport_map,
1402+
module_children_non_reexports: self.module_children_non_reexports,
1403+
module_children_reexports: self.module_children_reexports,
14021404
glob_map,
14031405
maybe_unused_trait_imports,
14041406
main_def,
@@ -1949,20 +1951,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
19491951
}
19501952
self.main_def = Some(MainDefinition { res, is_import, span });
19511953
}
1952-
1953-
// Items that go to reexport table encoded to metadata and visible through it to other crates.
1954-
fn is_reexport(&self, binding: &NameBinding<'a>) -> Option<def::Res<!>> {
1955-
if binding.is_import() {
1956-
let res = binding.res().expect_non_local();
1957-
// Ambiguous imports are treated as errors at this point and are
1958-
// not exposed to other crates (see #36837 for more details).
1959-
if res != def::Res::Err && !binding.is_ambiguity() {
1960-
return Some(res);
1961-
}
1962-
}
1963-
1964-
return None;
1965-
}
19661954
}
19671955

19681956
fn names_to_string(names: &[Symbol]) -> String {

src/librustdoc/clean/inline.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ pub(crate) fn try_inline_glob(
152152
// reexported by the glob, e.g. because they are shadowed by something else.
153153
let reexports = cx
154154
.tcx
155-
.module_reexports(current_mod)
155+
.module_children_reexports(current_mod)
156156
.iter()
157157
.filter_map(|child| child.res.opt_def_id())
158158
.collect();

src/librustdoc/clean/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2062,7 +2062,7 @@ pub(crate) fn reexport_chain<'tcx>(
20622062
import_def_id: LocalDefId,
20632063
target_def_id: LocalDefId,
20642064
) -> &'tcx [Reexport] {
2065-
for child in tcx.module_reexports(tcx.local_parent(import_def_id)) {
2065+
for child in tcx.module_children_reexports(tcx.local_parent(import_def_id)) {
20662066
if child.res.opt_def_id() == Some(target_def_id.to_def_id())
20672067
&& child.reexport_chain[0].id() == Some(import_def_id.to_def_id())
20682068
{

0 commit comments

Comments
 (0)