Skip to content

Commit 05eef36

Browse files
committed
rustdoc: Improve impl disambiguation
* Don't disambiguate if there are multiple impls for the same type. * Disambiguate for impls of &Foo and &mut Foo. * Don't try to disambiguate generic types.
1 parent fc02736 commit 05eef36

File tree

3 files changed

+67
-11
lines changed

3 files changed

+67
-11
lines changed

src/librustdoc/html/format.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -671,9 +671,11 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
671671
}
672672
_ => {
673673
if f.alternate() {
674-
write!(f, "&{}{}{:#}", lt, m, **ty)
674+
write!(f, "&{}{}", lt, m)?;
675+
fmt_type(&ty, f, use_absolute)
675676
} else {
676-
write!(f, "&{}{}{}", lt, m, **ty)
677+
write!(f, "&{}{}", lt, m)?;
678+
fmt_type(&ty, f, use_absolute)
677679
}
678680
}
679681
}

src/librustdoc/html/render.rs

+23-9
Original file line numberDiff line numberDiff line change
@@ -2132,23 +2132,37 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
21322132
<ul class='item-list' id='implementors-list'>
21332133
")?;
21342134
if let Some(implementors) = cache.implementors.get(&it.def_id) {
2135-
let mut implementor_count: FxHashMap<&str, usize> = FxHashMap();
2135+
// The DefId is for the first Type found with that name. The bool is
2136+
// if any Types with the same name but different DefId have been found.
2137+
let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap();
21362138
for implementor in implementors {
2137-
if let clean::Type::ResolvedPath {ref path, ..} = implementor.impl_.for_ {
2138-
*implementor_count.entry(path.last_name()).or_insert(0) += 1;
2139+
match implementor.impl_.for_ {
2140+
clean::ResolvedPath { ref path, did, is_generic: false, .. } |
2141+
clean::BorrowedRef {
2142+
type_: box clean::ResolvedPath { ref path, did, is_generic: false, .. },
2143+
..
2144+
} => {
2145+
let &mut (prev_did, ref mut has_duplicates) =
2146+
implementor_dups.entry(path.last_name()).or_insert((did, false));
2147+
if prev_did != did {
2148+
*has_duplicates = true;
2149+
}
2150+
}
2151+
_ => {}
21392152
}
21402153
}
21412154

21422155
for implementor in implementors {
21432156
write!(w, "<li><code>")?;
21442157
// If there's already another implementor that has the same abbridged name, use the
21452158
// full path, for example in `std::iter::ExactSizeIterator`
2146-
let use_absolute = if let clean::Type::ResolvedPath {
2147-
ref path, ..
2148-
} = implementor.impl_.for_ {
2149-
implementor_count[path.last_name()] > 1
2150-
} else {
2151-
false
2159+
let use_absolute = match implementor.impl_.for_ {
2160+
clean::ResolvedPath { ref path, is_generic: false, .. } |
2161+
clean::BorrowedRef {
2162+
type_: box clean::ResolvedPath { ref path, is_generic: false, .. },
2163+
..
2164+
} => implementor_dups[path.last_name()].1,
2165+
_ => false,
21522166
};
21532167
fmt_impl_for_trait_page(&implementor.impl_, w, use_absolute)?;
21542168
writeln!(w, "</code></li>")?;
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2017 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+
#![crate_name = "foo"]
12+
13+
pub trait Foo {}
14+
15+
pub struct Bar<T> { field: T }
16+
17+
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
18+
// "impl Foo for Bar<u8>"
19+
impl Foo for Bar<u8> {}
20+
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
21+
// "impl Foo for Bar<u16>"
22+
impl Foo for Bar<u16> {}
23+
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
24+
// "impl<'a> Foo for &'a Bar<u8>"
25+
impl<'a> Foo for &'a Bar<u8> {}
26+
27+
pub mod mod1 {
28+
pub struct Baz {}
29+
}
30+
31+
pub mod mod2 {
32+
pub enum Baz {}
33+
}
34+
35+
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
36+
// "impl Foo for foo::mod1::Baz"
37+
impl Foo for mod1::Baz {}
38+
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
39+
// "impl<'a> Foo for &'a foo::mod2::Baz"
40+
impl<'a> Foo for &'a mod2::Baz {}

0 commit comments

Comments
 (0)