Skip to content

Commit 54a4976

Browse files
authored
Rollup merge of rust-lang#111642 - GuillaumeGomez:only-impl-from-bodies, r=notriddle
[rustdoc] Only keep impl blocks from bodies Fixes rust-lang#111415. The problem was that we kept everything inside bodies whereas only impl blocks are actually accessible from outside bodies. r? `@notriddle`
2 parents d2e52ea + 0f1d4b5 commit 54a4976

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

src/librustdoc/visit_ast.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
55
use rustc_hir as hir;
66
use rustc_hir::def::{DefKind, Res};
77
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet};
8-
use rustc_hir::intravisit::{walk_item, Visitor};
8+
use rustc_hir::intravisit::{walk_body, walk_item, Visitor};
99
use rustc_hir::{Node, CRATE_HIR_ID};
1010
use rustc_middle::hir::nested_filter;
1111
use rustc_middle::ty::TyCtxt;
@@ -106,6 +106,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> {
106106
exact_paths: DefIdMap<Vec<Symbol>>,
107107
modules: Vec<Module<'tcx>>,
108108
is_importable_from_parent: bool,
109+
inside_body: bool,
109110
}
110111

111112
impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
@@ -129,6 +130,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
129130
exact_paths: Default::default(),
130131
modules: vec![om],
131132
is_importable_from_parent: true,
133+
inside_body: false,
132134
}
133135
}
134136

@@ -368,6 +370,26 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
368370
import_id: Option<LocalDefId>,
369371
) {
370372
debug!("visiting item {:?}", item);
373+
if self.inside_body {
374+
// Only impls can be "seen" outside a body. For example:
375+
//
376+
// ```
377+
// struct Bar;
378+
//
379+
// fn foo() {
380+
// impl Bar { fn bar() {} }
381+
// }
382+
// Bar::bar();
383+
// ```
384+
if let hir::ItemKind::Impl(impl_) = item.kind &&
385+
// Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
386+
// them up regardless of where they're located.
387+
impl_.of_trait.is_none()
388+
{
389+
self.add_to_current_mod(item, None, None);
390+
}
391+
return;
392+
}
371393
let name = renamed.unwrap_or(item.ident.name);
372394
let tcx = self.cx.tcx;
373395

@@ -564,4 +586,10 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
564586
fn visit_lifetime(&mut self, _: &hir::Lifetime) {
565587
// Unneeded.
566588
}
589+
590+
fn visit_body(&mut self, b: &'tcx hir::Body<'tcx>) {
591+
let prev = mem::replace(&mut self.inside_body, true);
592+
walk_body(self, b);
593+
self.inside_body = prev;
594+
}
567595
}
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/111415>.
2+
// This test ensures that only impl blocks are documented in bodies.
3+
4+
#![crate_name = "foo"]
5+
6+
// @has 'foo/index.html'
7+
// Checking there are only three sections.
8+
// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3
9+
// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
10+
// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions'
11+
// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits'
12+
// Checking that there are only three items.
13+
// @count - '//*[@id="main-content"]//*[@class="item-name"]' 3
14+
// @has - '//*[@id="main-content"]//a[@href="struct.Bar.html"]' 'Bar'
15+
// @has - '//*[@id="main-content"]//a[@href="fn.foo.html"]' 'foo'
16+
// @has - '//*[@id="main-content"]//a[@href="trait.Foo.html"]' 'Foo'
17+
18+
// Now checking that the `foo` method is visible in `Bar` page.
19+
// @has 'foo/struct.Bar.html'
20+
// @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub fn foo()'
21+
// @has - '//*[@id="method.bar"]/*[@class="code-header"]' 'fn bar()'
22+
pub struct Bar;
23+
24+
pub trait Foo {
25+
fn bar() {}
26+
}
27+
28+
pub fn foo() {
29+
pub mod inaccessible {}
30+
pub fn inner() {}
31+
pub const BAR: u32 = 0;
32+
impl Bar {
33+
pub fn foo() {}
34+
}
35+
impl Foo for Bar {}
36+
}

0 commit comments

Comments
 (0)