From 96c6a50e9650fe4fbbd2abf547ed39cc108b69f1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 18 Dec 2021 20:07:58 +0800 Subject: [PATCH 1/3] rustc_metadata: Optimize and document module children decoding --- compiler/rustc_metadata/src/rmeta/decoder.rs | 29 +++++++++-------- .../src/rmeta/decoder/cstore_impl.rs | 23 ++++++++------ compiler/rustc_metadata/src/rmeta/encoder.rs | 1 - compiler/rustc_middle/src/ty/print/pretty.rs | 4 ++- src/tools/clippy/clippy_utils/src/lib.rs | 31 ++++++++++++------- 5 files changed, 50 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 5c2752795793b..dd025eeac9e60 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1075,15 +1075,16 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } - /// Iterates over each child of the given item. + /// 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 each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), 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)), @@ -1096,12 +1097,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { 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)) { @@ -1162,10 +1157,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!("`each_child_of_item` is called on a non-module: {:?}", self.def_kind(id)), } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 804f277e26e12..ba0e76d2f5ec9 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -4,7 +4,7 @@ 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; @@ -309,28 +309,33 @@ 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: &Export, 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); + } } } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 11a986f0a7c81..47fb254da9ab5 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -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 { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 47a9234419c2d..f7a2cc126ce51 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -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); } } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 9179e67c4f4ee..bd6851d1fbba2 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -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 { + match tcx.def_kind(def_id) { + DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx + .item_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. From 3051f6e9c497018b507c407a04a56957f9c83df7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 23 Dec 2021 16:12:34 +0800 Subject: [PATCH 2/3] rustc_metadata: Rename `item_children(_untracked)` to `module_children(_untracked)` And `each_child_of_item` to `for_each_module_child` --- compiler/rustc_metadata/src/rmeta/decoder.rs | 9 +++++++-- .../rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 10 +++++----- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 4 ++-- compiler/rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_typeck/src/check/method/suggest.rs | 2 +- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/types.rs | 4 ++-- src/librustdoc/visit_lib.rs | 2 +- src/tools/clippy/clippy_lints/src/macro_use.rs | 2 +- .../clippy/clippy_lints/src/utils/internal_lints.rs | 4 ++-- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- src/tools/clippy/tests/ui/macro_use_imports.fixed | 2 +- src/tools/clippy/tests/ui/macro_use_imports.rs | 2 +- 14 files changed, 27 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index dd025eeac9e60..91696088cdd61 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1079,7 +1079,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { /// 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 each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), sess: &Session) { + fn for_each_module_child( + &self, + id: DefIndex, + mut callback: impl FnMut(Export), + 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. @@ -1164,7 +1169,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } EntryKind::Enum(..) | EntryKind::Trait(..) => {} - _ => bug!("`each_child_of_item` is called on a non-module: {:?}", self.def_kind(id)), + _ => bug!("`for_each_module_child` is called on a non-module: {:?}", self.def_kind(id)), } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index ba0e76d2f5ec9..f0d87241dd33f 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -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) } @@ -342,7 +342,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { }; 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); } } @@ -388,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 { + pub fn module_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec { 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, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f1c2be660bc76..33e7e9dd6e020 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1528,7 +1528,7 @@ rustc_queries! { desc { "fetching what a crate is named" } separate_provide_extern } - query item_children(def_id: DefId) -> &'tcx [Export] { + query module_children(def_id: DefId) -> &'tcx [Export] { desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f7a2cc126ce51..c6454f3e0d02a 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -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; } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 39074f811a50b..5de8b39f2ae98 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -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); diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 7f9c75c7fee64..1a6fcbc57bff2 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -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) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ce0ac322af914..d4e2969819fab 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -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() { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index bfe4a24b94216..491f7b2fa6901 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -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() } } } diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index ce94f06d574e1..5bcec779bc0e7 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -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() diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 50d80e6a1d224..41f5a913b316e 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs index e98dcd3cf983b..7d196af7a53f4 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs @@ -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); diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index bd6851d1fbba2..91ebc7ea89cc0 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -525,7 +525,7 @@ 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 { match tcx.def_kind(def_id) { DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx - .item_children(def_id) + .module_children(def_id) .iter() .find(|item| item.ident.name.as_str() == name) .map(|child| child.res.expect_non_local()), diff --git a/src/tools/clippy/tests/ui/macro_use_imports.fixed b/src/tools/clippy/tests/ui/macro_use_imports.fixed index 9171558f3a2d7..306ea50258da0 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports.fixed +++ b/src/tools/clippy/tests/ui/macro_use_imports.fixed @@ -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; diff --git a/src/tools/clippy/tests/ui/macro_use_imports.rs b/src/tools/clippy/tests/ui/macro_use_imports.rs index cd01fd43f6d32..e26a7545ea6f8 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports.rs +++ b/src/tools/clippy/tests/ui/macro_use_imports.rs @@ -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; From 4b03fd910c4d963a369baa3e38c9a7713c04a79c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 21 Dec 2021 11:24:43 +0800 Subject: [PATCH 3/3] rustc_middle: Rename `Export` to `ModChild` and add some comments Also rename `module_exports`/`export_map` to `module_reexports`/`reexport_map` for clarity. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 17 +++++++---- .../src/rmeta/decoder/cstore_impl.rs | 6 ++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_metadata/src/rmeta/mod.rs | 4 +-- compiler/rustc_middle/src/hir/exports.rs | 28 ------------------- compiler/rustc_middle/src/hir/mod.rs | 1 - compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/metadata.rs | 24 ++++++++++++++++ compiler/rustc_middle/src/query/mod.rs | 8 +++--- compiler/rustc_middle/src/ty/context.rs | 3 +- compiler/rustc_middle/src/ty/mod.rs | 4 +-- compiler/rustc_middle/src/ty/query.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 4 +-- .../rustc_resolve/src/build_reduced_graph.rs | 6 ++-- compiler/rustc_resolve/src/imports.rs | 6 ++-- compiler/rustc_resolve/src/lib.rs | 12 ++++---- src/librustdoc/visit_ast.rs | 2 +- 17 files changed, 66 insertions(+), 64 deletions(-) delete mode 100644 compiler/rustc_middle/src/hir/exports.rs create mode 100644 compiler/rustc_middle/src/metadata.rs diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 91696088cdd61..0bfd5628b35b8 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -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}; @@ -1082,7 +1082,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn for_each_module_child( &self, id: DefIndex, - mut callback: impl FnMut(Export), + mut callback: impl FnMut(ModChild), sess: &Session, ) { if let Some(data) = &self.root.proc_macro_data { @@ -1096,7 +1096,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { 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; @@ -1117,7 +1122,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let vis = self.get_visibility(child_index); let span = self.get_span(child_index, sess); - callback(Export { ident, res, vis, span }); + callback(ModChild { ident, res, vis, span }); // For non-re-export structs and variants add their constructors to children. // Re-export lists automatically contain constructors when necessary. @@ -1129,7 +1134,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); let vis = self.get_visibility(ctor_def_id.index); - callback(Export { res: ctor_res, vis, ident, span }); + callback(ModChild { ident, res: ctor_res, vis, span }); } } DefKind::Variant => { @@ -1154,7 +1159,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 }); } _ => {} } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index f0d87241dd33f..395f954b43043 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -7,7 +7,7 @@ use rustc_data_structures::stable_map::FxHashMap; 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}; @@ -309,7 +309,7 @@ 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<_>, child: &Export, parent: DefId| { + let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &ModChild, parent: DefId| { if !child.vis.is_public() { return; } @@ -388,7 +388,7 @@ impl CStore { self.get_crate_data(def.krate).get_visibility(def.index) } - pub fn module_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec { + pub fn module_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec { let mut result = vec![]; self.get_crate_data(def_id.krate).for_each_module_child( def_id.index, diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 47fb254da9ab5..b70c78cc8ad2f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -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(), } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index fa44cbc2d55e5..d2081827c147f 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -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; @@ -350,7 +350,7 @@ enum EntryKind { Union(Lazy, ReprOptions), Fn(Lazy), ForeignFn(Lazy), - Mod(Lazy<[Export]>), + Mod(Lazy<[ModChild]>), MacroDef(Lazy), ProcMacro(MacroKind), Closure, diff --git a/compiler/rustc_middle/src/hir/exports.rs b/compiler/rustc_middle/src/hir/exports.rs deleted file mode 100644 index f37b976fba68d..0000000000000 --- a/compiler/rustc_middle/src/hir/exports.rs +++ /dev/null @@ -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>; - -#[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, -} diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 95d7273b17b44..557dc25528f13 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -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; diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index e6dd4e484cc9c..920eca7a71772 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -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; diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs new file mode 100644 index 0000000000000..6dcdc58c72d82 --- /dev/null +++ b/compiler/rustc_middle/src/metadata.rs @@ -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, +} diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 33e7e9dd6e020..7108f662cd3ea 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -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 module_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 { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index dd571e29bf695..86ad573b5d748 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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 diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 78ccfbd5e8cdc..f5f55dcf38cf4 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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, pub maybe_unused_trait_imports: FxHashSet, pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>, - pub export_map: ExportMap, + pub reexport_map: FxHashMap>, pub glob_map: FxHashMap>, /// Extern prelude entries. The value is `true` if the entry was introduced /// via `extern crate` item and not `--extern` option or compiler built-in. diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 3af1b3a044024..4a38d1c422f92 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -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; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 183a5a205ec82..16418e627f2dc 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -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() { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 5de8b39f2ae98..944e71851840c 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -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}; @@ -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. diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index bf4cece8bde8d..2832f59a5efc6 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -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); } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b46a93c06734b..37be0e228d27a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -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, - export_map: ExportMap, + reexport_map: FxHashMap>, trait_map: NodeMap>, /// 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(), diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 8e29cb16a400f..6f1736afc3bdc 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -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) {