Skip to content

Commit

Permalink
Rollup merge of rust-lang#39589 - ollie27:rustdoc_impl_disambiguation…
Browse files Browse the repository at this point in the history
…, r=alexcrichton

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.

[before](https://doc.rust-lang.org/nightly/std/ops/trait.Rem.html#implementors) [after](https://ollie27.github.io/rust_doc_test/std/ops/trait.Rem.html#implementors)
  • Loading branch information
frewsxcv committed Feb 9, 2017
2 parents 3053494 + 05eef36 commit 4f6868a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
6 changes: 4 additions & 2 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,9 +671,11 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
}
_ => {
if f.alternate() {
write!(f, "&{}{}{:#}", lt, m, **ty)
write!(f, "&{}{}", lt, m)?;
fmt_type(&ty, f, use_absolute)
} else {
write!(f, "&{}{}{}", lt, m, **ty)
write!(f, "&{}{}", lt, m)?;
fmt_type(&ty, f, use_absolute)
}
}
}
Expand Down
32 changes: 23 additions & 9 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2132,23 +2132,37 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
<ul class='item-list' id='implementors-list'>
")?;
if let Some(implementors) = cache.implementors.get(&it.def_id) {
let mut implementor_count: FxHashMap<&str, usize> = FxHashMap();
// The DefId is for the first Type found with that name. The bool is
// if any Types with the same name but different DefId have been found.
let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap();
for implementor in implementors {
if let clean::Type::ResolvedPath {ref path, ..} = implementor.impl_.for_ {
*implementor_count.entry(path.last_name()).or_insert(0) += 1;
match implementor.impl_.for_ {
clean::ResolvedPath { ref path, did, is_generic: false, .. } |
clean::BorrowedRef {
type_: box clean::ResolvedPath { ref path, did, is_generic: false, .. },
..
} => {
let &mut (prev_did, ref mut has_duplicates) =
implementor_dups.entry(path.last_name()).or_insert((did, false));
if prev_did != did {
*has_duplicates = true;
}
}
_ => {}
}
}

for implementor in implementors {
write!(w, "<li><code>")?;
// If there's already another implementor that has the same abbridged name, use the
// full path, for example in `std::iter::ExactSizeIterator`
let use_absolute = if let clean::Type::ResolvedPath {
ref path, ..
} = implementor.impl_.for_ {
implementor_count[path.last_name()] > 1
} else {
false
let use_absolute = match implementor.impl_.for_ {
clean::ResolvedPath { ref path, is_generic: false, .. } |
clean::BorrowedRef {
type_: box clean::ResolvedPath { ref path, is_generic: false, .. },
..
} => implementor_dups[path.last_name()].1,
_ => false,
};
fmt_impl_for_trait_page(&implementor.impl_, w, use_absolute)?;
writeln!(w, "</code></li>")?;
Expand Down
40 changes: 40 additions & 0 deletions src/test/rustdoc/impl-disambiguation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_name = "foo"]

pub trait Foo {}

pub struct Bar<T> { field: T }

// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl Foo for Bar<u8>"
impl Foo for Bar<u8> {}
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl Foo for Bar<u16>"
impl Foo for Bar<u16> {}
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl<'a> Foo for &'a Bar<u8>"
impl<'a> Foo for &'a Bar<u8> {}

pub mod mod1 {
pub struct Baz {}
}

pub mod mod2 {
pub enum Baz {}
}

// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl Foo for foo::mod1::Baz"
impl Foo for mod1::Baz {}
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl<'a> Foo for &'a foo::mod2::Baz"
impl<'a> Foo for &'a mod2::Baz {}

0 comments on commit 4f6868a

Please sign in to comment.