Skip to content

Commit aaa9bb9

Browse files
committed
Auto merge of #106952 - petrochenkov:docglob, r=notriddle,GuillaumeGomez
rustdoc: Fix glob import inlining Filter away names that are not actually imported by the glob, e.g. because they are shadowed by something else. Fixes the issue found in #94857 (comment).
2 parents e08b379 + 3b0d306 commit aaa9bb9

File tree

4 files changed

+28
-4
lines changed

4 files changed

+28
-4
lines changed

src/librustdoc/clean/inline.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_ast as ast;
99
use rustc_data_structures::fx::FxHashSet;
1010
use rustc_hir as hir;
1111
use rustc_hir::def::{DefKind, Res};
12-
use rustc_hir::def_id::DefId;
12+
use rustc_hir::def_id::{DefId, LocalDefId};
1313
use rustc_hir::Mutability;
1414
use rustc_metadata::creader::{CStore, LoadedMacro};
1515
use rustc_middle::ty::{self, TyCtxt};
@@ -162,6 +162,7 @@ pub(crate) fn try_inline(
162162
pub(crate) fn try_inline_glob(
163163
cx: &mut DocContext<'_>,
164164
res: Res,
165+
current_mod: LocalDefId,
165166
visited: &mut FxHashSet<DefId>,
166167
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
167168
) -> Option<Vec<clean::Item>> {
@@ -172,7 +173,16 @@ pub(crate) fn try_inline_glob(
172173

173174
match res {
174175
Res::Def(DefKind::Mod, did) => {
175-
let mut items = build_module_items(cx, did, visited, inlined_names);
176+
// Use the set of module reexports to filter away names that are not actually
177+
// reexported by the glob, e.g. because they are shadowed by something else.
178+
let reexports = cx
179+
.tcx
180+
.module_reexports(current_mod)
181+
.unwrap_or_default()
182+
.iter()
183+
.filter_map(|child| child.res.opt_def_id())
184+
.collect();
185+
let mut items = build_module_items(cx, did, visited, inlined_names, Some(&reexports));
176186
items.drain_filter(|item| {
177187
if let Some(name) = item.name {
178188
// If an item with the same type and name already exists,
@@ -563,7 +573,7 @@ fn build_module(
563573
did: DefId,
564574
visited: &mut FxHashSet<DefId>,
565575
) -> clean::Module {
566-
let items = build_module_items(cx, did, visited, &mut FxHashSet::default());
576+
let items = build_module_items(cx, did, visited, &mut FxHashSet::default(), None);
567577

568578
let span = clean::Span::new(cx.tcx.def_span(did));
569579
clean::Module { items, span }
@@ -574,6 +584,7 @@ fn build_module_items(
574584
did: DefId,
575585
visited: &mut FxHashSet<DefId>,
576586
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
587+
allowed_def_ids: Option<&FxHashSet<DefId>>,
577588
) -> Vec<clean::Item> {
578589
let mut items = Vec::new();
579590

@@ -583,6 +594,11 @@ fn build_module_items(
583594
for &item in cx.tcx.module_children(did).iter() {
584595
if item.vis.is_public() {
585596
let res = item.res.expect_non_local();
597+
if let Some(def_id) = res.opt_def_id()
598+
&& let Some(allowed_def_ids) = allowed_def_ids
599+
&& !allowed_def_ids.contains(&def_id) {
600+
continue;
601+
}
586602
if let Some(def_id) = res.mod_def_id() {
587603
// If we're inlining a glob import, it's possible to have
588604
// two distinct modules with the same name. We don't want to

src/librustdoc/clean/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2441,7 +2441,8 @@ fn clean_use_statement_inner<'tcx>(
24412441
let inner = if kind == hir::UseKind::Glob {
24422442
if !denied {
24432443
let mut visited = FxHashSet::default();
2444-
if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited, inlined_names)
2444+
if let Some(items) =
2445+
inline::try_inline_glob(cx, path.res, current_mod, &mut visited, inlined_names)
24452446
{
24462447
return items;
24472448
}

tests/rustdoc/inline_cross/auxiliary/cross-glob.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
pub struct SomeStruct;
44

55
pub fn some_fn() {}
6+
7+
pub enum Shadowed {}

tests/rustdoc/inline_cross/cross-glob.rs

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ extern crate inner;
66

77
// @has cross_glob/struct.SomeStruct.html
88
// @has cross_glob/fn.some_fn.html
9+
// @!has cross_glob/enum.Shadowed.html
910
// @!has cross_glob/index.html '//code' 'pub use inner::*;'
1011
#[doc(inline)]
1112
pub use inner::*;
13+
14+
// This type shadows the glob-imported enum `Shadowed`.
15+
// @has cross_glob/type.Shadowed.html
16+
pub type Shadowed = u8;

0 commit comments

Comments
 (0)