Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolve: Preserve reexport chains in ModChildren #109500

Merged
merged 4 commits into from
Apr 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
_ => false,
};

ModChild { ident, res, vis, span, macro_rules }
ModChild { ident, res, vis, span, macro_rules, reexport_chain: Default::default() }
}

/// Iterates over all named children of the given module,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1327,8 +1327,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}));

if let Some(reexports) = tcx.module_reexports(local_def_id) {
assert!(!reexports.is_empty());
let reexports = tcx.module_reexports(local_def_id);
if !reexports.is_empty() {
record_array!(self.tables.module_reexports[def_id] <- reexports);
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ macro_rules! arena_types {
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
[decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
[] closure_kind_origin: (rustc_span::Span, rustc_middle::hir::place::Place<'tcx>),
[] mod_child: rustc_middle::metadata::ModChild,
]);
)
}
Expand Down
26 changes: 25 additions & 1 deletion compiler/rustc_middle/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,34 @@ use rustc_macros::HashStable;
use rustc_span::def_id::DefId;
use rustc_span::symbol::Ident;
use rustc_span::Span;
use smallvec::SmallVec;

/// A simplified version of `ImportKind` from resolve.
/// `DefId`s here correspond to `use` and `extern crate` items themselves, not their targets.
#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, HashStable)]
pub enum Reexport {
petrochenkov marked this conversation as resolved.
Show resolved Hide resolved
Single(DefId),
Glob(DefId),
ExternCrate(DefId),
MacroUse,
MacroExport,
}

impl Reexport {
pub fn id(self) -> Option<DefId> {
match self {
Reexport::Single(id) | Reexport::Glob(id) | Reexport::ExternCrate(id) => Some(id),
Reexport::MacroUse | Reexport::MacroExport => None,
}
}
}

/// 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)]
#[derive(Debug, TyEncodable, TyDecodable, HashStable)]
pub struct ModChild {
/// Name of the item.
pub ident: Ident,
Expand All @@ -24,4 +45,7 @@ pub struct ModChild {
pub span: Span,
/// A proper `macro_rules` item (not a reexport).
pub macro_rules: bool,
/// Reexport chain linking this module child to its original reexported item.
/// Empty if the module child is a proper item.
pub reexport_chain: SmallVec<[Reexport; 2]>,
}
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/query/erase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ trivial! {
rustc_hir::OwnerId,
rustc_hir::Upvar,
rustc_index::bit_set::FiniteBitSet<u32>,
rustc_middle::metadata::ModChild,
rustc_middle::middle::dependency_format::Linkage,
rustc_middle::middle::exported_symbols::SymbolExportInfo,
rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1510,7 +1510,7 @@ rustc_queries! {
desc { "getting traits in scope at a block" }
}

query module_reexports(def_id: LocalDefId) -> Option<&'tcx [ModChild]> {
query module_reexports(def_id: LocalDefId) -> &'tcx [ModChild] {
desc { |tcx| "looking up reexports of module `{}`", tcx.def_path_str(def_id.to_def_id()) }
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2502,7 +2502,7 @@ pub struct DeducedParamAttrs {

pub fn provide(providers: &mut ty::query::Providers) {
providers.module_reexports =
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map_or(&[], |v| &v[..]);
providers.maybe_unused_trait_imports =
|tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
providers.names_imported_by_glob_use = |tcx, id| {
Expand Down
16 changes: 6 additions & 10 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,16 +515,12 @@ 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);
}
if let Some(exports) = self.tcx.module_reexports(module_def_id) {
for export in exports {
if export.vis.is_accessible_from(defining_mod, self.tcx) {
if let Res::Def(def_kind, def_id) = export.res {
if let Some(def_id) = def_id.as_local() {
let vis = self.tcx.local_visibility(def_id);
self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod);
}
}
}
for export in self.tcx.module_reexports(module_def_id) {
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() {
let vis = self.tcx.local_visibility(def_id);
self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ 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, span, macro_rules } = child;
let ModChild { ident, res, vis, span, macro_rules, .. } = child;
let res = res.expect_non_local();
let expansion = self.parent_scope.expansion;
// Record primary definitions.
Expand Down
21 changes: 21 additions & 0 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ 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::span_bug;
use rustc_middle::ty;
use rustc_session::lint::builtin::{
Expand All @@ -27,6 +28,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::LocalExpnId;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::Span;
use smallvec::SmallVec;

use std::cell::Cell;
use std::{mem, ptr};
Expand Down Expand Up @@ -190,6 +192,17 @@ impl<'a> Import<'a> {
ImportKind::MacroUse | ImportKind::MacroExport => None,
}
}

fn simplify(&self, r: &Resolver<'_, '_>) -> Reexport {
let to_def_id = |id| r.local_def_id(id).to_def_id();
match self.kind {
ImportKind::Single { id, .. } => Reexport::Single(to_def_id(id)),
ImportKind::Glob { id, .. } => Reexport::Glob(to_def_id(id)),
ImportKind::ExternCrate { id, .. } => Reexport::ExternCrate(to_def_id(id)),
ImportKind::MacroUse => Reexport::MacroUse,
ImportKind::MacroExport => Reexport::MacroExport,
}
}
}

/// Records information about the resolution of a name in a namespace of a module.
Expand Down Expand Up @@ -1252,12 +1265,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {

module.for_each_child(self, |this, ident, _, binding| {
if let Some(res) = this.is_reexport(binding) {
let mut reexport_chain = SmallVec::new();
let mut next_binding = binding;
while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
reexport_chain.push(import.simplify(this));
next_binding = binding;
}

reexports.push(ModChild {
ident,
res,
vis: binding.vis,
span: binding.span,
macro_rules: false,
reexport_chain,
});
}
});
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/collections/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,10 @@ pub use alloc_crate::collections::{BTreeMap, BTreeSet, BinaryHeap};
pub use alloc_crate::collections::{LinkedList, VecDeque};

#[stable(feature = "rust1", since = "1.0.0")]
#[doc(inline)]
pub use self::hash_map::HashMap;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(inline)]
pub use self::hash_set::HashSet;

#[stable(feature = "try_reserve", since = "1.57.0")]
Expand Down
3 changes: 1 addition & 2 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ pub(crate) fn try_inline_glob(
let reexports = cx
.tcx
.module_reexports(current_mod)
.unwrap_or_default()
.iter()
.filter_map(|child| child.res.opt_def_id())
.collect();
Expand Down Expand Up @@ -558,7 +557,7 @@ 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() {
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.opt_def_id()
Expand Down
Loading