Skip to content

Commit c3c9f8f

Browse files
Fix invalid handling of nested items with --document-private-items
1 parent f91d02b commit c3c9f8f

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

src/librustdoc/visit_ast.rs

+35-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hir::{Node, CRATE_HIR_ID};
1010
use rustc_middle::hir::nested_filter;
1111
use rustc_middle::ty::TyCtxt;
1212
use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
13+
use rustc_span::hygiene::MacroKind;
1314
use rustc_span::symbol::{kw, sym, Symbol};
1415
use rustc_span::Span;
1516

@@ -87,6 +88,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> {
8788
inside_public_path: bool,
8889
exact_paths: DefIdMap<Vec<Symbol>>,
8990
modules: Vec<Module<'tcx>>,
91+
is_importable_from_parent: bool,
9092
}
9193

9294
impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
@@ -107,6 +109,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
107109
inside_public_path: true,
108110
exact_paths: Default::default(),
109111
modules: vec![om],
112+
is_importable_from_parent: true,
110113
}
111114
}
112115

@@ -319,11 +322,23 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
319322
renamed: Option<Symbol>,
320323
parent_id: Option<LocalDefId>,
321324
) {
322-
self.modules
323-
.last_mut()
324-
.unwrap()
325-
.items
326-
.insert((item.owner_id.def_id, renamed), (item, renamed, parent_id));
325+
if self.is_importable_from_parent
326+
// If we're inside an item, only impl blocks and `macro_rules!` with the `macro_export`
327+
// attribute can still be visible.
328+
|| match item.kind {
329+
hir::ItemKind::Impl(..) => true,
330+
hir::ItemKind::Macro(_, MacroKind::Bang) => {
331+
self.cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export)
332+
}
333+
_ => false,
334+
}
335+
{
336+
self.modules
337+
.last_mut()
338+
.unwrap()
339+
.items
340+
.insert((item.owner_id.def_id, renamed), (item, renamed, parent_id));
341+
}
327342
}
328343

329344
fn visit_item_inner(
@@ -485,7 +500,22 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
485500

486501
fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
487502
self.visit_item_inner(i, None, None);
503+
let new_value = if self.is_importable_from_parent {
504+
matches!(
505+
i.kind,
506+
hir::ItemKind::Mod(..)
507+
| hir::ItemKind::ForeignMod { .. }
508+
| hir::ItemKind::Impl(..)
509+
| hir::ItemKind::Trait(..)
510+
)
511+
} else {
512+
// Whatever the context, if it's an impl block, the items inside it can be used so they
513+
// should be visible.
514+
matches!(i.kind, hir::ItemKind::Impl(..))
515+
};
516+
let prev = mem::replace(&mut self.is_importable_from_parent, new_value);
488517
walk_item(self, i);
518+
self.is_importable_from_parent = prev;
489519
}
490520

491521
fn visit_mod(&mut self, _: &hir::Mod<'tcx>, _: Span, _: hir::HirId) {

0 commit comments

Comments
 (0)