From 88493d26657557b1e328be2057594db79cb2f594 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 16 May 2023 14:35:27 +0200 Subject: [PATCH] Only keep impl blocks from bodies --- src/librustdoc/visit_ast.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index ff13daa6db4..8f8dc6b7090 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet}; -use rustc_hir::intravisit::{walk_item, Visitor}; +use rustc_hir::intravisit::{walk_body, walk_item, Visitor}; use rustc_hir::{Node, CRATE_HIR_ID}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; @@ -106,6 +106,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> { exact_paths: DefIdMap>, modules: Vec>, is_importable_from_parent: bool, + inside_body: bool, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { @@ -129,6 +130,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { exact_paths: Default::default(), modules: vec![om], is_importable_from_parent: true, + inside_body: false, } } @@ -368,6 +370,26 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { import_id: Option, ) { debug!("visiting item {:?}", item); + if self.inside_body { + // Only impls can be "seen" outside a body. For example: + // + // ``` + // struct Bar; + // + // fn foo() { + // impl Bar { fn bar() {} } + // } + // Bar::bar(); + // ``` + if let hir::ItemKind::Impl(impl_) = item.kind && + // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick + // them up regardless of where they're located. + impl_.of_trait.is_none() + { + self.add_to_current_mod(item, None, None); + } + return; + } let name = renamed.unwrap_or(item.ident.name); let tcx = self.cx.tcx; @@ -564,4 +586,10 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> { fn visit_lifetime(&mut self, _: &hir::Lifetime) { // Unneeded. } + + fn visit_body(&mut self, b: &'tcx hir::Body<'tcx>) { + let prev = mem::replace(&mut self.inside_body, true); + walk_body(self, b); + self.inside_body = prev; + } }