diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-04-18 06:44:47 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-18 06:44:47 +0200 |
| commit | d6468916c0bdd98148970c8d6e51ecc935b9f47a (patch) | |
| tree | cbcfe37db5d9b2d7335d9d2aecaafd83f2eba656 /src | |
| parent | 1e3a38438ab4ee7c313a32e5b065f81c0a97622d (diff) | |
| parent | c456e15855b538aecff7b088dda6144dcde9d6ca (diff) | |
| download | rust-d6468916c0bdd98148970c8d6e51ecc935b9f47a.tar.gz rust-d6468916c0bdd98148970c8d6e51ecc935b9f47a.zip | |
Rollup merge of #110450 - GuillaumeGomez:fix-nested-items-on-private-doc, r=notriddle,jyn514
rustdoc: Fix invalid handling of nested items with `--document-private-items` Fixes #110422. The problem is that only impl block and re-exported `macro_rules!` items are "visible" as nested items. This PR adds the missing checks to handle this correctly. cc `@compiler-errors` r? `@notriddle`
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/visit_ast.rs | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index f54b70b417d..a6089680fae 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -10,6 +10,7 @@ use rustc_hir::{Node, CRATE_HIR_ID}; 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 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { inside_public_path: true, exact_paths: Default::default(), modules: vec![om], + is_importable_from_parent: true, } } @@ -319,11 +322,23 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { 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( @@ -331,7 +346,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { item: &'tcx hir::Item<'_>, renamed: Option<Symbol>, import_id: Option<LocalDefId>, - ) -> bool { + ) { debug!("visiting item {:?}", item); let name = renamed.unwrap_or(item.ident.name); let tcx = self.cx.tcx; @@ -448,7 +463,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } } - true } fn visit_foreign_item_inner( @@ -485,9 +499,23 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> { } fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) { - if self.visit_item_inner(i, None, None) { - walk_item(self, i); - } + 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) { |
