Rollup merge of #112108 - GuillaumeGomez:reexport-doc-hidden-private, r=notriddle
Fix re-export of doc hidden item inside private item not displayed This PR fixes this bug: ```rust mod private_module { #[doc(hidden)] pub struct Public; } pub use crate::private_module::Public as Foo; ``` `pub use crate::private_module::Public as Foo;` should be visible in the generated doc (and not inlined!) but currently isn't. This PR fixes it. r? `@notriddle`
This commit is contained in:
commit
1d643e16c2
@ -267,6 +267,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||||||
let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline)
|
let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline)
|
||||||
|| use_attrs.lists(sym::doc).has_word(sym::hidden);
|
|| use_attrs.lists(sym::doc).has_word(sym::hidden);
|
||||||
|
|
||||||
|
if is_no_inline {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// For cross-crate impl inlining we need to know whether items are
|
// For cross-crate impl inlining we need to know whether items are
|
||||||
// reachable in documentation -- a previously unreachable item can be
|
// reachable in documentation -- a previously unreachable item can be
|
||||||
// made reachable by cross-crate inlining which we're checking here.
|
// made reachable by cross-crate inlining which we're checking here.
|
||||||
@ -281,15 +285,21 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did);
|
let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did);
|
||||||
let is_hidden = inherits_doc_hidden(tcx, res_did, None);
|
let is_hidden = tcx.is_doc_hidden(ori_res_did);
|
||||||
|
let item = tcx.hir().get_by_def_id(res_did);
|
||||||
|
|
||||||
|
if !please_inline {
|
||||||
|
let inherits_hidden = inherits_doc_hidden(tcx, res_did, None);
|
||||||
// Only inline if requested or if the item would otherwise be stripped.
|
// Only inline if requested or if the item would otherwise be stripped.
|
||||||
if (!please_inline && !is_private && !is_hidden) || is_no_inline {
|
//
|
||||||
|
// If it's a doc hidden module, we need to keep it in case some of its inner items
|
||||||
|
// are re-exported.
|
||||||
|
if (!is_private && !inherits_hidden) || (
|
||||||
|
is_hidden &&
|
||||||
|
!matches!(item, Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_), .. }))
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
} else if let Some(item_def_id) = reexport_chain(tcx, def_id, res_did).iter()
|
||||||
|
|
||||||
if !please_inline &&
|
|
||||||
let Some(item_def_id) = reexport_chain(tcx, def_id, res_did).iter()
|
|
||||||
.flat_map(|reexport| reexport.id()).map(|id| id.expect_local())
|
.flat_map(|reexport| reexport.id()).map(|id| id.expect_local())
|
||||||
.chain(iter::once(res_did)).nth(1) &&
|
.chain(iter::once(res_did)).nth(1) &&
|
||||||
item_def_id != def_id &&
|
item_def_id != def_id &&
|
||||||
@ -303,9 +313,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||||||
// The imported item is public and not `doc(hidden)` so no need to inline it.
|
// The imported item is public and not `doc(hidden)` so no need to inline it.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let is_bang_macro = matches!(
|
let is_bang_macro = matches!(
|
||||||
tcx.hir().get_by_def_id(res_did),
|
item,
|
||||||
Node::Item(&hir::Item { kind: hir::ItemKind::Macro(_, MacroKind::Bang), .. })
|
Node::Item(&hir::Item { kind: hir::ItemKind::Macro(_, MacroKind::Bang), .. })
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -317,12 +328,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||||||
// Bang macros are handled a bit on their because of how they are handled by the
|
// Bang macros are handled a bit on their because of how they are handled by the
|
||||||
// compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
|
// compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
|
||||||
// `#[doc(inline)]`, then we don't inline it.
|
// `#[doc(inline)]`, then we don't inline it.
|
||||||
Node::Item(_)
|
Node::Item(_) if is_bang_macro && !please_inline && renamed.is_some() && is_hidden => {
|
||||||
if is_bang_macro
|
|
||||||
&& !please_inline
|
|
||||||
&& renamed.is_some()
|
|
||||||
&& self.cx.tcx.is_doc_hidden(ori_res_did) =>
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => {
|
Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => {
|
||||||
@ -455,6 +461,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||||||
is_glob,
|
is_glob,
|
||||||
please_inline,
|
please_inline,
|
||||||
) {
|
) {
|
||||||
|
debug!("Inlining {:?}", item.owner_id.def_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
tests/rustdoc/reexport-doc-hidden-inside-private.rs
Normal file
16
tests/rustdoc/reexport-doc-hidden-inside-private.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// This test ensures that a re-export of `#[doc(hidden)]` item inside a private
|
||||||
|
// module will still be displayed (the re-export, not the item).
|
||||||
|
|
||||||
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
mod private_module {
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub struct Public;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has 'foo/index.html'
|
||||||
|
// @has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;'
|
||||||
|
pub use crate::private_module::Public as Foo;
|
||||||
|
// Glob re-exports with no visible items should not be displayed.
|
||||||
|
// @count - '//*[@class="item-table"]/li' 1
|
||||||
|
pub use crate::private_module::*;
|
Loading…
x
Reference in New Issue
Block a user