about summary refs log tree commit diff
path: root/src/librustdoc/visit_ast.rs
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume.gomez@huawei.com>2023-05-16 14:35:27 +0200
committerGuillaume Gomez <guillaume.gomez@huawei.com>2023-05-16 14:35:27 +0200
commit88493d26657557b1e328be2057594db79cb2f594 (patch)
treeda5a724958ca0b5681c964ec0f18f13cba1aa108 /src/librustdoc/visit_ast.rs
parent69fef92ab2f287f072b66fb7b4f62c8bb4acba43 (diff)
downloadrust-88493d26657557b1e328be2057594db79cb2f594.tar.gz
rust-88493d26657557b1e328be2057594db79cb2f594.zip
Only keep impl blocks from bodies
Diffstat (limited to 'src/librustdoc/visit_ast.rs')
-rw-r--r--src/librustdoc/visit_ast.rs30
1 files changed, 29 insertions, 1 deletions
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<Vec<Symbol>>,
     modules: Vec<Module<'tcx>>,
     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<LocalDefId>,
     ) {
         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;
+    }
 }