diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 5ba7efc37f8..4e5d21049a0 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -17,7 +17,7 @@ use rustc_session::utils::NativeLibKind; use rustc_session::{Session, StableCrateId}; use rustc_span::hygiene::{ExpnHash, ExpnId}; use rustc_span::source_map::{Span, Spanned}; -use rustc_span::symbol::Symbol; +use rustc_span::symbol::{kw, Symbol}; use rustc_data_structures::sync::Lrc; use smallvec::SmallVec; @@ -295,6 +295,10 @@ pub fn provide(providers: &mut Providers) { use std::collections::vec_deque::VecDeque; let mut visible_parent_map: DefIdMap = Default::default(); + // This is a secondary visible_parent_map, storing the DefId of parents that re-export + // the child as `_`. Since we prefer parents that don't do this, merge this map at the + // end, only if we're missing any keys from the former. + let mut fallback_map: DefIdMap = Default::default(); // Issue 46112: We want the map to prefer the shortest // paths when reporting the path to an item. Therefore we @@ -317,12 +321,17 @@ pub 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| { - if !child.vis.is_public() { + let mut add_child = |bfs_queue: &mut VecDeque<_>, export: &Export, parent: DefId| { + if !export.vis.is_public() { return; } - if let Some(child) = child.res.opt_def_id() { + if let Some(child) = export.res.opt_def_id() { + if export.ident.name == kw::Underscore { + fallback_map.insert(child, parent); + return; + } + match visible_parent_map.entry(child) { Entry::Occupied(mut entry) => { // If `child` is defined in crate `cnum`, ensure @@ -345,6 +354,12 @@ pub fn provide(providers: &mut Providers) { } } + // Fill in any missing entries with the (less preferable) path ending in `::_`. + // We still use this path in a diagnostic that suggests importing `::*`. + for (child, parent) in fallback_map { + visible_parent_map.entry(child).or_insert(parent); + } + visible_parent_map },