Rustdoc: disambiguate Implementors when the type name is not unique
This commit is contained in:
parent
6483bdd860
commit
2841bf3bc7
2 changed files with 201 additions and 171 deletions
|
@ -433,7 +433,7 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
|
|||
/// 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,15 +561,14 @@ impl<'a> fmt::Display for HRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for clean::Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
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)?;
|
||||
resolved_path(f, did, path, is_generic, full_path)?;
|
||||
tybounds(f, typarams)
|
||||
}
|
||||
clean::Infer => write!(f, "_"),
|
||||
|
@ -718,7 +727,7 @@ impl fmt::Display for clean::Type {
|
|||
write!(f, "{}::", self_type)?;
|
||||
}
|
||||
let path = clean::Path::singleton(name.clone());
|
||||
resolved_path(f, did, &path, false)?;
|
||||
resolved_path(f, did, &path, true, full_path)?;
|
||||
|
||||
// FIXME: `typarams` are not rendered, and this seems bad?
|
||||
drop(typarams);
|
||||
|
@ -735,10 +744,15 @@ impl fmt::Display for clean::Type {
|
|||
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 {
|
||||
|
|
|
@ -2111,9 +2111,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) {
|
||||
for i in implementors {
|
||||
for k in implementors.iter() {
|
||||
write!(w, "<li><code>")?;
|
||||
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, "</code></li>")?;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue