Skip to content

Commit 30e5268

Browse files
rustdoc: add new "Implementations on Foreign Types" section to traits
1 parent 2f1ef9e commit 30e5268

File tree

2 files changed

+66
-14
lines changed

2 files changed

+66
-14
lines changed

src/librustdoc/clean/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1651,6 +1651,16 @@ impl GetDefId for Type {
16511651
fn def_id(&self) -> Option<DefId> {
16521652
match *self {
16531653
ResolvedPath { did, .. } => Some(did),
1654+
Primitive(p) => ::html::render::cache().primitive_locations.get(&p).cloned(),
1655+
BorrowedRef { type_: box Generic(..), .. } =>
1656+
Primitive(PrimitiveType::Reference).def_id(),
1657+
BorrowedRef { ref type_, .. } => type_.def_id(),
1658+
Tuple(..) => Primitive(PrimitiveType::Tuple).def_id(),
1659+
BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(),
1660+
Slice(..) => Primitive(PrimitiveType::Slice).def_id(),
1661+
Array(..) => Primitive(PrimitiveType::Array).def_id(),
1662+
RawPointer(..) => Primitive(PrimitiveType::RawPointer).def_id(),
1663+
QPath { ref self_type, .. } => self_type.def_id(),
16541664
_ => None,
16551665
}
16561666
}

src/librustdoc/html/render.rs

+56-14
Original file line numberDiff line numberDiff line change
@@ -2416,12 +2416,12 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
24162416
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)?;
24172417

24182418
let cache = cache();
2419-
write!(w, "
2419+
let impl_header = "
24202420
<h2 id='implementors' class='small-section-header'>
24212421
Implementors<a href='#implementors' class='anchor'></a>
24222422
</h2>
24232423
<ul class='item-list' id='implementors-list'>
2424-
")?;
2424+
";
24252425
if let Some(implementors) = cache.implementors.get(&it.def_id) {
24262426
// The DefId is for the first Type found with that name. The bool is
24272427
// if any Types with the same name but different DefId have been found.
@@ -2443,7 +2443,38 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
24432443
}
24442444
}
24452445

2446-
for implementor in implementors {
2446+
let (local, foreign) = implementors.iter()
2447+
.partition::<Vec<_>, _>(|i| i.impl_.for_.def_id()
2448+
.map_or(true, |d| cache.paths.contains_key(&d)));
2449+
2450+
if !foreign.is_empty() {
2451+
write!(w, "
2452+
<h2 id='foreign-impls' class='section-header'>
2453+
Implementations on Foreign Types<a href='#foreign-impls' class='anchor'></a>
2454+
</h2>
2455+
")?;
2456+
2457+
for implementor in foreign {
2458+
// need to get from a clean::Impl to a clean::Item so i can use render_impl
2459+
if let Some(t_did) = implementor.impl_.for_.def_id() {
2460+
if let Some(impl_item) = cache.impls.get(&t_did).and_then(|i| i.iter()
2461+
.find(|i| i.impl_item.def_id == implementor.def_id))
2462+
{
2463+
let i = &impl_item.impl_item;
2464+
let impl_ = Impl { impl_item: i.clone() };
2465+
let assoc_link = AssocItemLink::GotoSource(
2466+
i.def_id, &implementor.impl_.provided_trait_methods
2467+
);
2468+
render_impl(w, cx, &impl_, assoc_link,
2469+
RenderMode::Normal, i.stable_since(), false)?;
2470+
}
2471+
}
2472+
}
2473+
}
2474+
2475+
write!(w, "{}", impl_header)?;
2476+
2477+
for implementor in local {
24472478
write!(w, "<li><code>")?;
24482479
// If there's already another implementor that has the same abbridged name, use the
24492480
// full path, for example in `std::iter::ExactSizeIterator`
@@ -2465,6 +2496,10 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
24652496
}
24662497
writeln!(w, "</code></li>")?;
24672498
}
2499+
} else {
2500+
// even without any implementations to write in, we still want the heading and list, so the
2501+
// implementors javascript file pulled in below has somewhere to write the impls into
2502+
write!(w, "{}", impl_header)?;
24682503
}
24692504
write!(w, "</ul>")?;
24702505
write!(w, r#"<script type="text/javascript" async
@@ -3069,7 +3104,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
30693104
};
30703105
for i in &non_trait {
30713106
render_impl(w, cx, i, AssocItemLink::Anchor(None), render_mode,
3072-
containing_item.stable_since())?;
3107+
containing_item.stable_since(), true)?;
30733108
}
30743109
}
30753110
if let AssocItemRender::DerefFor { .. } = what {
@@ -3094,7 +3129,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
30943129
let did = i.trait_did().unwrap();
30953130
let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods);
30963131
render_impl(w, cx, i, assoc_link,
3097-
RenderMode::Normal, containing_item.stable_since())?;
3132+
RenderMode::Normal, containing_item.stable_since(), true)?;
30983133
}
30993134
}
31003135
Ok(())
@@ -3124,7 +3159,8 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
31243159
}
31253160

