summaryrefslogtreecommitdiff
path: root/src/librustdoc/visit_ast.rs
diff options
context:
space:
mode:
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;
+ }
}