Rollup merge of #37190 - QuietMisdreavus:rustdoc-where-newline, r=GuillaumeGomez
rustdoc: add line breaks to where clauses a la rustfmt Much like my last PR for rustdoc (#36679), this adds line breaks to certain statements based on their line length. Here the focus was on where clauses. Some examples: - [Where clause in a trait function](https://shiva.icesoldier.me/custom-std/std/iter/trait.Iterator.html?search=#method.unzip) (also in the trait header block at the top of the page) - [Where clause on a bare function](https://shiva.icesoldier.me/doc-custom2/petgraph/visit/fn.depth_first_search.html) - [Where clauses in trait impls on a struct](https://shiva.icesoldier.me/custom-std/std/collections/struct.HashMap.html) (scroll to the bottom) These are regularly not on their own line, but will be given their own line now if their "prefix text" doesn't give them enough room to sensibly print their constraints. HashMap's trait impls provide some examples of both behaviors. The libstd links above are the whole docs rendered with this, and the "bare function" link above is in another set that pulls some notable crates together. `petgraph` was the one that brought this request up, and that collection also includes [itertools](https://shiva.icesoldier.me/doc-custom2/itertools/trait.Itertools.html) which provided an easy sample to test with. r? @GuillaumeGomez
This commit is contained in:
commit
2db360eec1
4 changed files with 156 additions and 52 deletions
|
@ -42,7 +42,7 @@ pub struct UnsafetySpace(pub hir::Unsafety);
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct ConstnessSpace(pub hir::Constness);
|
pub struct ConstnessSpace(pub hir::Constness);
|
||||||
/// Wrapper struct for properly emitting a method declaration.
|
/// Wrapper struct for properly emitting a method declaration.
|
||||||
pub struct Method<'a>(pub &'a clean::FnDecl, pub &'a str);
|
pub struct Method<'a>(pub &'a clean::FnDecl, pub usize);
|
||||||
/// Similar to VisSpace, but used for mutability
|
/// Similar to VisSpace, but used for mutability
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct MutableSpace(pub clean::Mutability);
|
pub struct MutableSpace(pub clean::Mutability);
|
||||||
|
@ -50,7 +50,7 @@ pub struct MutableSpace(pub clean::Mutability);
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct RawMutableSpace(pub clean::Mutability);
|
pub struct RawMutableSpace(pub clean::Mutability);
|
||||||
/// Wrapper struct for emitting a where clause from Generics.
|
/// Wrapper struct for emitting a where clause from Generics.
|
||||||
pub struct WhereClause<'a>(pub &'a clean::Generics);
|
pub struct WhereClause<'a>(pub &'a clean::Generics, pub usize);
|
||||||
/// Wrapper struct for emitting type parameter bounds.
|
/// Wrapper struct for emitting type parameter bounds.
|
||||||
pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
|
pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
|
||||||
/// Wrapper struct for emitting a comma-separated list of items
|
/// Wrapper struct for emitting a comma-separated list of items
|
||||||
|
@ -157,52 +157,71 @@ impl fmt::Display for clean::Generics {
|
||||||
|
|
||||||
impl<'a> fmt::Display for WhereClause<'a> {
|
impl<'a> fmt::Display for WhereClause<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let &WhereClause(gens) = self;
|
let &WhereClause(gens, pad) = self;
|
||||||
if gens.where_predicates.is_empty() {
|
if gens.where_predicates.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
let mut clause = String::new();
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
f.write_str(" ")?;
|
clause.push_str(" where ");
|
||||||
} else {
|
} else {
|
||||||
f.write_str(" <span class='where'>where ")?;
|
clause.push_str(" <span class='where'>where ");
|
||||||
}
|
}
|
||||||
for (i, pred) in gens.where_predicates.iter().enumerate() {
|
for (i, pred) in gens.where_predicates.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
f.write_str(", ")?;
|
if f.alternate() {
|
||||||
|
clause.push_str(", ");
|
||||||
|
} else {
|
||||||
|
clause.push_str(",<br>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
match pred {
|
match pred {
|
||||||
&clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => {
|
&clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => {
|
||||||
let bounds = bounds;
|
let bounds = bounds;
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(f, "{:#}: {:#}", ty, TyParamBounds(bounds))?;
|
clause.push_str(&format!("{:#}: {:#}", ty, TyParamBounds(bounds)));
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}: {}", ty, TyParamBounds(bounds))?;
|
clause.push_str(&format!("{}: {}", ty, TyParamBounds(bounds)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&clean::WherePredicate::RegionPredicate { ref lifetime,
|
&clean::WherePredicate::RegionPredicate { ref lifetime,
|
||||||
ref bounds } => {
|
ref bounds } => {
|
||||||
write!(f, "{}: ", lifetime)?;
|
clause.push_str(&format!("{}: ", lifetime));
|
||||||
for (i, lifetime) in bounds.iter().enumerate() {
|
for (i, lifetime) in bounds.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
f.write_str(" + ")?;
|
clause.push_str(" + ");
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, "{}", lifetime)?;
|
clause.push_str(&format!("{}", lifetime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&clean::WherePredicate::EqPredicate { ref lhs, ref rhs } => {
|
&clean::WherePredicate::EqPredicate { ref lhs, ref rhs } => {
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(f, "{:#} == {:#}", lhs, rhs)?;
|
clause.push_str(&format!("{:#} == {:#}", lhs, rhs));
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{} == {}", lhs, rhs)?;
|
clause.push_str(&format!("{} == {}", lhs, rhs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !f.alternate() {
|
if !f.alternate() {
|
||||||
f.write_str("</span>")?;
|
clause.push_str("</span>");
|
||||||
|
let plain = format!("{:#}", self);
|
||||||
|
if plain.len() > 80 {
|
||||||
|
//break it onto its own line regardless, but make sure method impls and trait
|
||||||
|
//blocks keep their fixed padding (2 and 9, respectively)
|
||||||
|
let padding = if pad > 10 {
|
||||||
|
clause = clause.replace("class='where'", "class='where fmt-newline'");
|
||||||
|
repeat(" ").take(8).collect::<String>()
|
||||||
|
} else {
|
||||||
|
repeat(" ").take(pad + 6).collect::<String>()
|
||||||
|
};
|
||||||
|
clause = clause.replace("<br>", &format!("<br>{}", padding));
|
||||||
|
} else {
|
||||||
|
clause = clause.replace("<br>", " ");
|
||||||
}
|
}
|
||||||
Ok(())
|
}
|
||||||
|
write!(f, "{}", clause)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,30 +737,43 @@ impl fmt::Display for clean::Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) -> fmt::Result {
|
||||||
|
let mut plain = String::new();
|
||||||
|
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(f, "impl{:#} ", i.generics)?;
|
write!(f, "impl{:#} ", i.generics)?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, "impl{} ", i.generics)?;
|
write!(f, "impl{} ", i.generics)?;
|
||||||
}
|
}
|
||||||
|
plain.push_str(&format!("impl{:#} ", i.generics));
|
||||||
|
|
||||||
if let Some(ref ty) = i.trait_ {
|
if let Some(ref ty) = i.trait_ {
|
||||||
write!(f, "{}",
|
if i.polarity == Some(clean::ImplPolarity::Negative) {
|
||||||
if i.polarity == Some(clean::ImplPolarity::Negative) { "!" } else { "" })?;
|
write!(f, "!")?;
|
||||||
|
plain.push_str("!");
|
||||||
|
}
|
||||||
|
|
||||||
if link_trait {
|
if link_trait {
|
||||||
fmt::Display::fmt(ty, f)?;
|
fmt::Display::fmt(ty, f)?;
|
||||||
|
plain.push_str(&format!("{:#}", ty));
|
||||||
} else {
|
} else {
|
||||||
match *ty {
|
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();
|
let last = path.segments.last().unwrap();
|
||||||
fmt::Display::fmt(&last.name, f)?;
|
fmt::Display::fmt(&last.name, f)?;
|
||||||
fmt::Display::fmt(&last.params, f)?;
|
fmt::Display::fmt(&last.params, f)?;
|
||||||
|
plain.push_str(&format!("{:#}{:#}", last.name, last.params));
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write!(f, " for ")?;
|
write!(f, " for ")?;
|
||||||
|
plain.push_str(" for ");
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::Display::fmt(&i.for_, f)?;
|
fmt::Display::fmt(&i.for_, f)?;
|
||||||
fmt::Display::fmt(&WhereClause(&i.generics), f)?;
|
plain.push_str(&format!("{:#}", i.for_));
|
||||||
|
|
||||||
|
fmt::Display::fmt(&WhereClause(&i.generics, plain.len() + 1), f)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -870,26 +902,32 @@ impl<'a> fmt::Display for Method<'a> {
|
||||||
|
|
||||||
let mut output: String;
|
let mut output: String;
|
||||||
let plain: String;
|
let plain: String;
|
||||||
|
let pad = repeat(" ").take(indent).collect::<String>();
|
||||||
if arrow.is_empty() {
|
if arrow.is_empty() {
|
||||||
output = format!("({})", args);
|
output = format!("({})", args);
|
||||||
plain = format!("{}({})", indent.replace(" ", " "), args_plain);
|
plain = format!("{}({})", pad, args_plain);
|
||||||
} else {
|
} else {
|
||||||
output = format!("({args})<br>{arrow}", args = args, arrow = arrow);
|
output = format!("({args})<br>{arrow}", args = args, arrow = arrow);
|
||||||
plain = format!("{indent}({args}){arrow}",
|
plain = format!("{pad}({args}){arrow}",
|
||||||
indent = indent.replace(" ", " "),
|
pad = pad,
|
||||||
args = args_plain,
|
args = args_plain,
|
||||||
arrow = arrow_plain);
|
arrow = arrow_plain);
|
||||||
}
|
}
|
||||||
|
|
||||||
if plain.len() > 80 {
|
if plain.len() > 80 {
|
||||||
let pad = format!("<br>{}", indent);
|
let pad = repeat(" ").take(indent).collect::<String>();
|
||||||
|
let pad = format!("<br>{}", pad);
|
||||||
output = output.replace("<br>", &pad);
|
output = output.replace("<br>", &pad);
|
||||||
} else {
|
} else {
|
||||||
output = output.replace("<br>", "");
|
output = output.replace("<br>", "");
|
||||||
}
|
}
|
||||||
|
if f.alternate() {
|
||||||
|
write!(f, "{}", output.replace("<br>", "\n"))
|
||||||
|
} else {
|
||||||
write!(f, "{}", output)
|
write!(f, "{}", output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Display for VisSpace<'a> {
|
impl<'a> fmt::Display for VisSpace<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
|
|
@ -1972,14 +1972,13 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
UnstableFeatures::Allow => f.constness,
|
UnstableFeatures::Allow => f.constness,
|
||||||
_ => hir::Constness::NotConst
|
_ => hir::Constness::NotConst
|
||||||
};
|
};
|
||||||
let prefix = format!("{}{}{}{:#}fn {}{:#}",
|
let indent = format!("{}{}{}{:#}fn {}{:#}",
|
||||||
VisSpace(&it.visibility),
|
VisSpace(&it.visibility),
|
||||||
ConstnessSpace(vis_constness),
|
ConstnessSpace(vis_constness),
|
||||||
UnsafetySpace(f.unsafety),
|
UnsafetySpace(f.unsafety),
|
||||||
AbiSpace(f.abi),
|
AbiSpace(f.abi),
|
||||||
it.name.as_ref().unwrap(),
|
it.name.as_ref().unwrap(),
|
||||||
f.generics);
|
f.generics).len();
|
||||||
let indent = repeat(" ").take(prefix.len()).collect::<String>();
|
|
||||||
write!(w, "<pre class='rust fn'>{vis}{constness}{unsafety}{abi}fn \
|
write!(w, "<pre class='rust fn'>{vis}{constness}{unsafety}{abi}fn \
|
||||||
{name}{generics}{decl}{where_clause}</pre>",
|
{name}{generics}{decl}{where_clause}</pre>",
|
||||||
vis = VisSpace(&it.visibility),
|
vis = VisSpace(&it.visibility),
|
||||||
|
@ -1988,22 +1987,29 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
abi = AbiSpace(f.abi),
|
abi = AbiSpace(f.abi),
|
||||||
name = it.name.as_ref().unwrap(),
|
name = it.name.as_ref().unwrap(),
|
||||||
generics = f.generics,
|
generics = f.generics,
|
||||||
where_clause = WhereClause(&f.generics),
|
where_clause = WhereClause(&f.generics, 2),
|
||||||
decl = Method(&f.decl, &indent))?;
|
decl = Method(&f.decl, indent))?;
|
||||||
document(w, cx, it)
|
document(w, cx, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
t: &clean::Trait) -> fmt::Result {
|
t: &clean::Trait) -> fmt::Result {
|
||||||
let mut bounds = String::new();
|
let mut bounds = String::new();
|
||||||
|
let mut bounds_plain = String::new();
|
||||||
if !t.bounds.is_empty() {
|
if !t.bounds.is_empty() {
|
||||||
if !bounds.is_empty() {
|
if !bounds.is_empty() {
|
||||||
bounds.push(' ');
|
bounds.push(' ');
|
||||||
|
bounds_plain.push(' ');
|
||||||
}
|
}
|
||||||
bounds.push_str(": ");
|
bounds.push_str(": ");
|
||||||
|
bounds_plain.push_str(": ");
|
||||||
for (i, p) in t.bounds.iter().enumerate() {
|
for (i, p) in t.bounds.iter().enumerate() {
|
||||||
if i > 0 { bounds.push_str(" + "); }
|
if i > 0 {
|
||||||
|
bounds.push_str(" + ");
|
||||||
|
bounds_plain.push_str(" + ");
|
||||||
|
}
|
||||||
bounds.push_str(&format!("{}", *p));
|
bounds.push_str(&format!("{}", *p));
|
||||||
|
bounds_plain.push_str(&format!("{:#}", *p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2014,7 +2020,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
it.name.as_ref().unwrap(),
|
it.name.as_ref().unwrap(),
|
||||||
t.generics,
|
t.generics,
|
||||||
bounds,
|
bounds,
|
||||||
WhereClause(&t.generics))?;
|
// Where clauses in traits are indented nine spaces, per rustdoc.css
|
||||||
|
WhereClause(&t.generics, 9))?;
|
||||||
|
|
||||||
let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
|
let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
|
||||||
let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
|
let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
|
||||||
|
@ -2028,7 +2035,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
write!(w, "{{\n")?;
|
write!(w, "{{\n")?;
|
||||||
for t in &types {
|
for t in &types {
|
||||||
write!(w, " ")?;
|
write!(w, " ")?;
|
||||||
render_assoc_item(w, t, AssocItemLink::Anchor(None))?;
|
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||||
write!(w, ";\n")?;
|
write!(w, ";\n")?;
|
||||||
}
|
}
|
||||||
if !types.is_empty() && !consts.is_empty() {
|
if !types.is_empty() && !consts.is_empty() {
|
||||||
|
@ -2036,7 +2043,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
}
|
}
|
||||||
for t in &consts {
|
for t in &consts {
|
||||||
write!(w, " ")?;
|
write!(w, " ")?;
|
||||||
render_assoc_item(w, t, AssocItemLink::Anchor(None))?;
|
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||||
write!(w, ";\n")?;
|
write!(w, ";\n")?;
|
||||||
}
|
}
|
||||||
if !consts.is_empty() && !required.is_empty() {
|
if !consts.is_empty() && !required.is_empty() {
|
||||||
|
@ -2044,7 +2051,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
}
|
}
|
||||||
for m in &required {
|
for m in &required {
|
||||||
write!(w, " ")?;
|
write!(w, " ")?;
|
||||||
render_assoc_item(w, m, AssocItemLink::Anchor(None))?;
|
render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||||
write!(w, ";\n")?;
|
write!(w, ";\n")?;
|
||||||
}
|
}
|
||||||
if !required.is_empty() && !provided.is_empty() {
|
if !required.is_empty() && !provided.is_empty() {
|
||||||
|
@ -2052,7 +2059,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
}
|
}
|
||||||
for m in &provided {
|
for m in &provided {
|
||||||
write!(w, " ")?;
|
write!(w, " ")?;
|
||||||
render_assoc_item(w, m, AssocItemLink::Anchor(None))?;
|
render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||||
write!(w, " {{ ... }}\n")?;
|
write!(w, " {{ ... }}\n")?;
|
||||||
}
|
}
|
||||||
write!(w, "}}")?;
|
write!(w, "}}")?;
|
||||||
|
@ -2073,7 +2080,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
id = id,
|
id = id,
|
||||||
stab = m.stability_class(),
|
stab = m.stability_class(),
|
||||||
ns_id = ns_id)?;
|
ns_id = ns_id)?;
|
||||||
render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)))?;
|
render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl)?;
|
||||||
write!(w, "</code>")?;
|
write!(w, "</code>")?;
|
||||||
render_stability_since(w, m, t)?;
|
render_stability_since(w, m, t)?;
|
||||||
write!(w, "</span></h3>")?;
|
write!(w, "</span></h3>")?;
|
||||||
|
@ -2227,7 +2234,8 @@ fn render_stability_since(w: &mut fmt::Formatter,
|
||||||
|
|
||||||
fn render_assoc_item(w: &mut fmt::Formatter,
|
fn render_assoc_item(w: &mut fmt::Formatter,
|
||||||
item: &clean::Item,
|
item: &clean::Item,
|
||||||
link: AssocItemLink) -> fmt::Result {
|
link: AssocItemLink,
|
||||||
|
parent: ItemType) -> fmt::Result {
|
||||||
fn method(w: &mut fmt::Formatter,
|
fn method(w: &mut fmt::Formatter,
|
||||||
meth: &clean::Item,
|
meth: &clean::Item,
|
||||||
unsafety: hir::Unsafety,
|
unsafety: hir::Unsafety,
|
||||||
|
@ -2235,7 +2243,8 @@ fn render_assoc_item(w: &mut fmt::Formatter,
|
||||||
abi: abi::Abi,
|
abi: abi::Abi,
|
||||||
g: &clean::Generics,
|
g: &clean::Generics,
|
||||||
d: &clean::FnDecl,
|
d: &clean::FnDecl,
|
||||||
link: AssocItemLink)
|
link: AssocItemLink,
|
||||||
|
parent: ItemType)
|
||||||
-> fmt::Result {
|
-> fmt::Result {
|
||||||
let name = meth.name.as_ref().unwrap();
|
let name = meth.name.as_ref().unwrap();
|
||||||
let anchor = format!("#{}.{}", meth.type_(), name);
|
let anchor = format!("#{}.{}", meth.type_(), name);
|
||||||
|
@ -2265,7 +2274,16 @@ fn render_assoc_item(w: &mut fmt::Formatter,
|
||||||
AbiSpace(abi),
|
AbiSpace(abi),
|
||||||
name,
|
name,
|
||||||
*g);
|
*g);
|
||||||
let indent = repeat(" ").take(prefix.len()).collect::<String>();
|
let mut indent = prefix.len();
|
||||||
|
let where_indent = if parent == ItemType::Trait {
|
||||||
|
indent += 4;
|
||||||
|
8
|
||||||
|
} else if parent == ItemType::Impl {
|
||||||
|
2
|
||||||
|
} else {
|
||||||
|
let prefix = prefix + &format!("{:#}", Method(d, indent));
|
||||||
|
prefix.lines().last().unwrap().len() + 1
|
||||||
|
};
|
||||||
write!(w, "{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
|
write!(w, "{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
|
||||||
{generics}{decl}{where_clause}",
|
{generics}{decl}{where_clause}",
|
||||||
ConstnessSpace(vis_constness),
|
ConstnessSpace(vis_constness),
|
||||||
|
@ -2274,19 +2292,18 @@ fn render_assoc_item(w: &mut fmt::Formatter,
|
||||||
href = href,
|
href = href,
|
||||||
name = name,
|
name = name,
|
||||||
generics = *g,
|
generics = *g,
|
||||||
decl = Method(d, &indent),
|
decl = Method(d, indent),
|
||||||
where_clause = WhereClause(g))
|
where_clause = WhereClause(g, where_indent))
|
||||||
}
|
}
|
||||||
match item.inner {
|
match item.inner {
|
||||||
clean::StrippedItem(..) => Ok(()),
|
clean::StrippedItem(..) => Ok(()),
|
||||||
clean::TyMethodItem(ref m) => {
|
clean::TyMethodItem(ref m) => {
|
||||||
method(w, item, m.unsafety, hir::Constness::NotConst,
|
method(w, item, m.unsafety, hir::Constness::NotConst,
|
||||||
m.abi, &m.generics, &m.decl, link)
|
m.abi, &m.generics, &m.decl, link, parent)
|
||||||
}
|
}
|
||||||
clean::MethodItem(ref m) => {
|
clean::MethodItem(ref m) => {
|
||||||
method(w, item, m.unsafety, m.constness,
|
method(w, item, m.unsafety, m.constness,
|
||||||
m.abi, &m.generics, &m.decl,
|
m.abi, &m.generics, &m.decl, link, parent)
|
||||||
link)
|
|
||||||
}
|
}
|
||||||
clean::AssociatedConstItem(ref ty, ref default) => {
|
clean::AssociatedConstItem(ref ty, ref default) => {
|
||||||
assoc_const(w, item, ty, default.as_ref(), link)
|
assoc_const(w, item, ty, default.as_ref(), link)
|
||||||
|
@ -2383,11 +2400,15 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
e: &clean::Enum) -> fmt::Result {
|
e: &clean::Enum) -> fmt::Result {
|
||||||
write!(w, "<pre class='rust enum'>")?;
|
write!(w, "<pre class='rust enum'>")?;
|
||||||
render_attributes(w, it)?;
|
render_attributes(w, it)?;
|
||||||
|
let padding = format!("{}enum {}{:#} ",
|
||||||
|
VisSpace(&it.visibility),
|
||||||
|
it.name.as_ref().unwrap(),
|
||||||
|
e.generics).len();
|
||||||
write!(w, "{}enum {}{}{}",
|
write!(w, "{}enum {}{}{}",
|
||||||
VisSpace(&it.visibility),
|
VisSpace(&it.visibility),
|
||||||
it.name.as_ref().unwrap(),
|
it.name.as_ref().unwrap(),
|
||||||
e.generics,
|
e.generics,
|
||||||
WhereClause(&e.generics))?;
|
WhereClause(&e.generics, padding))?;
|
||||||
if e.variants.is_empty() && !e.variants_stripped {
|
if e.variants.is_empty() && !e.variants_stripped {
|
||||||
write!(w, " {{}}")?;
|
write!(w, " {{}}")?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2559,17 +2580,23 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
||||||
fields: &[clean::Item],
|
fields: &[clean::Item],
|
||||||
tab: &str,
|
tab: &str,
|
||||||
structhead: bool) -> fmt::Result {
|
structhead: bool) -> fmt::Result {
|
||||||
|
let mut plain = String::new();
|
||||||
write!(w, "{}{}{}",
|
write!(w, "{}{}{}",
|
||||||
VisSpace(&it.visibility),
|
VisSpace(&it.visibility),
|
||||||
if structhead {"struct "} else {""},
|
if structhead {"struct "} else {""},
|
||||||
it.name.as_ref().unwrap())?;
|
it.name.as_ref().unwrap())?;
|
||||||
|
plain.push_str(&format!("{}{}{}",
|
||||||
|
VisSpace(&it.visibility),
|
||||||
|
if structhead {"struct "} else {""},
|
||||||
|
it.name.as_ref().unwrap()));
|
||||||
if let Some(g) = g {
|
if let Some(g) = g {
|
||||||
|
plain.push_str(&format!("{:#}", g));
|
||||||
write!(w, "{}", g)?
|
write!(w, "{}", g)?
|
||||||
}
|
}
|
||||||
match ty {
|
match ty {
|
||||||
doctree::Plain => {
|
doctree::Plain => {
|
||||||
if let Some(g) = g {
|
if let Some(g) = g {
|
||||||
write!(w, "{}", WhereClause(g))?
|
write!(w, "{}", WhereClause(g, plain.len() + 1))?
|
||||||
}
|
}
|
||||||
let mut has_visible_fields = false;
|
let mut has_visible_fields = false;
|
||||||
write!(w, " {{")?;
|
write!(w, " {{")?;
|
||||||
|
@ -2598,30 +2625,35 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
||||||
}
|
}
|
||||||
doctree::Tuple => {
|
doctree::Tuple => {
|
||||||
write!(w, "(")?;
|
write!(w, "(")?;
|
||||||
|
plain.push_str("(");
|
||||||
for (i, field) in fields.iter().enumerate() {
|
for (i, field) in fields.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
write!(w, ", ")?;
|
write!(w, ", ")?;
|
||||||
|
plain.push_str(", ");
|
||||||
}
|
}
|
||||||
match field.inner {
|
match field.inner {
|
||||||
clean::StrippedItem(box clean::StructFieldItem(..)) => {
|
clean::StrippedItem(box clean::StructFieldItem(..)) => {
|
||||||
|
plain.push_str("_");
|
||||||
write!(w, "_")?
|
write!(w, "_")?
|
||||||
}
|
}
|
||||||
clean::StructFieldItem(ref ty) => {
|
clean::StructFieldItem(ref ty) => {
|
||||||
|
plain.push_str(&format!("{}{:#}", VisSpace(&field.visibility), *ty));
|
||||||
write!(w, "{}{}", VisSpace(&field.visibility), *ty)?
|
write!(w, "{}{}", VisSpace(&field.visibility), *ty)?
|
||||||
}
|
}
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write!(w, ")")?;
|
write!(w, ")")?;
|
||||||
|
plain.push_str(")");
|
||||||
if let Some(g) = g {
|
if let Some(g) = g {
|
||||||
write!(w, "{}", WhereClause(g))?
|
write!(w, "{}", WhereClause(g, plain.len() + 1))?
|
||||||
}
|
}
|
||||||
write!(w, ";")?;
|
write!(w, ";")?;
|
||||||
}
|
}
|
||||||
doctree::Unit => {
|
doctree::Unit => {
|
||||||
// Needed for PhantomData.
|
// Needed for PhantomData.
|
||||||
if let Some(g) = g {
|
if let Some(g) = g {
|
||||||
write!(w, "{}", WhereClause(g))?
|
write!(w, "{}", WhereClause(g, plain.len() + 1))?
|
||||||
}
|
}
|
||||||
write!(w, ";")?;
|
write!(w, ";")?;
|
||||||
}
|
}
|
||||||
|
@ -2634,13 +2666,19 @@ fn render_union(w: &mut fmt::Formatter, it: &clean::Item,
|
||||||
fields: &[clean::Item],
|
fields: &[clean::Item],
|
||||||
tab: &str,
|
tab: &str,
|
||||||
structhead: bool) -> fmt::Result {
|
structhead: bool) -> fmt::Result {
|
||||||
|
let mut plain = String::new();
|
||||||
write!(w, "{}{}{}",
|
write!(w, "{}{}{}",
|
||||||
VisSpace(&it.visibility),
|
VisSpace(&it.visibility),
|
||||||
if structhead {"union "} else {""},
|
if structhead {"union "} else {""},
|
||||||
it.name.as_ref().unwrap())?;
|
it.name.as_ref().unwrap())?;
|
||||||
|
plain.push_str(&format!("{}{}{}",
|
||||||
|
VisSpace(&it.visibility),
|
||||||
|
if structhead {"union "} else {""},
|
||||||
|
it.name.as_ref().unwrap()));
|
||||||
if let Some(g) = g {
|
if let Some(g) = g {
|
||||||
write!(w, "{}", g)?;
|
write!(w, "{}", g)?;
|
||||||
write!(w, "{}", WhereClause(g))?;
|
plain.push_str(&format!("{:#}", g));
|
||||||
|
write!(w, "{}", WhereClause(g, plain.len() + 1))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(w, " {{\n{}", tab)?;
|
write!(w, " {{\n{}", tab)?;
|
||||||
|
@ -2831,7 +2869,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
||||||
write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
|
write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
|
||||||
write!(w, "<span id='{}' class='invisible'>", ns_id)?;
|
write!(w, "<span id='{}' class='invisible'>", ns_id)?;
|
||||||
write!(w, "<code>")?;
|
write!(w, "<code>")?;
|
||||||
render_assoc_item(w, item, link.anchor(&id))?;
|
render_assoc_item(w, item, link.anchor(&id), ItemType::Impl)?;
|
||||||
write!(w, "</code>")?;
|
write!(w, "</code>")?;
|
||||||
render_stability_since_raw(w, item.stable_since(), outer_version)?;
|
render_stability_since_raw(w, item.stable_since(), outer_version)?;
|
||||||
write!(w, "</span></h4>\n")?;
|
write!(w, "</span></h4>\n")?;
|
||||||
|
@ -2941,10 +2979,11 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
||||||
|
|
||||||
fn item_typedef(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
fn item_typedef(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
t: &clean::Typedef) -> fmt::Result {
|
t: &clean::Typedef) -> fmt::Result {
|
||||||
|
let indent = format!("type {}{:#} ", it.name.as_ref().unwrap(), t.generics).len();
|
||||||
write!(w, "<pre class='rust typedef'>type {}{}{where_clause} = {type_};</pre>",
|
write!(w, "<pre class='rust typedef'>type {}{}{where_clause} = {type_};</pre>",
|
||||||
it.name.as_ref().unwrap(),
|
it.name.as_ref().unwrap(),
|
||||||
t.generics,
|
t.generics,
|
||||||
where_clause = WhereClause(&t.generics),
|
where_clause = WhereClause(&t.generics, indent),
|
||||||
type_ = t.type_)?;
|
type_ = t.type_)?;
|
||||||
|
|
||||||
document(w, cx, it)
|
document(w, cx, it)
|
||||||
|
|
|
@ -361,9 +361,17 @@ h4 > code, h3 > code, .invisible > code {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
/* Shift "where ..." part of method or fn definition down a line */
|
/* Shift "where ..." part of method or fn definition down a line */
|
||||||
.content .method .where, .content .fn .where { display: block; }
|
.content .method .where,
|
||||||
|
.content .fn .where,
|
||||||
|
.content .where.fmt-newline {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
/* Bit of whitespace to indent it */
|
/* Bit of whitespace to indent it */
|
||||||
.content .method .where::before, .content .fn .where::before { content: ' '; }
|
.content .method .where::before,
|
||||||
|
.content .fn .where::before,
|
||||||
|
.content .where.fmt-newline::before {
|
||||||
|
content: ' ';
|
||||||
|
}
|
||||||
|
|
||||||
.content .methods > div { margin-left: 40px; }
|
.content .methods > div { margin-left: 40px; }
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
use std::ops::Add;
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
//@count foo/fn.function_with_a_really_long_name.html //pre/br 2
|
//@count foo/fn.function_with_a_really_long_name.html //pre/br 2
|
||||||
pub fn function_with_a_really_long_name(parameter_one: i32,
|
pub fn function_with_a_really_long_name(parameter_one: i32,
|
||||||
parameter_two: i32)
|
parameter_two: i32)
|
||||||
|
@ -19,3 +22,19 @@ pub fn function_with_a_really_long_name(parameter_one: i32,
|
||||||
|
|
||||||
//@count foo/fn.short_name.html //pre/br 0
|
//@count foo/fn.short_name.html //pre/br 0
|
||||||
pub fn short_name(param: i32) -> i32 { param + 1 }
|
pub fn short_name(param: i32) -> i32 { param + 1 }
|
||||||
|
|
||||||
|
//@count foo/fn.where_clause.html //pre/br 4
|
||||||
|
pub fn where_clause<T, U>(param_one: T,
|
||||||
|
param_two: U)
|
||||||
|
where T: Add<U> + Display + Copy,
|
||||||
|
U: Add<T> + Display + Copy,
|
||||||
|
T::Output: Display + Add<U::Output> + Copy,
|
||||||
|
<T::Output as Add<U::Output>>::Output: Display,
|
||||||
|
U::Output: Display + Copy
|
||||||
|
{
|
||||||
|
let x = param_one + param_two;
|
||||||
|
println!("{} + {} = {}", param_one, param_two, x);
|
||||||
|
let y = param_two + param_one;
|
||||||
|
println!("{} + {} = {}", param_two, param_one, y);
|
||||||
|
println!("{} + {} = {}", x, y, x + y);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue