Fix invalid handling of nested items with --document-private-items

This commit is contained in:
Guillaume Gomez 2023-04-17 14:34:50 +02:00
parent f91d02b153
commit c3c9f8f5f8

View File

@ -10,6 +10,7 @@
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;
@ -87,6 +88,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> {
inside_public_path: bool,
exact_paths: DefIdMap<Vec<Symbol>>,
modules: Vec<Module<'tcx>>,
is_importable_from_parent: bool,
}
impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
@ -107,6 +109,7 @@ pub(crate) fn new(cx: &'a mut core::DocContext<'tcx>) -> RustdocVisitor<'a, 'tcx
inside_public_path: true,
exact_paths: Default::default(),
modules: vec![om],
is_importable_from_parent: true,
}
}
@ -319,11 +322,23 @@ fn add_to_current_mod(
renamed: Option<Symbol>,
parent_id: Option<LocalDefId>,
) {
self.modules
.last_mut()
.unwrap()
.items
.insert((item.owner_id.def_id, renamed), (item, renamed, parent_id));
if self.is_importable_from_parent
// If we're inside an item, only impl blocks and `macro_rules!` with the `macro_export`
// attribute can still be visible.
|| match item.kind {
hir::ItemKind::Impl(..) => true,
hir::ItemKind::Macro(_, MacroKind::Bang) => {
self.cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export)
}
_ => false,
}
{
self.modules
.last_mut()
.unwrap()
.items
.insert((item.owner_id.def_id, renamed), (item, renamed, parent_id));
}
}
fn visit_item_inner(
@ -485,7 +500,22 @@ fn nested_visit_map(&mut self) -> Self::Map {
fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
self.visit_item_inner(i, None, None);
let new_value = if self.is_importable_from_parent {
matches!(
i.kind,
hir::ItemKind::Mod(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::Impl(..)
| hir::ItemKind::Trait(..)
)
} else {
// Whatever the context, if it's an impl block, the items inside it can be used so they
// should be visible.
matches!(i.kind, hir::ItemKind::Impl(..))
};
let prev = mem::replace(&mut self.is_importable_from_parent, new_value);
walk_item(self, i);
self.is_importable_from_parent = prev;
}
fn visit_mod(&mut self, _: &hir::Mod<'tcx>, _: Span, _: hir::HirId) {