Fix invalid associated type rendering in rustdoc
This commit is contained in:
parent
c58c928e65
commit
dd7dfe56a9
src
@ -2277,7 +2277,7 @@ impl Clean<PathParameters> for hir::PathParameters {
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
||||
pub struct PathSegment {
|
||||
pub name: String,
|
||||
pub params: PathParameters
|
||||
pub params: PathParameters,
|
||||
}
|
||||
|
||||
impl Clean<PathSegment> for hir::PathSegment {
|
||||
|
@ -470,10 +470,22 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
|
||||
/// 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, use_absolute: bool, is_not_debug: bool) -> fmt::Result {
|
||||
let last = path.segments.last().unwrap();
|
||||
let rel_root = match &*path.segments[0].name {
|
||||
"self" => Some("./".to_string()),
|
||||
_ => None,
|
||||
let empty = clean::PathSegment {
|
||||
name: String::new(),
|
||||
params: clean::PathParameters::Parenthesized {
|
||||
inputs: Vec::new(),
|
||||
output: None,
|
||||
}
|
||||
};
|
||||
let last = path.segments.last()
|
||||
.unwrap_or(&empty);
|
||||
let rel_root = if path.segments.is_empty() {
|
||||
None
|
||||
} else {
|
||||
match &*path.segments[0].name {
|
||||
"self" => Some("./".to_string()),
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
|
||||
if print_all {
|
||||
@ -487,10 +499,9 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
|
||||
root.push_str(&seg.name);
|
||||
root.push_str("/");
|
||||
if is_not_debug {
|
||||
write!(w, "<a class=\"mod\"
|
||||
href=\"{}index.html\">{}</a>::",
|
||||
root,
|
||||
seg.name)?;
|
||||
write!(w, "<a class=\"mod\" href=\"{}index.html\">{}</a>::",
|
||||
root,
|
||||
seg.name)?;
|
||||
} else {
|
||||
write!(w, "{}::", seg.name)?;
|
||||
}
|
||||
@ -516,7 +527,8 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
|
||||
match href(did) {
|
||||
Some((_, _, fqp)) => format!("{}::{}",
|
||||
fqp[..fqp.len()-1].join("::"),
|
||||
HRef::new(did, fqp.last().unwrap())),
|
||||
HRef::new(did, fqp.last()
|
||||
.unwrap_or(&String::new()))),
|
||||
None => format!("{}", HRef::new(did, &last.name)),
|
||||
}
|
||||
} else {
|
||||
@ -528,7 +540,8 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
|
||||
match href(did) {
|
||||
Some((_, _, fqp)) => format!("{:?}::{:?}",
|
||||
fqp[..fqp.len()-1].join("::"),
|
||||
HRef::new(did, fqp.last().unwrap())),
|
||||
HRef::new(did, fqp.last()
|
||||
.unwrap_or(&String::new()))),
|
||||
None => format!("{:?}", HRef::new(did, &last.name)),
|
||||
}
|
||||
} else {
|
||||
@ -801,45 +814,65 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
// It's pretty unsightly to look at `<A as B>::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, use_absolute, is_not_debug)?;
|
||||
|
||||
// FIXME: `typarams` are not rendered, and this seems bad?
|
||||
drop(typarams);
|
||||
Ok(())
|
||||
}
|
||||
clean::QPath { ref name, ref self_type, ref trait_ } => {
|
||||
let should_show_cast = match *trait_ {
|
||||
box clean::ResolvedPath { .. } => {
|
||||
let path = clean::Path::singleton(name.clone());
|
||||
!path.segments.is_empty() && &format!("{:#}", trait_) != "()" &&
|
||||
&format!("{:#}", self_type) != "Self"
|
||||
}
|
||||
_ => true,
|
||||
};
|
||||
if f.alternate() {
|
||||
if is_not_debug {
|
||||
write!(f, "<{:#} as {:#}>::{}", self_type, trait_, name)
|
||||
if should_show_cast {
|
||||
write!(f, "<{:#} as {:#}>::", self_type, trait_)?
|
||||
} else {
|
||||
write!(f, "{:#}::", self_type)?
|
||||
}
|
||||
} else {
|
||||
write!(f, "<{:#?} as {:#?}>::{}", self_type, trait_, name)
|
||||
if should_show_cast {
|
||||
write!(f, "<{:#?} as {:#?}>::", self_type, trait_)?
|
||||
} else {
|
||||
write!(f, "{:#?}::", self_type)?
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if is_not_debug {
|
||||
write!(f, "<{} as {}>::{}", self_type, trait_, name)
|
||||
if should_show_cast {
|
||||
write!(f, "<{} as {}>::", self_type, trait_)?
|
||||
} else {
|
||||
write!(f, "{}::", self_type)?
|
||||
}
|
||||
} else {
|
||||
write!(f, "<{:?} as {:?}>::{}", self_type, trait_, name)
|
||||
if should_show_cast {
|
||||
write!(f, "<{:?} as {:?}>::", self_type, trait_)?
|
||||
} else {
|
||||
write!(f, "{:?}::", self_type)?
|
||||
}
|
||||
}
|
||||
};
|
||||
match *trait_ {
|
||||
// It's pretty unsightly to look at `<A as B>::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).
|
||||
box clean::ResolvedPath { did, ref typarams, .. } => {
|
||||
let path = clean::Path::singleton(name.clone());
|
||||
resolved_path(f, did, &path, true, use_absolute, is_not_debug)?;
|
||||
|
||||
// FIXME: `typarams` are not rendered, and this seems bad?
|
||||
drop(typarams);
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
write!(f, "{}", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
src/test/rustdoc/assoc-item-cast.rs
Normal file
26
src/test/rustdoc/assoc-item-cast.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// 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"]
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
pub trait Expression {
|
||||
type SqlType;
|
||||
}
|
||||
|
||||
pub trait AsExpression<T> {
|
||||
type Expression: Expression<SqlType = T>;
|
||||
fn as_expression(self) -> Self::Expression;
|
||||
}
|
||||
|
||||
// @has foo/type.AsExprOf.html
|
||||
// @has - '//*[@class="rust typedef"]' 'type AsExprOf<Item, Type> = <Item as AsExpression<Type>>::Expression;'
|
||||
pub type AsExprOf<Item, Type> = <Item as AsExpression<Type>>::Expression;
|
Loading…
Reference in New Issue
Block a user