Skip to content

Commit 87760e5

Browse files
collect auto-/blanket-impls during collect-trait-impls
1 parent e854d39 commit 87760e5

File tree

3 files changed

+65
-63
lines changed

3 files changed

+65
-63
lines changed

src/librustdoc/clean/inline.rs

+7-21
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ use clean::{
2929
self,
3030
GetDefId,
3131
ToSource,
32-
get_auto_traits_with_def_id,
33-
get_blanket_impls_with_def_id,
3432
};
3533

3634
use super::Clean;
@@ -56,7 +54,7 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa
5654
let inner = match def {
5755
Def::Trait(did) => {
5856
record_extern_fqn(cx, did, clean::TypeKind::Trait);
59-
ret.extend(build_impls(cx, did, false));
57+
ret.extend(build_impls(cx, did));
6058
clean::TraitItem(build_external_trait(cx, did))
6159
}
6260
Def::Fn(did) => {
@@ -65,27 +63,27 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa
6563
}
6664
Def::Struct(did) => {
6765
record_extern_fqn(cx, did, clean::TypeKind::Struct);
68-
ret.extend(build_impls(cx, did, true));
66+
ret.extend(build_impls(cx, did));
6967
clean::StructItem(build_struct(cx, did))
7068
}
7169
Def::Union(did) => {
7270
record_extern_fqn(cx, did, clean::TypeKind::Union);
73-
ret.extend(build_impls(cx, did, true));
71+
ret.extend(build_impls(cx, did));
7472
clean::UnionItem(build_union(cx, did))
7573
}
7674
Def::TyAlias(did) => {
7775
record_extern_fqn(cx, did, clean::TypeKind::Typedef);
78-
ret.extend(build_impls(cx, did, false));
76+
ret.extend(build_impls(cx, did));
7977
clean::TypedefItem(build_type_alias(cx, did), false)
8078
}
8179
Def::Enum(did) => {
8280
record_extern_fqn(cx, did, clean::TypeKind::Enum);
83-
ret.extend(build_impls(cx, did, true));
81+
ret.extend(build_impls(cx, did));
8482
clean::EnumItem(build_enum(cx, did))
8583
}
8684
Def::ForeignTy(did) => {
8785
record_extern_fqn(cx, did, clean::TypeKind::Foreign);
88-
ret.extend(build_impls(cx, did, false));
86+
ret.extend(build_impls(cx, did));
8987
clean::ForeignTypeItem
9088
}
9189
// Never inline enum variants but leave them shown as re-exports.
@@ -275,26 +273,14 @@ fn build_type_alias(cx: &DocContext, did: DefId) -> clean::Typedef {
275273
}
276274
}
277275

