about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/clean/inline.rs22
-rw-r--r--src/librustdoc/clean/mod.rs3
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/cross-glob.rs2
-rw-r--r--tests/rustdoc/inline_cross/cross-glob.rs5
4 files changed, 28 insertions, 4 deletions
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index c6939326144..b3b09331233 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -9,7 +9,7 @@ use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::Mutability;
 use rustc_metadata::creader::{CStore, LoadedMacro};
 use rustc_middle::ty::{self, TyCtxt};
@@ -162,6 +162,7 @@ pub(crate) fn try_inline(
 pub(crate) fn try_inline_glob(
     cx: &mut DocContext<'_>,
     res: Res,
+    current_mod: LocalDefId,
     visited: &mut FxHashSet<DefId>,
     inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
 ) -> Option<Vec<clean::Item>> {
@@ -172,7 +173,16 @@ pub(crate) fn try_inline_glob(
 
     match res {
         Res::Def(DefKind::Mod, did) => {
-            let mut items = build_module_items(cx, did, visited, inlined_names);
+            // Use the set of module reexports to filter away names that are not actually
+            // reexported by the glob, e.g. because they are shadowed by something else.
+            let reexports = cx
+                .tcx
+                .module_reexports(current_mod)
+                .unwrap_or_default()
+                .iter()
+                .filter_map(|child| child.res.opt_def_id())
+                .collect();
+            let mut items = build_module_items(cx, did, visited, inlined_names, Some(&reexports));
             items.drain_filter(|item| {
                 if let Some(name) = item.name {
                     // If an item with the same type and name already exists,
@@ -563,7 +573,7 @@ fn build_module(
     did: DefId,
     visited: &mut FxHashSet<DefId>,
 ) -> clean::Module {
-    let items = build_module_items(cx, did, visited, &mut FxHashSet::default());
+    let items = build_module_items(cx, did, visited, &mut FxHashSet::default(), None);
 
     let span = clean::Span::new(cx.tcx.def_span(did));
     clean::Module { items, span }
@@ -574,6 +584,7 @@ fn build_module_items(
     did: DefId,
     visited: &mut FxHashSet<DefId>,
     inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
+    allowed_def_ids: Option<&FxHashSet<DefId>>,
 ) -> Vec<clean::Item> {
     let mut items = Vec::new();
 
@@ -583,6 +594,11 @@ fn build_module_items(
     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()
+                && let Some(allowed_def_ids) = allowed_def_ids
+                && !allowed_def_ids.contains(&def_id) {
+                continue;
+            }
             if let Some(def_id) = res.mod_def_id() {
                 // If we're inlining a glob import, it's possible to have
                 // two distinct modules with the same name. We don't want to
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 415e7d5a360..20984696b6c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2441,7 +2441,8 @@ fn clean_use_statement_inner<'tcx>(
     let inner = if kind == hir::UseKind::Glob {
         if !denied {
             let mut visited = FxHashSet::default();
-            if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited, inlined_names)
+            if let Some(items) =
+                inline::try_inline_glob(cx, path.res, current_mod, &mut visited, inlined_names)
             {
                 return items;
             }
diff --git a/tests/rustdoc/inline_cross/auxiliary/cross-glob.rs b/tests/rustdoc/inline_cross/auxiliary/cross-glob.rs
index cde7f68ff01..48672590a12 100644
--- a/tests/rustdoc/inline_cross/auxiliary/cross-glob.rs
+++ b/tests/rustdoc/inline_cross/auxiliary/cross-glob.rs
@@ -3,3 +3,5 @@
 pub struct SomeStruct;
 
 pub fn some_fn() {}
+
+pub enum Shadowed {}
diff --git a/tests/rustdoc/inline_cross/cross-glob.rs b/tests/rustdoc/inline_cross/cross-glob.rs
index f97da11a901..7a519d2d255 100644
--- a/tests/rustdoc/inline_cross/cross-glob.rs
+++ b/tests/rustdoc/inline_cross/cross-glob.rs
@@ -6,6 +6,11 @@ extern crate inner;
 
 // @has cross_glob/struct.SomeStruct.html
 // @has cross_glob/fn.some_fn.html
+// @!has cross_glob/enum.Shadowed.html
 // @!has cross_glob/index.html '//code' 'pub use inner::*;'
 #[doc(inline)]
 pub use inner::*;
+
+// This type shadows the glob-imported enum `Shadowed`.
+// @has cross_glob/type.Shadowed.html
+pub type Shadowed = u8;