From de64b4eb194889d88a7ce1612be56fd3a7db7137 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 26 Apr 2023 14:12:16 +0300 Subject: [PATCH] [WIP] One more attempt to optimize `module_children` --- .../rustc_hir_typeck/src/method/suggest.rs | 10 ++-- compiler/rustc_metadata/src/rmeta/decoder.rs | 32 +++++------ .../src/rmeta/decoder/cstore_impl.rs | 16 ++++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 18 ++---- compiler/rustc_metadata/src/rmeta/mod.rs | 3 +- compiler/rustc_middle/src/metadata.rs | 57 ++++++++++++++++++- compiler/rustc_middle/src/ty/context.rs | 22 +------ compiler/rustc_middle/src/ty/mod.rs | 3 +- compiler/rustc_middle/src/ty/print/pretty.rs | 46 ++++++++------- compiler/rustc_privacy/src/lib.rs | 4 +- .../rustc_resolve/src/build_reduced_graph.rs | 12 +++- compiler/rustc_resolve/src/imports.rs | 25 ++++---- compiler/rustc_resolve/src/lib.rs | 9 +-- src/librustdoc/clean/inline.rs | 16 +++--- src/librustdoc/clean/mod.rs | 9 +-- src/librustdoc/clean/types.rs | 12 +++- src/librustdoc/visit_ast.rs | 4 +- src/librustdoc/visit_lib.rs | 6 +- .../clippy/clippy_lints/src/macro_use.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 4 +- src/tools/miri/src/helpers.rs | 33 ++++++----- 21 files changed, 195 insertions(+), 148 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index db1f10f645fd..25da467a04d5 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -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; } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index a310cbb80293..3f0485d79511 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -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; @@ -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() @@ -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, @@ -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; } } }) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 4a3b783c6367..e08f8eb0b51f 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -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; @@ -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; } @@ -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); @@ -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); } } @@ -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) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index f5ffdd27cae3..5a06ccd18f42 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -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); @@ -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)); } } @@ -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); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index dd02463e16a0..0c0e234bdcfd 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -357,11 +357,10 @@ define_tables! { associated_types_for_impl_traits_in_associated_fn: Table>, opt_rpitit_info: Table>>, unused_generic_params: Table, - module_children_reexports: Table>, - optional: attributes: Table>, - module_children_non_reexports: Table>, + module_children: Table>, associated_item_or_field_def_ids: Table>, opt_def_kind: Table, visibility: Table>>, diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index 674402cb4bf9..740ff1518561 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -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. @@ -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. @@ -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 { + 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 { + 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, + } + } +} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7df4be263d58..dc33da8b5160 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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[..]) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8e4e708b73c4..7d90a1fd61ac 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -166,8 +166,7 @@ pub struct ResolverGlobalCtxt { pub effective_visibilities: EffectiveVisibilities, pub extern_crate_map: FxHashMap, pub maybe_unused_trait_imports: FxIndexSet, - pub module_children_non_reexports: LocalDefIdMap>, - pub module_children_reexports: LocalDefIdMap>, + pub module_children: LocalDefIdMap>, pub glob_map: FxHashMap>, pub main_def: Option, pub trait_impls: FxIndexMap>, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 1c1432ecd5a0..bf96e9308d06 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -318,13 +318,16 @@ pub trait PrettyPrinter<'tcx>: && let DefPathData::TypeNs(_) = key.disambiguated_data.data && Some(*visible_parent) != actual_parent { - this - .tcx() - .module_children(visible_parent) + let tcx = this.tcx(); + tcx.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) - .map(|child| child.ident.name) + .find_map(|child| { + let name = child.name(tcx); + (name != kw::Underscore + && child.opt_def_id() == Some(def_id) + && child.vis(tcx).is_public()) + .then_some(name) + }) .unwrap_or(name) } else { name @@ -543,13 +546,14 @@ pub trait PrettyPrinter<'tcx>: DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => { // Item might be re-exported several times, but filter for the one // that's public and whose identifier isn't `_`. - let reexport = self - .tcx() - .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) - .map(|child| child.ident.name); + let tcx = self.tcx(); + let reexport = tcx.module_children(visible_parent).iter().find_map(|child| { + let name = child.name(tcx); + (name != kw::Underscore + && child.opt_def_id() == Some(def_id) + && child.vis(tcx).is_public()) + .then_some(name) + }); if let Some(new_name) = reexport { *name = new_name; @@ -2894,7 +2898,7 @@ define_print_and_forward_display! { } } -fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) { +fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(Symbol, Namespace, DefId)) { // Iterate all local crate items no matter where they are defined. let hir = tcx.hir(); for id in hir.items() { @@ -2909,7 +2913,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N let def_id = item.owner_id.to_def_id(); let ns = tcx.def_kind(def_id).ns().unwrap_or(Namespace::TypeNS); - collect_fn(&item.ident, ns, def_id); + collect_fn(item.ident.name, ns, def_id); } // Now take care of extern crate items. @@ -2934,17 +2938,17 @@ 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.module_children(def).iter() { - if !child.vis.is_public() { + for child in tcx.module_children(def) { + if !child.vis(tcx).is_public() { continue; } - match child.res { + match child.res(tcx) { def::Res::Def(DefKind::AssocTy, _) => {} def::Res::Def(DefKind::TyAlias, _) => {} def::Res::Def(defkind, def_id) => { if let Some(ns) = defkind.ns() { - collect_fn(&child.ident, ns, def_id); + collect_fn(child.name(tcx), ns, def_id); } if matches!(defkind, DefKind::Mod | DefKind::Enum | DefKind::Trait) @@ -2997,10 +3001,10 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap { } } - for_each_def(tcx, |ident, ns, def_id| { + for_each_def(tcx, |name, ns, def_id| { use std::collections::hash_map::Entry::{Occupied, Vacant}; - match unique_symbols_rev.entry((ns, ident.name)) { + match unique_symbols_rev.entry((ns, name)) { Occupied(mut v) => match v.get() { None => {} Some(existing) => { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index c607c7fd5f4a..3f7b8932f28c 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -25,6 +25,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; +use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::{EffectiveVisibilities, Level}; use rustc_middle::span_bug; use rustc_middle::ty::query::Providers; @@ -515,7 +516,8 @@ impl<'tcx> EmbargoVisitor<'tcx> { let vis = self.tcx.local_visibility(item_id.owner_id.def_id); self.update_macro_reachable_def(item_id.owner_id.def_id, def_kind, vis, defining_mod); } - for export in self.tcx.module_children_reexports(module_def_id) { + for child in self.tcx.module_children_local(module_def_id) { + let ModChild::Reexport(export) = child else { continue }; if export.vis.is_accessible_from(defining_mod, self.tcx) && let Res::Def(def_kind, def_id) = export.res && let Some(def_id) = def_id.as_local() { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 3799679cb1ea..d69f5ad07a2d 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -27,7 +27,7 @@ use rustc_expand::expand::AstFragment; use rustc_hir::def::{self, *}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_metadata::creader::LoadedMacro; -use rustc_middle::metadata::ModChild; +use rustc_middle::metadata::{ModChild, ModChildData}; use rustc_middle::{bug, ty}; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -926,7 +926,15 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { /// Builds the reduced graph for a single item in an external crate. fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild) { let parent = self.parent_scope.module; - let ModChild { ident, res, vis, ref reexport_chain } = *child; + let data; + let data = match child { + ModChild::Def(def_id) => { + data = self.r.cstore().mod_child_data_untracked(*def_id, self.r.tcx.sess); + &data + } + ModChild::Reexport(reexport) => reexport, + }; + let ModChildData { ident, res, vis, ref reexport_chain } = *data; let span = self.r.def_span( reexport_chain .first() diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index d7c518fbdd0d..258fda9f7cd2 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -16,8 +16,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; use rustc_hir::def::{self, DefKind, PartialRes}; -use rustc_middle::metadata::ModChild; -use rustc_middle::metadata::Reexport; +use rustc_middle::metadata::{ModChild, ModChildData, Reexport}; use rustc_middle::span_bug; use rustc_middle::ty; use rustc_session::lint::builtin::{ @@ -1261,13 +1260,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { *module.globs.borrow_mut() = Vec::new(); if let Some(def_id) = module.opt_def_id() { - let mut non_reexports = Vec::new(); - let mut reexports = Vec::new(); + let mut children = Vec::new(); module.for_each_child(self, |this, ident, _, binding| { let res = binding.res().expect_non_local(); if !binding.is_import() { - non_reexports.push(res.def_id().expect_local()); + children.push(ModChild::Def(res.def_id())); } else if res != def::Res::Err && !binding.is_ambiguity() { let mut reexport_chain = SmallVec::new(); let mut next_binding = binding; @@ -1276,17 +1274,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { next_binding = binding; } - reexports.push(ModChild { ident, res, vis: binding.vis, reexport_chain }); + children.push(ModChild::Reexport(ModChildData { + ident, + res, + vis: binding.vis, + reexport_chain, + })); } }); - // Should be fine because this code is only called for local modules. - let def_id = def_id.expect_local(); - if !non_reexports.is_empty() { - self.module_children_non_reexports.insert(def_id, non_reexports); - } - if !reexports.is_empty() { - self.module_children_reexports.insert(def_id, reexports); + if !children.is_empty() { + // Should be fine because this code is only called for local modules. + self.module_children.insert(def_id.expect_local(), children); } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 125f5ce76117..e46463579fe4 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -909,8 +909,7 @@ pub struct Resolver<'a, 'tcx> { /// `CrateNum` resolutions of `extern crate` items. extern_crate_map: FxHashMap, - module_children_non_reexports: LocalDefIdMap>, - module_children_reexports: LocalDefIdMap>, + module_children: LocalDefIdMap>, trait_map: NodeMap>, /// A map from nodes to anonymous modules. @@ -1260,8 +1259,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { lifetimes_res_map: Default::default(), extra_lifetime_params_map: Default::default(), extern_crate_map: Default::default(), - module_children_non_reexports: Default::default(), - module_children_reexports: Default::default(), + module_children: Default::default(), trait_map: NodeMap::default(), underscore_disambiguator: 0, empty_module, @@ -1399,8 +1397,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { has_pub_restricted, effective_visibilities, extern_crate_map, - module_children_non_reexports: self.module_children_non_reexports, - module_children_reexports: self.module_children_reexports, + module_children: self.module_children, glob_map, maybe_unused_trait_imports, main_def, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3f6a5d6d9017..25bebfe2868f 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -152,9 +152,9 @@ pub(crate) fn try_inline_glob( // reexported by the glob, e.g. because they are shadowed by something else. let reexports = cx .tcx - .module_children_reexports(current_mod) + .module_children_local(current_mod) .iter() - .filter_map(|child| child.res.opt_def_id()) + .filter_map(|child| child.opt_def_id()) .collect(); let mut items = build_module_items(cx, did, visited, inlined_names, Some(&reexports)); items.drain_filter(|item| { @@ -557,9 +557,9 @@ fn build_module_items( // If we're re-exporting a re-export it may actually re-export something in // two namespaces, so the target may be listed twice. Make sure we only // visit each node at most once. - for item in cx.tcx.module_children(did).iter() { - if item.vis.is_public() { - let res = item.res.expect_non_local(); + for item in cx.tcx.module_children(did) { + if item.vis(cx.tcx).is_public() { + let res = item.res(cx.tcx).expect_non_local(); if let Some(def_id) = res.opt_def_id() && let Some(allowed_def_ids) = allowed_def_ids && !allowed_def_ids.contains(&def_id) { @@ -570,7 +570,7 @@ fn build_module_items( // two distinct modules with the same name. We don't want to // inline it, or mark any of its contents as visited. if did == def_id - || inlined_names.contains(&(ItemType::Module, item.ident.name)) + || inlined_names.contains(&(ItemType::Module, item.name(cx.tcx))) || !visited.insert(def_id) { continue; @@ -586,7 +586,7 @@ fn build_module_items( // from it is `DefId.krate`. item_id: ItemId::DefId(did), kind: Box::new(clean::ImportItem(clean::Import::new_simple( - item.ident.name, + item.name(cx.tcx), clean::ImportSource { path: clean::Path { res, @@ -605,7 +605,7 @@ fn build_module_items( cfg: None, inline_stmt_id: None, }); - } else if let Some(i) = try_inline(cx, res, item.ident.name, None, visited) { + } else if let Some(i) = try_inline(cx, res, item.name(cx.tcx), None, visited) { items.extend(i) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c992a5388d19..ee8fcca91dd9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2070,11 +2070,12 @@ pub(crate) fn reexport_chain<'tcx>( import_def_id: LocalDefId, target_def_id: LocalDefId, ) -> &'tcx [Reexport] { - for child in tcx.module_children_reexports(tcx.local_parent(import_def_id)) { - if child.res.opt_def_id() == Some(target_def_id.to_def_id()) - && child.reexport_chain[0].id() == Some(import_def_id.to_def_id()) + for child in tcx.module_children_local(tcx.local_parent(import_def_id)) { + if child.opt_def_id() == Some(target_def_id.to_def_id()) + && child.reexport_chain().first().and_then(|rx| rx.id()) + == Some(import_def_id.to_def_id()) { - return &child.reexport_chain; + return child.reexport_chain(); } } &[] diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 74f330b76217..67a9e9ef9ea9 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -236,7 +236,11 @@ impl ExternalCrate { }) .collect() } else { - tcx.module_children(root).iter().map(|item| item.res).filter_map(as_keyword).collect() + tcx.module_children(root) + .iter() + .map(|item| item.res(tcx)) + .filter_map(as_keyword) + .collect() } } @@ -284,7 +288,11 @@ impl ExternalCrate { }) .collect() } else { - tcx.module_children(root).iter().map(|item| item.res).filter_map(as_primitive).collect() + tcx.module_children(root) + .iter() + .map(|item| item.res(tcx)) + .filter_map(as_primitive) + .collect() } } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index a6089680fae9..4135d13de1ab 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -8,6 +8,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet}; use rustc_hir::intravisit::{walk_item, Visitor}; use rustc_hir::{Node, CRATE_HIR_ID}; use rustc_middle::hir::nested_filter; +use rustc_middle::metadata::ModChild; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_span::hygiene::MacroKind; @@ -136,7 +137,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // is declared but also a reexport of itself producing two exports of the same // macro in the same module. let mut inserted = FxHashSet::default(); - for export in self.cx.tcx.module_children_reexports(CRATE_DEF_ID) { + for child in self.cx.tcx.module_children_local(CRATE_DEF_ID) { + let ModChild::Reexport(export) = child else { continue }; if let Res::Def(DefKind::Macro(_), def_id) = export.res && let Some(local_def_id) = def_id.as_local() && self.cx.tcx.has_attr(def_id, sym::macro_export) && diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index fd4f9254107c..51f72275b649 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -53,9 +53,9 @@ impl LibEmbargoVisitor<'_, '_> { return; } - for item in self.tcx.module_children(def_id).iter() { - if let Some(def_id) = item.res.opt_def_id() { - if item.vis.is_public() { + for item in self.tcx.module_children(def_id) { + if let Some(def_id) = item.opt_def_id() { + if item.vis(self.tcx).is_public() { self.visit_item(def_id); } } diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index e2e6a87a3015..4b62bd2a9dab 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -101,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports { if !id.is_local(); then { for kid in cx.tcx.module_children(id).iter() { - if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res { + if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res(cx.tcx) { let span = mac_attr.span; let def_path = cx.tcx.def_path_str(mac_id); self.imports.push((def_path, span, hir_id)); diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 6b677df46414..be72613a2950 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -549,8 +549,8 @@ fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx .module_children(def_id) .iter() - .filter(|item| item.ident.name == name) - .map(|child| child.res.expect_non_local()) + .filter(|item| item.name(tcx) == name) + .map(|child| child.res(tcx).expect_non_local()) .collect(), DefKind::Impl { .. } => tcx .associated_item_def_ids(def_id) diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 8f6ae7294917..3dc139e77042 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -8,7 +8,7 @@ use std::time::Duration; use log::trace; -use rustc_hir::def::{DefKind, Namespace}; +use rustc_hir::def::{DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_middle::mir; use rustc_middle::ty::{ @@ -94,16 +94,17 @@ const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = { /// /// A `None` namespace indicates we are looking for a module. fn try_resolve_did(tcx: TyCtxt<'_>, path: &[&str], namespace: Option) -> Option { - /// Yield all children of the given item, that have the given name. - fn find_children<'tcx: 'a, 'a>( - tcx: TyCtxt<'tcx>, + /// Find a child of the given item, that have the given name and resolution. + fn find_child( + tcx: TyCtxt<'_>, item: DefId, - name: &'a str, - ) -> impl Iterator + 'a { - tcx.module_children(item) - .iter() - .filter(move |item| item.ident.name.as_str() == name) - .map(move |item| item.res.def_id()) + name: &str, + cond: impl Fn(Res) -> bool, + ) -> Option { + tcx.module_children(item).iter().find_map(|child| { + let res = child.res(tcx); + if cond(res) && child.name(tcx).as_str() == name { res.opt_def_id() } else { None } + }) } // Take apart the path: leading crate, a sequence of modules, and potentially a final item. @@ -122,16 +123,14 @@ fn try_resolve_did(tcx: TyCtxt<'_>, path: &[&str], namespace: Option) let mut cur_item = DefId { krate: *krate, index: CRATE_DEF_INDEX }; // Then go over the modules. for &segment in modules { - cur_item = find_children(tcx, cur_item, segment) - .find(|item| tcx.def_kind(item) == DefKind::Mod)?; + cur_item = + find_child(tcx, cur_item, segment, |res| matches!(res, Res::Def(DefKind::Mod, _)))?; } // Finally, look up the desired item in this module, if any. match item { - Some((item_name, namespace)) => - Some( - find_children(tcx, cur_item, item_name) - .find(|item| tcx.def_kind(item).ns() == Some(namespace))?, - ), + Some((item_name, namespace)) => { + Some(find_child(tcx, cur_item, item_name, |res| res.ns() == Some(namespace))?) + } None => Some(cur_item), } }