mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 19:12:50 +00:00
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.
This commit is contained in:
commit
e19ca1d946
@ -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};
|
||||
@ -1074,33 +1074,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,
|
||||
/// 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)) {
|
||||
@ -1116,7 +1121,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.
|
||||
@ -1128,7 +1133,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 => {
|
||||
@ -1153,7 +1158,7 @@ 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 });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -1161,10 +1166,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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};
|
||||
@ -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) }
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
|
@ -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(),
|
||||
}
|
||||
@ -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 {
|
||||
|
@ -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;
|
||||
@ -336,7 +336,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,
|
||||
|
@ -1,28 +0,0 @@
|
||||
use crate::ty;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
/// This is the replacement export map. It maps a module to all of the exports
|
||||
/// within.
|
||||
pub type ExportMap = FxHashMap<LocalDefId, Vec<Export>>;
|
||||
|
||||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
pub struct Export {
|
||||
/// The name of the target.
|
||||
pub ident: Ident,
|
||||
/// The resolution of the target.
|
||||
/// Local variables cannot be exported, so this `Res` doesn't need the ID parameter.
|
||||
pub res: Res<!>,
|
||||
/// The span of the target.
|
||||
pub span: Span,
|
||||
/// The visibility of the export.
|
||||
/// We include non-`pub` exports for hygienic macros that get used from extern crates.
|
||||
pub vis: ty::Visibility,
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
24
compiler/rustc_middle/src/metadata.rs
Normal file
24
compiler/rustc_middle/src/metadata.rs
Normal file
@ -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,
|
||||
}
|
@ -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 {
|
||||
@ -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> {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
@ -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.
|
||||
|
@ -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)
|
||||
@ -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;
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -520,7 +520,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
|
||||
let vis = self.tcx.visibility(item_id.def_id);
|
||||
self.update_macro_reachable_def(item_id.def_id, def_kind, vis, defining_mod);
|
||||
}
|
||||
if let Some(exports) = self.tcx.module_exports(module_def_id) {
|
||||
if let Some(exports) = self.tcx.module_reexports(module_def_id) {
|
||||
for export in exports {
|
||||
if export.vis.is_accessible_from(defining_mod.to_def_id(), self.tcx) {
|
||||
if let Res::Def(def_kind, def_id) = export.res {
|
||||
@ -926,7 +926,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||
// crate module gets processed as well.
|
||||
if self.prev_level.is_some() {
|
||||
let def_id = self.tcx.hir().local_def_id(id);
|
||||
if let Some(exports) = self.tcx.module_exports(def_id) {
|
||||
if let Some(exports) = self.tcx.module_reexports(def_id) {
|
||||
for export in exports.iter() {
|
||||
if export.vis.is_public() {
|
||||
if let Some(def_id) = export.res.opt_def_id() {
|
||||
|
@ -26,7 +26,7 @@ use rustc_hir::def::{self, *};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
|
||||
use rustc_metadata::creader::LoadedMacro;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::hir::exports::Export;
|
||||
use rustc_middle::metadata::ModChild;
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::cstore::CrateStore;
|
||||
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
|
||||
@ -214,7 +214,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
crate fn build_reduced_graph_external(&mut self, module: Module<'a>) {
|
||||
for child in self.cstore().item_children_untracked(module.def_id(), self.session) {
|
||||
for child in self.cstore().module_children_untracked(module.def_id(), self.session) {
|
||||
let parent_scope = ParentScope::module(module, self);
|
||||
BuildReducedGraphVisitor { r: self, parent_scope }
|
||||
.build_reduced_graph_for_external_crate_res(child);
|
||||
@ -938,9 +938,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||
}
|
||||
|
||||
/// Builds the reduced graph for a single item in an external crate.
|
||||
fn build_reduced_graph_for_external_crate_res(&mut self, child: Export) {
|
||||
fn build_reduced_graph_for_external_crate_res(&mut self, child: ModChild) {
|
||||
let parent = self.parent_scope.module;
|
||||
let Export { ident, res, vis, span } = child;
|
||||
let ModChild { ident, res, vis, span } = child;
|
||||
let res = res.expect_non_local();
|
||||
let expansion = self.parent_scope.expansion;
|
||||
// Record primary definitions.
|
||||
|
@ -15,7 +15,7 @@ use rustc_data_structures::ptr_key::PtrKey;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability};
|
||||
use rustc_hir::def::{self, PartialRes};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::hir::exports::Export;
|
||||
use rustc_middle::metadata::ModChild;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS};
|
||||
@ -1409,7 +1409,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||
if is_good_import || binding.is_macro_def() {
|
||||
let res = binding.res().expect_non_local();
|
||||
if res != def::Res::Err {
|
||||
reexports.push(Export { ident, res, span: binding.span, vis: binding.vis });
|
||||
reexports.push(ModChild { ident, res, vis: binding.vis, span: binding.span });
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1418,7 +1418,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||
if let Some(def_id) = module.opt_def_id() {
|
||||
// Call to `expect_local` should be fine because current
|
||||
// code is only called for local modules.
|
||||
self.r.export_map.insert(def_id.expect_local(), reexports);
|
||||
self.r.reexport_map.insert(def_id.expect_local(), reexports);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
|
||||
use rustc_hir::TraitCandidate;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_metadata::creader::{CStore, CrateLoader};
|
||||
use rustc_middle::hir::exports::ExportMap;
|
||||
use rustc_middle::metadata::ModChild;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, DefIdTree, MainDefinition, ResolverOutputs};
|
||||
@ -927,7 +927,7 @@ pub struct Resolver<'a> {
|
||||
|
||||
/// `CrateNum` resolutions of `extern crate` items.
|
||||
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
||||
export_map: ExportMap,
|
||||
reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
|
||||
trait_map: NodeMap<Vec<TraitCandidate>>,
|
||||
|
||||
/// A map from nodes to anonymous modules.
|
||||
@ -1333,7 +1333,7 @@ impl<'a> Resolver<'a> {
|
||||
import_res_map: Default::default(),
|
||||
label_res_map: Default::default(),
|
||||
extern_crate_map: Default::default(),
|
||||
export_map: FxHashMap::default(),
|
||||
reexport_map: FxHashMap::default(),
|
||||
trait_map: NodeMap::default(),
|
||||
underscore_disambiguator: 0,
|
||||
empty_module,
|
||||
@ -1446,7 +1446,7 @@ impl<'a> Resolver<'a> {
|
||||
let definitions = self.definitions;
|
||||
let visibilities = self.visibilities;
|
||||
let extern_crate_map = self.extern_crate_map;
|
||||
let export_map = self.export_map;
|
||||
let reexport_map = self.reexport_map;
|
||||
let maybe_unused_trait_imports = self.maybe_unused_trait_imports;
|
||||
let maybe_unused_extern_crates = self.maybe_unused_extern_crates;
|
||||
let glob_map = self.glob_map;
|
||||
@ -1457,7 +1457,7 @@ impl<'a> Resolver<'a> {
|
||||
cstore: Box::new(self.crate_loader.into_cstore()),
|
||||
visibilities,
|
||||
extern_crate_map,
|
||||
export_map,
|
||||
reexport_map,
|
||||
glob_map,
|
||||
maybe_unused_trait_imports,
|
||||
maybe_unused_extern_crates,
|
||||
@ -1480,7 +1480,7 @@ impl<'a> Resolver<'a> {
|
||||
cstore: Box::new(self.cstore().clone()),
|
||||
visibilities: self.visibilities.clone(),
|
||||
extern_crate_map: self.extern_crate_map.clone(),
|
||||
export_map: self.export_map.clone(),
|
||||
reexport_map: self.reexport_map.clone(),
|
||||
glob_map: self.glob_map.clone(),
|
||||
maybe_unused_trait_imports: self.maybe_unused_trait_imports.clone(),
|
||||
maybe_unused_extern_crates: self.maybe_unused_extern_crates.clone(),
|
||||
|
@ -1321,7 +1321,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if Some(*parent_did) != self.tcx.parent(*trait_did)
|
||||
&& self
|
||||
.tcx
|
||||
.item_children(*parent_did)
|
||||
.module_children(*parent_did)
|
||||
.iter()
|
||||
.filter(|child| child.res.opt_def_id() == Some(*trait_did))
|
||||
.all(|child| child.ident.name == kw::Underscore)
|
||||
|
@ -516,7 +516,7 @@ fn build_module(
|
||||
// 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.item_children(did).iter() {
|
||||
for &item in cx.tcx.module_children(did).iter() {
|
||||
if item.vis.is_public() {
|
||||
let res = item.res.expect_non_local();
|
||||
if let Some(def_id) = res.mod_def_id() {
|
||||
|
@ -265,7 +265,7 @@ impl ExternalCrate {
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
tcx.item_children(root).iter().map(|item| item.res).filter_map(as_keyword).collect()
|
||||
tcx.module_children(root).iter().map(|item| item.res).filter_map(as_keyword).collect()
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +333,7 @@ impl ExternalCrate {
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
tcx.item_children(root).iter().map(|item| item.res).filter_map(as_primitive).collect()
|
||||
tcx.module_children(root).iter().map(|item| item.res).filter_map(as_primitive).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ 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_exports(CRATE_DEF_ID).unwrap_or(&[]) {
|
||||
for export in self.cx.tcx.module_reexports(CRATE_DEF_ID).unwrap_or(&[]) {
|
||||
if let Res::Def(DefKind::Macro(_), def_id) = export.res {
|
||||
if let Some(local_def_id) = def_id.as_local() {
|
||||
if self.cx.tcx.has_attr(def_id, sym::macro_export) {
|
||||
|
@ -53,7 +53,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
for item in self.tcx.item_children(def_id).iter() {
|
||||
for item in self.tcx.module_children(def_id).iter() {
|
||||
if let Some(def_id) = item.res.opt_def_id() {
|
||||
if self.tcx.def_key(def_id).parent.map_or(false, |d| d == def_id.index)
|
||||
|| item.vis.is_public()
|
||||
|
@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
|
||||
if let Res::Def(DefKind::Mod, id) = path.res;
|
||||
if !id.is_local();
|
||||
then {
|
||||
for kid in cx.tcx.item_children(id).iter() {
|
||||
for kid in cx.tcx.module_children(id).iter() {
|
||||
if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res {
|
||||
let span = mac_attr.span;
|
||||
let def_path = cx.tcx.def_path_str(mac_id);
|
||||
|
@ -924,7 +924,7 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
|
||||
let lang_item_path = cx.get_def_path(*item_def_id);
|
||||
if path_syms.starts_with(&lang_item_path) {
|
||||
if let [item] = &path_syms[lang_item_path.len()..] {
|
||||
for child in cx.tcx.item_children(*item_def_id) {
|
||||
for child in cx.tcx.module_children(*item_def_id) {
|
||||
if child.ident.name == *item {
|
||||
return true;
|
||||
}
|
||||
@ -984,7 +984,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
|
||||
|
||||
for &module in &[&paths::KW_MODULE, &paths::SYM_MODULE] {
|
||||
if let Some(def_id) = path_to_res(cx, module).opt_def_id() {
|
||||
for item in cx.tcx.item_children(def_id).iter() {
|
||||
for item in cx.tcx.module_children(def_id).iter() {
|
||||
if_chain! {
|
||||
if let Res::Def(DefKind::Const, item_def_id) = item.res;
|
||||
let ty = cx.tcx.type_of(item_def_id);
|
||||
|
@ -82,7 +82,6 @@ use rustc_hir::{
|
||||
TraitItemKind, TraitRef, TyKind, UnOp, ArrayLen
|
||||
};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc_middle::hir::exports::Export;
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::hir::place::PlaceBase;
|
||||
use rustc_middle::ty as rustc_ty;
|
||||
@ -523,10 +522,21 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
||||
}
|
||||
};
|
||||
}
|
||||
fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export> {
|
||||
tcx.item_children(def_id)
|
||||
.iter()
|
||||
.find(|item| item.ident.name.as_str() == name)
|
||||
fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<Res> {
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx
|
||||
.module_children(def_id)
|
||||
.iter()
|
||||
.find(|item| item.ident.name.as_str() == name)
|
||||
.map(|child| child.res.expect_non_local()),
|
||||
DefKind::Impl => tcx
|
||||
.associated_item_def_ids(def_id)
|
||||
.iter()
|
||||
.copied()
|
||||
.find(|assoc_def_id| tcx.item_name(*assoc_def_id).as_str() == name)
|
||||
.map(|assoc_def_id| Res::Def(tcx.def_kind(assoc_def_id), assoc_def_id)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
let (krate, first, path) = match *path {
|
||||
@ -543,15 +553,12 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
||||
let last = path
|
||||
.iter()
|
||||
.copied()
|
||||
// `get_def_path` seems to generate these empty segments for extern blocks.
|
||||
// We can just ignore them.
|
||||
.filter(|segment| !segment.is_empty())
|
||||
// for each segment, find the child item
|
||||
.try_fold(first, |item, segment| {
|
||||
let def_id = item.res.def_id();
|
||||
.try_fold(first, |res, segment| {
|
||||
let def_id = res.def_id();
|
||||
if let Some(item) = item_child_by_name(tcx, def_id, segment) {
|
||||
Some(item)
|
||||
} else if matches!(item.res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
|
||||
} else if matches!(res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
|
||||
// it is not a child item so check inherent impl items
|
||||
tcx.inherent_impls(def_id)
|
||||
.iter()
|
||||
@ -560,7 +567,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
||||
None
|
||||
}
|
||||
});
|
||||
try_res!(last).res.expect_non_local()
|
||||
try_res!(last).expect_non_local()
|
||||
}
|
||||
|
||||
/// Convenience function to get the `DefId` of a trait by path.
|
||||
|
@ -40,7 +40,7 @@ mod a {
|
||||
}
|
||||
}
|
||||
|
||||
// issue #7015, ICE due to calling `item_children` with local `DefId`
|
||||
// issue #7015, ICE due to calling `module_children` with local `DefId`
|
||||
#[macro_use]
|
||||
use a as b;
|
||||
|
||||
|
@ -40,7 +40,7 @@ mod a {
|
||||
}
|
||||
}
|
||||
|
||||
// issue #7015, ICE due to calling `item_children` with local `DefId`
|
||||
// issue #7015, ICE due to calling `module_children` with local `DefId`
|
||||
#[macro_use]
|
||||
use a as b;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user