Skip to content

Commit e854d39

Browse files
don't index trait impls if the trait isn't also documented
1 parent 7e70fee commit e854d39

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

src/librustdoc/html/render.rs

+29-5
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,15 @@ pub struct Cache {
337337
// and their parent id here and indexes them at the end of crate parsing.
338338
orphan_impl_items: Vec<(DefId, clean::Item)>,
339339

340+
// Similarly to `orphan_impl_items`, sometimes trait impls are picked up
341+
// even though the trait itself is not exported. This can happen if a trait
342+
// was defined in function/expression scope, since the impl will be picked
343+
// up by `collect-trait-impls` but the trait won't be scraped out in the HIR
344+
// crawl. In order to prevent crashes when looking for spotlight traits or
345+
// when gathering trait documentation on a type, hold impls here while
346+
// folding and add them to the cache later on if we find the trait.
347+
orphan_trait_impls: Vec<(DefId, FxHashSet<DefId>, Impl)>,
348+
340349
/// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias,
341350
/// we need the alias element to have an array of items.
342351
aliases: FxHashMap<String, Vec<IndexItem>>,
@@ -594,6 +603,7 @@ pub fn run(mut krate: clean::Crate,
594603
access_levels: krate.access_levels.clone(),
595604
crate_version: krate.version.take(),
596605
orphan_impl_items: Vec::new(),
606+
orphan_trait_impls: Vec::new(),
597607
traits: mem::replace(&mut krate.external_traits, FxHashMap()),
598608
deref_trait_did,
599609
deref_mut_trait_did,
@@ -636,6 +646,14 @@ pub fn run(mut krate: clean::Crate,
636646
cache.stack.push(krate.name.clone());
637647
krate = cache.fold_crate(krate);
638648

649+
for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) {
650+
if cache.traits.contains_key(&trait_did) {
651+
for did in dids {
652+
cache.impls.entry(did).or_insert(vec![]).push(impl_.clone());
653+
}
654+
}
655+
}
656+
639657
// Build our search index
640658
let index = build_index(&krate, &mut cache);
641659

@@ -1224,7 +1242,7 @@ impl<'a> SourceCollector<'a> {
12241242
impl DocFolder for Cache {
12251243
fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
12261244
if item.def_id.is_local() {
1227-
debug!("folding item \"{:?}\", a {}", item.name, item.type_());
1245+
debug!("folding {} \"{:?}\", id {:?}", item.type_(), item.name, item.def_id);
12281246
}
12291247

12301248
// If this is a stripped module,
@@ -1457,10 +1475,16 @@ impl DocFolder for Cache {
14571475
} else {
14581476
unreachable!()
14591477
};
1460-
for did in dids {
1461-
self.impls.entry(did).or_default().push(Impl {
1462-
impl_item: item.clone(),
1463-
});
1478+
let impl_item = Impl {
1479+
impl_item: item,
1480+
};
1481+
if impl_item.trait_did().map_or(true, |d| self.traits.contains_key(&d)) {
1482+
for did in dids {
1483+
self.impls.entry(did).or_insert(vec![]).push(impl_item.clone());
1484+
}
1485+
} else {
1486+
let trait_did = impl_item.trait_did().unwrap();
1487+
self.orphan_trait_impls.push((trait_did, dids, impl_item));
14641488
}
14651489
None
14661490
} else {

src/librustdoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#![feature(ptr_offset_from)]
2525
#![feature(crate_visibility_modifier)]
2626
#![feature(const_fn)]
27+
#![feature(drain_filter)]
2728

2829
#![recursion_limit="256"]
2930

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// when implementing the fix for traits-in-bodies, there was an ICE when documenting private items
12+
// and a trait was defined in non-module scope
13+
14+
// compile-flags:--document-private-items
15+
16+
// @has traits_in_bodies_private/struct.SomeStruct.html
17+
// @!has - '//code' 'impl HiddenTrait for SomeStruct'
18+
pub struct SomeStruct;
19+
20+
fn __implementation_details() {
21+
trait HiddenTrait {}
22+
impl HiddenTrait for SomeStruct {}
23+
}

0 commit comments

Comments
 (0)