rustdoc: do not mark the contents of a skipped module as inlined
This commit is contained in:
parent
5c54be35c6
commit
2289955546
@ -145,6 +145,7 @@ pub(crate) fn try_inline_glob(
|
||||
cx: &mut DocContext<'_>,
|
||||
res: Res,
|
||||
visited: &mut FxHashSet<DefId>,
|
||||
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
|
||||
) -> Option<Vec<clean::Item>> {
|
||||
let did = res.opt_def_id()?;
|
||||
if did.is_local() {
|
||||
@ -153,8 +154,17 @@ pub(crate) fn try_inline_glob(
|
||||
|
||||
match res {
|
||||
Res::Def(DefKind::Mod, did) => {
|
||||
let m = build_module(cx, did, visited);
|
||||
Some(m.items)
|
||||
let mut items = build_module_items(cx, did, visited, inlined_names);
|
||||
items.drain_filter(|item| {
|
||||
if let Some(name) = item.name {
|
||||
// If an item with the same type and name already exists,
|
||||
// it takes priority over the inlined stuff.
|
||||
!inlined_names.insert((item.type_(), name))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
Some(items)
|
||||
}
|
||||
// glob imports on things like enums aren't inlined even for local exports, so just bail
|
||||
_ => None,
|
||||
@ -517,6 +527,18 @@ fn build_module(
|
||||
did: DefId,
|
||||
visited: &mut FxHashSet<DefId>,
|
||||
) -> clean::Module {
|
||||
let items = build_module_items(cx, did, visited, &mut FxHashSet::default());
|
||||
|
||||
let span = clean::Span::new(cx.tcx.def_span(did));
|
||||
clean::Module { items, span }
|
||||
}
|
||||
|
||||
fn build_module_items(
|
||||
cx: &mut DocContext<'_>,
|
||||
did: DefId,
|
||||
visited: &mut FxHashSet<DefId>,
|
||||
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
|
||||
) -> Vec<clean::Item> {
|
||||
let mut items = Vec::new();
|
||||
|
||||
// If we're re-exporting a re-export it may actually re-export something in
|
||||
@ -526,7 +548,13 @@ fn build_module(
|
||||
if item.vis.is_public() {
|
||||
let res = item.res.expect_non_local();
|
||||
if let Some(def_id) = res.mod_def_id() {
|
||||
if did == def_id || !visited.insert(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
|
||||
// inline it, or mark any of its contents as visited.
|
||||
if did == def_id
|
||||
|| inlined_names.contains(&(ItemType::Module, item.ident.name))
|
||||
|| !visited.insert(def_id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -563,8 +591,7 @@ fn build_module(
|
||||
}
|
||||
}
|
||||
|
||||
let span = clean::Span::new(cx.tcx.def_span(did));
|
||||
clean::Module { items, span }
|
||||
items
|
||||
}
|
||||
|
||||
pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
|
||||
|
@ -71,7 +71,7 @@ impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> {
|
||||
// priority to the not-imported one, so we should, too.
|
||||
items.extend(self.items.iter().flat_map(|(item, renamed)| {
|
||||
// First, lower everything other than imports.
|
||||
if matches!(item.kind, hir::ItemKind::Use(..)) {
|
||||
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
|
||||
return Vec::new();
|
||||
}
|
||||
let v = clean_maybe_renamed_item(cx, item, *renamed);
|
||||
@ -84,20 +84,13 @@ impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> {
|
||||
}));
|
||||
items.extend(self.items.iter().flat_map(|(item, renamed)| {
|
||||
// Now we actually lower the imports, skipping everything else.
|
||||
if !matches!(item.kind, hir::ItemKind::Use(..)) {
|
||||
return Vec::new();
|
||||
if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind {
|
||||
let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
|
||||
clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted)
|
||||
} else {
|
||||
// skip everything else
|
||||
Vec::new()
|
||||
}
|
||||
let mut v = clean_maybe_renamed_item(cx, item, *renamed);
|
||||
v.drain_filter(|item| {
|
||||
if let Some(name) = item.name {
|
||||
// If an item with the same type and name already exists,
|
||||
// it takes priority over the inlined stuff.
|
||||
!inserted.insert((item.type_(), name))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
v
|
||||
}));
|
||||
|
||||
// determine if we should display the inner contents or
|
||||
@ -1962,7 +1955,7 @@ fn clean_maybe_renamed_item<'tcx>(
|
||||
return clean_extern_crate(item, name, orig_name, cx);
|
||||
}
|
||||
ItemKind::Use(path, kind) => {
|
||||
return clean_use_statement(item, name, path, kind, cx);
|
||||
return clean_use_statement(item, name, path, kind, cx, &mut FxHashSet::default());
|
||||
}
|
||||
_ => unreachable!("not yet converted"),
|
||||
};
|
||||
@ -2083,6 +2076,7 @@ fn clean_use_statement<'tcx>(
|
||||
path: &hir::Path<'tcx>,
|
||||
kind: hir::UseKind,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
|
||||
) -> Vec<Item> {
|
||||
// We need this comparison because some imports (for std types for example)
|
||||
// are "inserted" as well but directly by the compiler and they should not be
|
||||
@ -2148,7 +2142,8 @@ fn clean_use_statement<'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) {
|
||||
if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited, inlined_names)
|
||||
{
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
13
src/test/rustdoc/auxiliary/issue-100204-aux.rs
Normal file
13
src/test/rustdoc/auxiliary/issue-100204-aux.rs
Normal file
@ -0,0 +1,13 @@
|
||||
#![crate_name="first"]
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::Bot;
|
||||
}
|
||||
|
||||
pub struct Bot;
|
||||
|
||||
impl Bot {
|
||||
pub fn new() -> Bot {
|
||||
Bot
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
// aux-build:issue-100204-aux.rs
|
||||
// build-aux-docs
|
||||
// ignore-cross-compile
|
||||
|
||||
#![crate_name="second"]
|
||||
|
||||
extern crate first;
|
||||
|
||||
pub mod prelude {}
|
||||
|
||||
// @has first/struct.Bot.html '//h4[@class="code-header"]' 'pub fn new() -> Bot'
|
||||
// @has second/struct.Bot.html '//h4[@class="code-header"]' 'pub fn new() -> Bot'
|
||||
#[doc(inline)]
|
||||
pub use first::*;
|
Loading…
x
Reference in New Issue
Block a user