31263161
fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLink,
3127-
render_mode: RenderMode, outer_version: Option<&str>) -> fmt::Result {
3162+
render_mode: RenderMode, outer_version: Option<&str>,
3163+
show_def_docs: bool) -> fmt::Result {
31283164
if render_mode == RenderMode::Normal {
31293165
let id = derive_id(match i.inner_impl().trait_ {
31303166
Some(ref t) => format!("impl-{}", Escape(&format!("{:#}", t))),
@@ -3153,7 +3189,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
31533189
fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
31543190
link: AssocItemLink, render_mode: RenderMode,
31553191
is_default_item: bool, outer_version: Option<&str>,
3156-
trait_: Option<&clean::Trait>) -> fmt::Result {
3192+
trait_: Option<&clean::Trait>, show_def_docs: bool) -> fmt::Result {
31573193
let item_type = item.type_();
31583194
let name = item.name.as_ref().unwrap();
31593195

@@ -3248,19 +3284,23 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
32483284
document_stability(w, cx, it)?;
32493285
if item.doc_value().is_some() {
32503286
document_full(w, item, cx, &prefix)?;
3251-
} else {
3287+
} else if show_def_docs {
32523288
// In case the item isn't documented,
32533289
// provide short documentation from the trait.
32543290
document_short(w, it, link, cx, &prefix)?;
32553291
}
32563292
}
32573293
} else {
32583294
document_stability(w, cx, item)?;
3259-
document_full(w, item, cx, &prefix)?;
3295+
if show_def_docs {
3296+
document_full(w, item, cx, &prefix)?;
3297+
}
32603298
}
32613299
} else {
32623300
document_stability(w, cx, item)?;
3263-
document_short(w, item, link, cx, &prefix)?;
3301+
if show_def_docs {
3302+
document_short(w, item, link, cx, &prefix)?;
3303+
}
32643304
}
32653305
}
32663306
Ok(())
@@ -3272,15 +3312,16 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
32723312
write!(w, "<div class='impl-items'>")?;
32733313
for trait_item in &i.inner_impl().items {
32743314
doc_impl_item(w, cx, trait_item, link, render_mode,
3275-
false, outer_version, trait_)?;
3315+
false, outer_version, trait_, show_def_docs)?;
32763316
}
32773317

32783318
fn render_default_items(w: &mut fmt::Formatter,
32793319
cx: &Context,
32803320
t: &clean::Trait,
32813321
i: &clean::Impl,
32823322
render_mode: RenderMode,
3283-
outer_version: Option<&str>) -> fmt::Result {
3323+
outer_version: Option<&str>,
3324+
show_def_docs: bool) -> fmt::Result {
32843325
for trait_item in &t.items {
32853326
let n = trait_item.name.clone();
32863327
if i.items.iter().find(|m| m.name == n).is_some() {
@@ -3290,15 +3331,16 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
32903331
let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods);
32913332

32923333
doc_impl_item(w, cx, trait_item, assoc_link, render_mode, true,
3293-
outer_version, None)?;
3334+
outer_version, None, show_def_docs)?;
32943335
}
32953336
Ok(())
32963337
}
32973338

32983339
// If we've implemented a trait, then also emit documentation for all
32993340
// default items which weren't overridden in the implementation block.
33003341
if let Some(t) = trait_ {
3301-
render_default_items(w, cx, t, &i.inner_impl(), render_mode, outer_version)?;
3342+
render_default_items(w, cx, t, &i.inner_impl(),
3343+
render_mode, outer_version, show_def_docs)?;
33023344
}
33033345
write!(w, "</div>")?;
33043346
Ok(())

0 commit comments

Comments
 (0)