about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/html/format.rs6
-rw-r--r--src/librustdoc/html/render.rs32
-rw-r--r--src/test/rustdoc/impl-disambiguation.rs40
3 files changed, 67 insertions, 11 deletions
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 60dae19d876..c591c09bf20 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -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)
                     }
                 }
             }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 40eb7e5ab78..6234d890244 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2132,10 +2132,23 @@ 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;
+                    }
+                }
+                _ => {}
             }
         }
 
@@ -2143,12 +2156,13 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
             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>")?;
diff --git a/src/test/rustdoc/impl-disambiguation.rs b/src/test/rustdoc/impl-disambiguation.rs
new file mode 100644
index 00000000000..afe1daf5983
--- /dev/null
+++ b/src/test/rustdoc/impl-disambiguation.rs
@@ -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 {}