Skip to content

Commit d0f7ce9

Browse files
committed
Impl
1 parent 0d7c146 commit d0f7ce9

File tree

2 files changed

+58
-65
lines changed

2 files changed

+58
-65
lines changed

src/librustdoc/clean/mod.rs

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ impl Clean<Vec<Item>> for hir::Item<'_> {
313313
generics: generics.clean(cx),
314314
bounds: bounds.clean(cx),
315315
})),
316-
_ => unimplemented!(),
316+
ItemKind::Impl { .. } => return clean_impl(self, cx),
317317
};
318318

319319
let build_item = |kind| Item {
@@ -2060,57 +2060,66 @@ impl Clean<ImplPolarity> for ty::ImplPolarity {
20602060
}
20612061
}
20622062

2063-
impl Clean<Vec<Item>> for doctree::Impl<'_> {
2064-
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
2065-
let mut ret = Vec::new();
2066-
let trait_ = self.trait_.clean(cx);
2067-
let items = self.items.iter().map(|ii| ii.clean(cx)).collect::<Vec<_>>();
2068-
let def_id = cx.tcx.hir().local_def_id(self.id);
2069-
2070-
// If this impl block is an implementation of the Deref trait, then we
2071-
// need to try inlining the target's inherent impl blocks as well.
2072-
if trait_.def_id() == cx.tcx.lang_items().deref_trait() {
2073-
build_deref_target_impls(cx, &items, &mut ret);
2063+
fn clean_impl(item: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec<Item> {
2064+
let (unsafety, of_trait, self_ty, items, generics) = match item.kind {
2065+
hir::ItemKind::Impl { unsafety, ref of_trait, self_ty, items, ref generics, .. } => {
2066+
(unsafety, of_trait, self_ty, items, generics)
20742067
}
2068+
_ => unreachable!(),
2069+
};
20752070

2076-
let provided: FxHashSet<String> = trait_
2077-
.def_id()
2078-
.map(|did| {
2079-
cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect()
2080-
})
2081-
.unwrap_or_default();
2082-
2083-
let for_ = self.for_.clean(cx);
2084-
let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) {
2085-
DefKind::TyAlias => Some(cx.tcx.type_of(did).clean(cx)),
2086-
_ => None,
2087-
});
2088-
let make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| Item {
2089-
name: None,
2090-
attrs: self.attrs.clean(cx),
2091-
source: self.span.clean(cx),
2092-
def_id: def_id.to_def_id(),
2093-
visibility: self.vis.clean(cx),
2094-
stability: cx.stability(self.id),
2095-
deprecation: cx.deprecation(self.id).clean(cx),
2096-
kind: ImplItem(Impl {
2097-
unsafety: self.unsafety,
2098-
generics: self.generics.clean(cx),
2099-
provided_trait_methods: provided.clone(),
2100-
trait_,
2101-
for_,
2102-
items,
2103-
polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)),
2104-
synthetic: false,
2105-
blanket_impl: None,
2106-
}),
2107-
};
2108-
if let Some(type_alias) = type_alias {
2109-
ret.push(make_item(trait_.clone(), type_alias, items.clone()));
2110-
}
2111-
ret.push(make_item(trait_, for_, items));
2112-
ret
2071+
// Don't duplicate impls when implementing a trait, we'll pick
2072+
// them up regardless of where they're located.
2073+
if of_trait.is_some() {
2074+
return vec![];
2075+
}
2076+
2077+
let mut ret = Vec::new();
2078+
let trait_ = of_trait.clean(cx);
2079+
let items: Vec<_> = items.iter().map(|ii| cx.tcx.hir().impl_item(ii.id).clean(cx)).collect();
2080+
let def_id = cx.tcx.hir().local_def_id(item.hir_id);
2081+
2082+
// If this impl block is an implementation of the Deref trait, then we
2083+
// need to try inlining the target's inherent impl blocks as well.
2084+
if trait_.def_id() == cx.tcx.lang_items().deref_trait() {
2085+
build_deref_target_impls(cx, &items, &mut ret);
2086+
}
2087+
2088+
let provided: FxHashSet<String> = trait_
2089+
.def_id()
2090+
.map(|did| cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect())
2091+
.unwrap_or_default();
2092+
2093+
let for_ = self_ty.clean(cx);
2094+
let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) {
2095+
DefKind::TyAlias => Some(cx.tcx.type_of(did).clean(cx)),
2096+
_ => None,
2097+
});
2098+
let make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| Item {
2099+
name: None,
2100+
attrs: item.attrs.clean(cx),
2101+
source: item.span.clean(cx),
2102+
def_id: def_id.to_def_id(),
2103+
visibility: item.vis.clean(cx),
2104+
stability: cx.stability(item.hir_id),
2105+
deprecation: cx.deprecation(item.hir_id).clean(cx),
2106+
kind: ImplItem(Impl {
2107+
unsafety,
2108+
generics: generics.clean(cx),
2109+
provided_trait_methods: provided.clone(),
2110+
trait_,
2111+
for_,
2112+
items,
2113+
polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)),
2114+
synthetic: false,
2115+
blanket_impl: None,
2116+
}),
2117+
};
2118+
if let Some(type_alias) = type_alias {
2119+
ret.push(make_item(trait_.clone(), type_alias, items.clone()));
21132120
}
2121+
ret.push(make_item(trait_, for_, items));
2122+
ret
21142123
}
21152124

21162125
fn clean_extern_crate(

src/librustdoc/doctree.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,6 @@ crate struct Static<'hir> {
3030
crate span: Span,
3131
}
3232

33-
#[derive(Debug)]
34-
crate struct Impl<'hir> {
35-
crate unsafety: hir::Unsafety,
36-
crate polarity: hir::ImplPolarity,
37-
crate defaultness: hir::Defaultness,
38-
crate constness: hir::Constness,
39-
crate generics: &'hir hir::Generics<'hir>,
40-
crate trait_: &'hir Option<hir::TraitRef<'hir>>,
41-
crate for_: &'hir hir::Ty<'hir>,
42-
crate items: Vec<&'hir hir::ImplItem<'hir>>,
43-
crate attrs: &'hir [ast::Attribute],
44-
crate span: Span,
45-
crate vis: &'hir hir::Visibility<'hir>,
46-
crate id: hir::HirId,
47-
}
48-
4933
#[derive(Debug)]
5034
crate struct Import<'hir> {
5135
crate name: Symbol,

0 commit comments

Comments
 (0)