278-
pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean::Item> {
276+
pub fn build_impls(cx: &DocContext, did: DefId) -> Vec<clean::Item> {
279277
let tcx = cx.tcx;
280278
let mut impls = Vec::new();
281279

282280
for &did in tcx.inherent_impls(did).iter() {
283281
build_impl(cx, did, &mut impls);
284282
}
285283

286-
if auto_traits {
287-
let auto_impls = get_auto_traits_with_def_id(cx, did);
288-
{
289-
let mut renderinfo = cx.renderinfo.borrow_mut();
290-
let new_impls: Vec<clean::Item> = auto_impls.into_iter()
291-
.filter(|i| renderinfo.inlined.insert(i.def_id)).collect();
292-
293-
impls.extend(new_impls);
294-
}
295-
impls.extend(get_blanket_impls_with_def_id(cx, did));
296-
}
297-
298284
impls
299285
}
300286

src/librustdoc/clean/mod.rs

+19-41
Original file line numberDiff line numberDiff line change
@@ -576,9 +576,9 @@ impl Clean<Item> for doctree::Module {
576576
let mut items: Vec<Item> = vec![];
577577
items.extend(self.extern_crates.iter().map(|x| x.clean(cx)));
578578
items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
579-
items.extend(self.structs.iter().flat_map(|x| x.clean(cx)));
580-
items.extend(self.unions.iter().flat_map(|x| x.clean(cx)));
581-
items.extend(self.enums.iter().flat_map(|x| x.clean(cx)));
579+
items.extend(self.structs.iter().map(|x| x.clean(cx)));
580+
items.extend(self.unions.iter().map(|x| x.clean(cx)));
581+
items.extend(self.enums.iter().map(|x| x.clean(cx)));
582582
items.extend(self.fns.iter().map(|x| x.clean(cx)));
583583
items.extend(self.foreigns.iter().flat_map(|x| x.clean(cx)));
584584
items.extend(self.mods.iter().map(|x| x.clean(cx)));
@@ -2813,14 +2813,10 @@ pub struct Union {
28132813
pub fields_stripped: bool,
28142814
}
28152815

2816-
impl Clean<Vec<Item>> for doctree::Struct {
2817-
fn clean(&self, cx: &DocContext) -> Vec<Item> {
2818-
let name = self.name.clean(cx);
2819-
let mut ret = get_auto_traits_with_node_id(cx, self.id, name.clone());
2820-
ret.extend(get_blanket_impls_with_node_id(cx, self.id, name.clone()));
2821-
2822-
ret.push(Item {
2823-
name: Some(name),
2816+
impl Clean<Item> for doctree::Struct {
2817+
fn clean(&self, cx: &DocContext) -> Item {
2818+
Item {
2819+
name: Some(self.name.clean(cx)),
28242820
attrs: self.attrs.clean(cx),
28252821
source: self.whence.clean(cx),
28262822
def_id: cx.tcx.hir.local_def_id(self.id),
@@ -2833,20 +2829,14 @@ impl Clean<Vec<Item>> for doctree::Struct {
28332829
fields: self.fields.clean(cx),
28342830
fields_stripped: false,
28352831
}),
2836-
});
2837-
2838-
ret
2832+
}
28392833
}
28402834
}
28412835

2842-
impl Clean<Vec<Item>> for doctree::Union {
2843-
fn clean(&self, cx: &DocContext) -> Vec<Item> {
2844-
let name = self.name.clean(cx);
2845-
let mut ret = get_auto_traits_with_node_id(cx, self.id, name.clone());
2846-
ret.extend(get_blanket_impls_with_node_id(cx, self.id, name.clone()));
2847-
2848-
ret.push(Item {
2849-
name: Some(name),
2836+
impl Clean<Item> for doctree::Union {
2837+
fn clean(&self, cx: &DocContext) -> Item {
2838+
Item {
2839+
name: Some(self.name.clean(cx)),
28502840
attrs: self.attrs.clean(cx),
28512841
source: self.whence.clean(cx),
28522842
def_id: cx.tcx.hir.local_def_id(self.id),
@@ -2859,9 +2849,7 @@ impl Clean<Vec<Item>> for doctree::Union {
28592849
fields: self.fields.clean(cx),
28602850
fields_stripped: false,
28612851
}),
2862-
});
2863-
2864-
ret
2852+
}
28652853
}
28662854
}
28672855

@@ -2892,14 +2880,10 @@ pub struct Enum {
28922880
pub variants_stripped: bool,
28932881
}
28942882

2895-
impl Clean<Vec<Item>> for doctree::Enum {
2896-
fn clean(&self, cx: &DocContext) -> Vec<Item> {
2897-
let name = self.name.clean(cx);
2898-
let mut ret = get_auto_traits_with_node_id(cx, self.id, name.clone());
2899-
ret.extend(get_blanket_impls_with_node_id(cx, self.id, name.clone()));
2900-
2901-
ret.push(Item {
2902-
name: Some(name),
2883+
impl Clean<Item> for doctree::Enum {
2884+
fn clean(&self, cx: &DocContext) -> Item {
2885+
Item {
2886+
name: Some(self.name.clean(cx)),
29032887
attrs: self.attrs.clean(cx),
29042888
source: self.whence.clean(cx),
29052889
def_id: cx.tcx.hir.local_def_id(self.id),
@@ -2911,9 +2895,7 @@ impl Clean<Vec<Item>> for doctree::Enum {
29112895
generics: self.generics.clean(cx),
29122896
variants_stripped: false,
29132897
}),
2914-
});
2915-
2916-
ret
2898+
}
29172899
}
29182900
}
29192901

@@ -3442,11 +3424,7 @@ fn build_deref_target_impls(cx: &DocContext,
34423424
let primitive = match *target {
34433425
ResolvedPath { did, .. } if did.is_local() => continue,
34443426
ResolvedPath { did, .. } => {
3445-
// We set the last parameter to false to avoid looking for auto-impls for traits
3446-
// and therefore avoid an ICE.
3447-
// The reason behind this is that auto-traits don't propagate through Deref so
3448-
// we're not supposed to synthesise impls for them.
3449-
ret.extend(inline::build_impls(cx, did, false));
3427+
ret.extend(inline::build_impls(cx, did));
34503428
continue
34513429
}
34523430
_ => match target.primitive_type() {

src/librustdoc/passes/collect_trait_impls.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@ use clean::*;
1212

1313
use super::Pass;
1414
use core::DocContext;
15+
use fold::DocFolder;
1516

1617
pub const COLLECT_TRAIT_IMPLS: Pass =
1718
Pass::early("collect-trait-impls", collect_trait_impls,
1819
"retrieves trait impls for items in the crate");
1920

20-
pub fn collect_trait_impls(mut krate: Crate, cx: &DocContext) -> Crate {
21+
pub fn collect_trait_impls(krate: Crate, cx: &DocContext) -> Crate {
22+
let mut synth = SyntheticImplCollector::new(cx);
23+
let mut krate = synth.fold_crate(krate);
24+
2125
if let Some(ref mut it) = krate.module {
2226
if let ModuleItem(Module { ref mut items, .. }) = it.inner {
27+
items.extend(synth.impls);
28+
2329
for &cnum in cx.tcx.crates().iter() {
2430
for &did in cx.tcx.all_trait_implementations(cnum).iter() {
2531
inline::build_impl(cx, did, items);
@@ -90,3 +96,35 @@ pub fn collect_trait_impls(mut krate: Crate, cx: &DocContext) -> Crate {
9096

9197
krate
9298
}
99+
100+
struct SyntheticImplCollector<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> {
101+
cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>,
102+
impls: Vec<Item>,
103+
}
104+
105+
impl<'a, 'tcx, 'rcx, 'cstore> SyntheticImplCollector<'a, 'tcx, 'rcx, 'cstore> {
106+
fn new(cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>) -> Self {
107+
SyntheticImplCollector {
108+
cx,
109+
impls: Vec::new(),
110+
}
111+
}
112+
}
113+
114+
impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for SyntheticImplCollector<'a, 'tcx, 'rcx, 'cstore> {
115+
fn fold_item(&mut self, i: Item) -> Option<Item> {
116+
if i.is_struct() || i.is_enum() || i.is_union() {
117+
if let (Some(node_id), Some(name)) =
118+
(self.cx.tcx.hir.as_local_node_id(i.def_id), i.name.clone())
119+
{
120+
self.impls.extend(get_auto_traits_with_node_id(self.cx, node_id, name.clone()));
121+
self.impls.extend(get_blanket_impls_with_node_id(self.cx, node_id, name));
122+
} else {
123+
self.impls.extend(get_auto_traits_with_def_id(self.cx, i.def_id));
124+
self.impls.extend(get_blanket_impls_with_def_id(self.cx, i.def_id));
125+
}
126+
}
127+
128+
self.fold_item_recur(i)
129+
}
130+
}

0 commit comments

Comments
 (0)