From 2841bf3bc79bb866980c5aea55a96a3d1cdea2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 15 Dec 2016 23:13:00 -0800 Subject: [PATCH 1/5] Rustdoc: disambiguate Implementors when the type name is not unique --- src/librustdoc/html/format.rs | 344 ++++++++++++++++++---------------- src/librustdoc/html/render.rs | 18 +- 2 files changed, 196 insertions(+), 166 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6dc6e80dae0b8..6808752b1fe05 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -433,7 +433,7 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec)> { /// Used when rendering a `ResolvedPath` structure. This invokes the `path` /// rendering function with the necessary arguments for linking to a local path. fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, - print_all: bool) -> fmt::Result { + print_all: bool, use_absolute: bool) -> fmt::Result { let last = path.segments.last().unwrap(); let rel_root = match &*path.segments[0].name { "self" => Some("./".to_string()), @@ -467,7 +467,17 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path, if w.alternate() { write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.params)?; } else { - write!(w, "{}{}", HRef::new(did, &last.name), last.params)?; + let path = if use_absolute { + match href(did) { + Some((_, _, fqp)) => format!("{}::{}", + fqp[..fqp.len()-1].join("::"), + HRef::new(did, fqp.last().unwrap())), + None => format!("{}", HRef::new(did, &last.name)), + } + } else { + format!("{}", HRef::new(did, &last.name)) + }; + write!(w, "{}{}", path, last.params)?; } Ok(()) } @@ -551,194 +561,198 @@ impl<'a> fmt::Display for HRef<'a> { } } -impl fmt::Display for clean::Type { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - clean::Generic(ref name) => { - f.write_str(name) - } - clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => { - // Paths like T::Output and Self::Output should be rendered with all segments - resolved_path(f, did, path, is_generic)?; - tybounds(f, typarams) +fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, full_path: bool) -> fmt::Result { + match *t { + clean::Generic(ref name) => { + f.write_str(name) + } + clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => { + // Paths like T::Output and Self::Output should be rendered with all segments + resolved_path(f, did, path, is_generic, full_path)?; + tybounds(f, typarams) + } + clean::Infer => write!(f, "_"), + clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()), + clean::BareFunction(ref decl) => { + if f.alternate() { + write!(f, "{}{}fn{:#}{:#}", + UnsafetySpace(decl.unsafety), + AbiSpace(decl.abi), + decl.generics, + decl.decl) + } else { + write!(f, "{}{}fn{}{}", + UnsafetySpace(decl.unsafety), + AbiSpace(decl.abi), + decl.generics, + decl.decl) } - clean::Infer => write!(f, "_"), - clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()), - clean::BareFunction(ref decl) => { - if f.alternate() { - write!(f, "{}{}fn{:#}{:#}", - UnsafetySpace(decl.unsafety), - AbiSpace(decl.abi), - decl.generics, - decl.decl) - } else { - write!(f, "{}{}fn{}{}", - UnsafetySpace(decl.unsafety), - AbiSpace(decl.abi), - decl.generics, - decl.decl) + } + clean::Tuple(ref typs) => { + match &typs[..] { + &[] => primitive_link(f, PrimitiveType::Tuple, "()"), + &[ref one] => { + primitive_link(f, PrimitiveType::Tuple, "(")?; + //carry f.alternate() into this display w/o branching manually + fmt::Display::fmt(one, f)?; + primitive_link(f, PrimitiveType::Tuple, ",)") } - } - clean::Tuple(ref typs) => { - match &typs[..] { - &[] => primitive_link(f, PrimitiveType::Tuple, "()"), - &[ref one] => { - primitive_link(f, PrimitiveType::Tuple, "(")?; - //carry f.alternate() into this display w/o branching manually - fmt::Display::fmt(one, f)?; - primitive_link(f, PrimitiveType::Tuple, ",)") - } - many => { - primitive_link(f, PrimitiveType::Tuple, "(")?; - fmt::Display::fmt(&CommaSep(&many), f)?; - primitive_link(f, PrimitiveType::Tuple, ")") - } + many => { + primitive_link(f, PrimitiveType::Tuple, "(")?; + fmt::Display::fmt(&CommaSep(&many), f)?; + primitive_link(f, PrimitiveType::Tuple, ")") } } - clean::Vector(ref t) => { - primitive_link(f, PrimitiveType::Slice, &format!("["))?; - fmt::Display::fmt(t, f)?; - primitive_link(f, PrimitiveType::Slice, &format!("]")) - } - clean::FixedVector(ref t, ref s) => { - primitive_link(f, PrimitiveType::Array, "[")?; - fmt::Display::fmt(t, f)?; - if f.alternate() { - primitive_link(f, PrimitiveType::Array, - &format!("; {}]", s)) - } else { - primitive_link(f, PrimitiveType::Array, - &format!("; {}]", Escape(s))) - } + } + clean::Vector(ref t) => { + primitive_link(f, PrimitiveType::Slice, &format!("["))?; + fmt::Display::fmt(t, f)?; + primitive_link(f, PrimitiveType::Slice, &format!("]")) + } + clean::FixedVector(ref t, ref s) => { + primitive_link(f, PrimitiveType::Array, "[")?; + fmt::Display::fmt(t, f)?; + if f.alternate() { + primitive_link(f, PrimitiveType::Array, + &format!("; {}]", s)) + } else { + primitive_link(f, PrimitiveType::Array, + &format!("; {}]", Escape(s))) } - clean::Never => f.write_str("!"), - clean::RawPointer(m, ref t) => { - match **t { - clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => { - if f.alternate() { - primitive_link(f, clean::PrimitiveType::RawPointer, - &format!("*{}{:#}", RawMutableSpace(m), t)) - } else { - primitive_link(f, clean::PrimitiveType::RawPointer, - &format!("*{}{}", RawMutableSpace(m), t)) - } - } - _ => { + } + clean::Never => f.write_str("!"), + clean::RawPointer(m, ref t) => { + match **t { + clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => { + if f.alternate() { primitive_link(f, clean::PrimitiveType::RawPointer, - &format!("*{}", RawMutableSpace(m)))?; - fmt::Display::fmt(t, f) + &format!("*{}{:#}", RawMutableSpace(m), t)) + } else { + primitive_link(f, clean::PrimitiveType::RawPointer, + &format!("*{}{}", RawMutableSpace(m), t)) } } + _ => { + primitive_link(f, clean::PrimitiveType::RawPointer, + &format!("*{}", RawMutableSpace(m)))?; + fmt::Display::fmt(t, f) + } } - clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => { - let lt = match *l { - Some(ref l) => format!("{} ", *l), - _ => "".to_string(), - }; - let m = MutableSpace(mutability); - match **ty { - clean::Vector(ref bt) => { // BorrowedRef{ ... Vector(T) } is &[T] - match **bt { - clean::Generic(_) => - if f.alternate() { - primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[{:#}]", lt, m, **bt)) - } else { - primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[{}]", lt, m, **bt)) - }, - _ => { - if f.alternate() { - primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[", lt, m))?; - write!(f, "{:#}", **bt)?; - } else { - primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[", lt, m))?; - write!(f, "{}", **bt)?; - } - primitive_link(f, PrimitiveType::Slice, "]") + } + clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => { + let lt = match *l { + Some(ref l) => format!("{} ", *l), + _ => "".to_string(), + }; + let m = MutableSpace(mutability); + match **ty { + clean::Vector(ref bt) => { // BorrowedRef{ ... Vector(T) } is &[T] + match **bt { + clean::Generic(_) => + if f.alternate() { + primitive_link(f, PrimitiveType::Slice, + &format!("&{}{}[{:#}]", lt, m, **bt)) + } else { + primitive_link(f, PrimitiveType::Slice, + &format!("&{}{}[{}]", lt, m, **bt)) + }, + _ => { + if f.alternate() { + primitive_link(f, PrimitiveType::Slice, + &format!("&{}{}[", lt, m))?; + write!(f, "{:#}", **bt)?; + } else { + primitive_link(f, PrimitiveType::Slice, + &format!("&{}{}[", lt, m))?; + write!(f, "{}", **bt)?; } - } - } - _ => { - if f.alternate() { - write!(f, "&{}{}{:#}", lt, m, **ty) - } else { - write!(f, "&{}{}{}", lt, m, **ty) + primitive_link(f, PrimitiveType::Slice, "]") } } } - } - clean::PolyTraitRef(ref bounds) => { - for (i, bound) in bounds.iter().enumerate() { - if i != 0 { - write!(f, " + ")?; - } + _ => { if f.alternate() { - write!(f, "{:#}", *bound)?; + write!(f, "&{}{}{:#}", lt, m, **ty) } else { - write!(f, "{}", *bound)?; + write!(f, "&{}{}{}", lt, m, **ty) } } - Ok(()) } - clean::ImplTrait(ref bounds) => { - write!(f, "impl ")?; - for (i, bound) in bounds.iter().enumerate() { - if i != 0 { - write!(f, " + ")?; - } - if f.alternate() { - write!(f, "{:#}", *bound)?; - } else { - write!(f, "{}", *bound)?; - } + } + clean::PolyTraitRef(ref bounds) => { + for (i, bound) in bounds.iter().enumerate() { + if i != 0 { + write!(f, " + ")?; } - Ok(()) - } - // It's pretty unsightly to look at `::C` in output, and - // we've got hyperlinking on our side, so try to avoid longer - // notation as much as possible by making `C` a hyperlink to trait - // `B` to disambiguate. - // - // FIXME: this is still a lossy conversion and there should probably - // be a better way of representing this in general? Most of - // the ugliness comes from inlining across crates where - // everything comes in as a fully resolved QPath (hard to - // look at). - clean::QPath { - ref name, - ref self_type, - trait_: box clean::ResolvedPath { did, ref typarams, .. }, - } => { if f.alternate() { - write!(f, "{:#}::", self_type)?; + write!(f, "{:#}", *bound)?; } else { - write!(f, "{}::", self_type)?; + write!(f, "{}", *bound)?; } - let path = clean::Path::singleton(name.clone()); - resolved_path(f, did, &path, false)?; - - // FIXME: `typarams` are not rendered, and this seems bad? - drop(typarams); - Ok(()) } - clean::QPath { ref name, ref self_type, ref trait_ } => { + Ok(()) + } + clean::ImplTrait(ref bounds) => { + write!(f, "impl ")?; + for (i, bound) in bounds.iter().enumerate() { + if i != 0 { + write!(f, " + ")?; + } if f.alternate() { - write!(f, "<{:#} as {:#}>::{}", self_type, trait_, name) + write!(f, "{:#}", *bound)?; } else { - write!(f, "<{} as {}>::{}", self_type, trait_, name) + write!(f, "{}", *bound)?; } } - clean::Unique(..) => { - panic!("should have been cleaned") + Ok(()) + } + // It's pretty unsightly to look at `::C` in output, and + // we've got hyperlinking on our side, so try to avoid longer + // notation as much as possible by making `C` a hyperlink to trait + // `B` to disambiguate. + // + // FIXME: this is still a lossy conversion and there should probably + // be a better way of representing this in general? Most of + // the ugliness comes from inlining across crates where + // everything comes in as a fully resolved QPath (hard to + // look at). + clean::QPath { + ref name, + ref self_type, + trait_: box clean::ResolvedPath { did, ref typarams, .. }, + } => { + if f.alternate() { + write!(f, "{:#}::", self_type)?; + } else { + write!(f, "{}::", self_type)?; + } + let path = clean::Path::singleton(name.clone()); + resolved_path(f, did, &path, true, full_path)?; + + // FIXME: `typarams` are not rendered, and this seems bad? + drop(typarams); + Ok(()) + } + clean::QPath { ref name, ref self_type, ref trait_ } => { + if f.alternate() { + write!(f, "<{:#} as {:#}>::{}", self_type, trait_, name) + } else { + write!(f, "<{} as {}>::{}", self_type, trait_, name) } } + clean::Unique(..) => { + panic!("should have been cleaned") + } + } +} + +impl fmt::Display for clean::Type { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt_type(self, f, false) } } -fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool) -> fmt::Result { +fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool, full: bool) -> fmt::Result { let mut plain = String::new(); if f.alternate() { @@ -759,7 +773,7 @@ fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool) -> fmt::R plain.push_str(&format!("{:#}", ty)); } else { match *ty { - clean::ResolvedPath{ typarams: None, ref path, is_generic: false, .. } => { + clean::ResolvedPath { typarams: None, ref path, is_generic: false, .. } => { let last = path.segments.last().unwrap(); fmt::Display::fmt(&last.name, f)?; fmt::Display::fmt(&last.params, f)?; @@ -772,7 +786,7 @@ fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool) -> fmt::R plain.push_str(" for "); } - fmt::Display::fmt(&i.for_, f)?; + fmt_type(&i.for_, f, full)?; plain.push_str(&format!("{:#}", i.for_)); fmt::Display::fmt(&WhereClause(&i.generics, plain.len() + 1), f)?; @@ -781,13 +795,15 @@ fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool) -> fmt::R impl fmt::Display for clean::Impl { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt_impl(self, f, true) + fmt_impl(self, f, true, false) } } // The difference from above is that trait is not hyperlinked. -pub fn fmt_impl_for_trait_page(i: &clean::Impl, f: &mut fmt::Formatter) -> fmt::Result { - fmt_impl(i, f, false) +pub fn fmt_impl_for_trait_page(i: &clean::Impl, + f: &mut fmt::Formatter, + disambiguate: bool) -> fmt::Result { + fmt_impl(i, f, false, disambiguate) } impl fmt::Display for clean::Arguments { @@ -978,7 +994,7 @@ impl fmt::Display for clean::Import { impl fmt::Display for clean::ImportSource { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.did { - Some(did) => resolved_path(f, did, &self.path, true), + Some(did) => resolved_path(f, did, &self.path, true, false), _ => { for (i, seg) in self.path.segments.iter().enumerate() { if i > 0 { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index e721b66779fff..c7a2581455377 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2111,9 +2111,23 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
    ")?; if let Some(implementors) = cache.implementors.get(&it.def_id) { - for i in implementors { + for k in implementors.iter() { write!(w, "
  • ")?; - fmt_impl_for_trait_page(&i.impl_, w)?; + // If there's already another implementor that has the same abbridged name, use the + // full path, for example in `std::iter::ExactSizeIterator` + let mut dissambiguate = false; + for l in implementors.iter() { + match (k.impl_.for_.clone(), l.impl_.for_.clone()) { + (clean::Type::ResolvedPath {path: path_a, ..}, + clean::Type::ResolvedPath {path: path_b, ..}) => { + if k.def_id != l.def_id && path_a.last_name() == path_b.last_name() { + dissambiguate = true; + } + } + _ => (), + } + } + fmt_impl_for_trait_page(&k.impl_, w, dissambiguate)?; writeln!(w, "
  • ")?; } } From 08aa825eb86f762638ffb401c0387590ec13d20e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Dec 2016 13:30:42 -0800 Subject: [PATCH 2/5] remove O(n^2) to O(n) behavior --- src/librustdoc/html/render.rs | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c7a2581455377..846c0721ccbd3 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2110,24 +2110,27 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,

    Implementors

      ")?; + let mut implementor_count: FxHashMap = FxHashMap(); + for (_, implementors) in cache.implementors.iter() { + for implementor in implementors { + if let clean::Type::ResolvedPath {ref path, ..} = implementor.impl_.for_ { + *implementor_count.entry(path.last_name()).or_insert(0) += 1; + } + } + } if let Some(implementors) = cache.implementors.get(&it.def_id) { - for k in implementors.iter() { + for implementor in implementors.iter() { write!(w, "
    • ")?; // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` - let mut dissambiguate = false; - for l in implementors.iter() { - match (k.impl_.for_.clone(), l.impl_.for_.clone()) { - (clean::Type::ResolvedPath {path: path_a, ..}, - clean::Type::ResolvedPath {path: path_b, ..}) => { - if k.def_id != l.def_id && path_a.last_name() == path_b.last_name() { - dissambiguate = true; - } - } - _ => (), - } - } - fmt_impl_for_trait_page(&k.impl_, w, dissambiguate)?; + let dissambiguate = if let clean::Type::ResolvedPath { + ref path, .. + } = implementor.impl_.for_ { + *implementor_count.get(&path.last_name()).unwrap_or(&0) > 1 + } else { + false + }; + fmt_impl_for_trait_page(&implementor.impl_, w, dissambiguate)?; writeln!(w, "
    • ")?; } } From bf7d7ae7fa2fca33dbe0becebbc75d198321c0a7 Mon Sep 17 00:00:00 2001 From: bluss Date: Wed, 21 Dec 2016 21:27:31 -0800 Subject: [PATCH 3/5] use &str instead of String --- src/librustdoc/clean/mod.rs | 4 ++-- src/librustdoc/html/render.rs | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 28ca92f5db6f6..5b8b2ecf95d39 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2205,8 +2205,8 @@ impl Path { } } - pub fn last_name(&self) -> String { - self.segments.last().unwrap().name.clone() + pub fn last_name(&self) -> &str { + self.segments.last().unwrap().name } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 846c0721ccbd3..5839c46d75d2a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2110,23 +2110,22 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,

      Implementors

        ")?; - let mut implementor_count: FxHashMap = FxHashMap(); - for (_, implementors) in cache.implementors.iter() { + if let Some(implementors) = cache.implementors.get(&it.def_id) { + let mut implementor_count: FxHashMap<&str, usize> = 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; } } - } - if let Some(implementors) = cache.implementors.get(&it.def_id) { - for implementor in implementors.iter() { + + for implementor in implementors { write!(w, "
      • ")?; // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` let dissambiguate = if let clean::Type::ResolvedPath { ref path, .. } = implementor.impl_.for_ { - *implementor_count.get(&path.last_name()).unwrap_or(&0) > 1 + implementor_count[path.last_name()] > 1 } else { false }; From de69a3b7e5cf5c2a8d79fa93013ea581a75493ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 21 Dec 2016 23:13:11 -0800 Subject: [PATCH 4/5] fix String to &str cast --- src/librustdoc/clean/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5b8b2ecf95d39..a48af1c162b5f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2206,7 +2206,7 @@ impl Path { } pub fn last_name(&self) -> &str { - self.segments.last().unwrap().name + self.segments.last().unwrap().name.as_str() } } From 346a44211087a36de91877545ea28e9af501db6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 22 Dec 2016 23:20:22 -0800 Subject: [PATCH 5/5] use same param name across methods --- src/librustdoc/html/format.rs | 17 ++++++++++------- src/librustdoc/html/render.rs | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6808752b1fe05..ed7ad36cc8468 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -561,14 +561,14 @@ impl<'a> fmt::Display for HRef<'a> { } } -fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, full_path: bool) -> fmt::Result { +fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt::Result { match *t { clean::Generic(ref name) => { f.write_str(name) } clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => { // Paths like T::Output and Self::Output should be rendered with all segments - resolved_path(f, did, path, is_generic, full_path)?; + resolved_path(f, did, path, is_generic, use_absolute)?; tybounds(f, typarams) } clean::Infer => write!(f, "_"), @@ -727,7 +727,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, full_path: bool) -> fmt::Re write!(f, "{}::", self_type)?; } let path = clean::Path::singleton(name.clone()); - resolved_path(f, did, &path, true, full_path)?; + resolved_path(f, did, &path, true, use_absolute)?; // FIXME: `typarams` are not rendered, and this seems bad? drop(typarams); @@ -752,7 +752,10 @@ impl fmt::Display for clean::Type { } } -fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool, full: bool) -> fmt::Result { +fn fmt_impl(i: &clean::Impl, + f: &mut fmt::Formatter, + link_trait: bool, + use_absolute: bool) -> fmt::Result { let mut plain = String::new(); if f.alternate() { @@ -786,7 +789,7 @@ fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool, full: boo plain.push_str(" for "); } - fmt_type(&i.for_, f, full)?; + fmt_type(&i.for_, f, use_absolute)?; plain.push_str(&format!("{:#}", i.for_)); fmt::Display::fmt(&WhereClause(&i.generics, plain.len() + 1), f)?; @@ -802,8 +805,8 @@ impl fmt::Display for clean::Impl { // The difference from above is that trait is not hyperlinked. pub fn fmt_impl_for_trait_page(i: &clean::Impl, f: &mut fmt::Formatter, - disambiguate: bool) -> fmt::Result { - fmt_impl(i, f, false, disambiguate) + use_absolute: bool) -> fmt::Result { + fmt_impl(i, f, false, use_absolute) } impl fmt::Display for clean::Arguments { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5839c46d75d2a..dcf7515f87531 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2122,14 +2122,14 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, write!(w, "
      • ")?; // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` - let dissambiguate = if let clean::Type::ResolvedPath { + let use_absolute = if let clean::Type::ResolvedPath { ref path, .. } = implementor.impl_.for_ { implementor_count[path.last_name()] > 1 } else { false }; - fmt_impl_for_trait_page(&implementor.impl_, w, dissambiguate)?; + fmt_impl_for_trait_page(&implementor.impl_, w, use_absolute)?; writeln!(w, "
      • ")?; } }