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
|
@ -1972,14 +1972,13 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
|||
UnstableFeatures::Allow => f.constness,
|
||||
_ => hir::Constness::NotConst
|
||||
};
|
||||
let prefix = format!("{}{}{}{:#}fn {}{:#}",
|
||||
let indent = format!("{}{}{}{:#}fn {}{:#}",
|
||||
VisSpace(&it.visibility),
|
||||
ConstnessSpace(vis_constness),
|
||||
UnsafetySpace(f.unsafety),
|
||||
AbiSpace(f.abi),
|
||||
it.name.as_ref().unwrap(),
|
||||
f.generics);
|
||||
let indent = repeat(" ").take(prefix.len()).collect::<String>();
|
||||
f.generics).len();
|
||||
write!(w, "<pre class='rust fn'>{vis}{constness}{unsafety}{abi}fn \
|
||||
{name}{generics}{decl}{where_clause}</pre>",
|
||||
vis = VisSpace(&it.visibility),
|
||||
|
@ -1988,22 +1987,29 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
|||
abi = AbiSpace(f.abi),
|
||||
name = it.name.as_ref().unwrap(),
|
||||
generics = f.generics,
|
||||
where_clause = WhereClause(&f.generics),
|
||||
decl = Method(&f.decl, &indent))?;
|
||||
where_clause = WhereClause(&f.generics, 2),
|
||||
decl = Method(&f.decl, indent))?;
|
||||
document(w, cx, it)
|
||||
}
|
||||
|
||||
fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
t: &clean::Trait) -> fmt::Result {
|
||||
let mut bounds = String::new();
|
||||
let mut bounds_plain = String::new();
|
||||
if !t.bounds.is_empty() {
|
||||
if !bounds.is_empty() {
|
||||
bounds.push(' ');
|
||||
bounds_plain.push(' ');
|
||||
}
|
||||
bounds.push_str(": ");
|
||||
bounds_plain.push_str(": ");
|
||||
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_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(),
|
||||
t.generics,
|
||||
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 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")?;
|
||||
for t in &types {
|
||||
write!(w, " ")?;
|
||||
render_assoc_item(w, t, AssocItemLink::Anchor(None))?;
|
||||
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||
write!(w, ";\n")?;
|
||||
}
|
||||
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 {
|
||||
write!(w, " ")?;
|
||||
render_assoc_item(w, t, AssocItemLink::Anchor(None))?;
|
||||
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||
write!(w, ";\n")?;
|
||||
}
|
||||
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 {
|
||||
write!(w, " ")?;
|
||||
render_assoc_item(w, m, AssocItemLink::Anchor(None))?;
|
||||
render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?;
|
||||
write!(w, ";\n")?;
|
||||
}
|
||||
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 {
|
||||
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, "}}")?;
|
||||
|
@ -2073,7 +2080,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
|||
id = id,
|
||||
stab = m.stability_class(),
|
||||
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>")?;
|
||||
render_stability_since(w, m, t)?;
|
||||
write!(w, "</span></h3>")?;
|
||||
|
@ -2227,7 +2234,8 @@ fn render_stability_since(w: &mut fmt::Formatter,
|
|||
|
||||
fn render_assoc_item(w: &mut fmt::Formatter,
|
||||
item: &clean::Item,
|
||||
link: AssocItemLink) -> fmt::Result {
|
||||
link: AssocItemLink,
|
||||
parent: ItemType) -> fmt::Result {
|
||||
fn method(w: &mut fmt::Formatter,
|
||||
meth: &clean::Item,
|
||||
unsafety: hir::Unsafety,
|
||||
|
@ -2235,7 +2243,8 @@ fn render_assoc_item(w: &mut fmt::Formatter,
|
|||
abi: abi::Abi,
|
||||
g: &clean::Generics,
|
||||
d: &clean::FnDecl,
|
||||
link: AssocItemLink)
|
||||
link: AssocItemLink,
|
||||
parent: ItemType)
|
||||
-> fmt::Result {
|
||||
let name = meth.name.as_ref().unwrap();
|
||||
let anchor = format!("#{}.{}", meth.type_(), name);
|
||||
|
@ -2265,7 +2274,16 @@ fn render_assoc_item(w: &mut fmt::Formatter,
|
|||
AbiSpace(abi),
|
||||
name,
|
||||
*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>\
|
||||
{generics}{decl}{where_clause}",
|
||||
ConstnessSpace(vis_constness),
|
||||
|
@ -2274,19 +2292,18 @@ fn render_assoc_item(w: &mut fmt::Formatter,
|
|||
href = href,
|
||||
name = name,
|
||||
generics = *g,
|
||||
decl = Method(d, &indent),
|
||||
where_clause = WhereClause(g))
|
||||
decl = Method(d, indent),
|
||||
where_clause = WhereClause(g, where_indent))
|
||||
}
|
||||
match item.inner {
|
||||
clean::StrippedItem(..) => Ok(()),
|
||||
clean::TyMethodItem(ref m) => {
|
||||
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) => {
|
||||
method(w, item, m.unsafety, m.constness,
|
||||
m.abi, &m.generics, &m.decl,
|
||||
link)
|
||||
m.abi, &m.generics, &m.decl, link, parent)
|
||||
}
|
||||
clean::AssociatedConstItem(ref ty, ref default) => {
|
||||
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 {
|
||||
write!(w, "<pre class='rust enum'>")?;
|
||||
render_attributes(w, it)?;
|
||||
let padding = format!("{}enum {}{:#} ",
|
||||
VisSpace(&it.visibility),
|
||||
it.name.as_ref().unwrap(),
|
||||
e.generics).len();
|
||||
write!(w, "{}enum {}{}{}",
|
||||
VisSpace(&it.visibility),
|
||||
it.name.as_ref().unwrap(),
|
||||
e.generics,
|
||||
WhereClause(&e.generics))?;
|
||||
WhereClause(&e.generics, padding))?;
|
||||
if e.variants.is_empty() && !e.variants_stripped {
|
||||
write!(w, " {{}}")?;
|
||||
} else {
|
||||
|
@ -2559,17 +2580,23 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
|||
fields: &[clean::Item],
|
||||
tab: &str,
|
||||
structhead: bool) -> fmt::Result {
|
||||
let mut plain = String::new();
|
||||
write!(w, "{}{}{}",
|
||||
VisSpace(&it.visibility),
|
||||
if structhead {"struct "} else {""},
|
||||
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 {
|
||||
plain.push_str(&format!("{:#}", g));
|
||||
write!(w, "{}", g)?
|
||||
}
|
||||
match ty {
|
||||
doctree::Plain => {
|
||||
if let Some(g) = g {
|
||||
write!(w, "{}", WhereClause(g))?
|
||||
write!(w, "{}", WhereClause(g, plain.len() + 1))?
|
||||
}
|
||||
let mut has_visible_fields = false;
|
||||
write!(w, " {{")?;
|
||||
|
@ -2598,30 +2625,35 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
|||
}
|
||||
doctree::Tuple => {
|
||||
write!(w, "(")?;
|
||||
plain.push_str("(");
|
||||
for (i, field) in fields.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(w, ", ")?;
|
||||
plain.push_str(", ");
|
||||
}
|
||||
match field.inner {
|
||||
clean::StrippedItem(box clean::StructFieldItem(..)) => {
|
||||
plain.push_str("_");
|
||||
write!(w, "_")?
|
||||
}
|
||||
clean::StructFieldItem(ref ty) => {
|
||||
plain.push_str(&format!("{}{:#}", VisSpace(&field.visibility), *ty));
|
||||
write!(w, "{}{}", VisSpace(&field.visibility), *ty)?
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
write!(w, ")")?;
|
||||
plain.push_str(")");
|
||||
if let Some(g) = g {
|
||||
write!(w, "{}", WhereClause(g))?
|
||||
write!(w, "{}", WhereClause(g, plain.len() + 1))?
|
||||
}
|
||||
write!(w, ";")?;
|
||||
}
|
||||
doctree::Unit => {
|
||||
// Needed for PhantomData.
|
||||
if let Some(g) = g {
|
||||
write!(w, "{}", WhereClause(g))?
|
||||
write!(w, "{}", WhereClause(g, plain.len() + 1))?
|
||||
}
|
||||
write!(w, ";")?;
|
||||
}
|
||||
|
@ -2634,13 +2666,19 @@ fn render_union(w: &mut fmt::Formatter, it: &clean::Item,
|
|||
fields: &[clean::Item],
|
||||
tab: &str,
|
||||
structhead: bool) -> fmt::Result {
|
||||
let mut plain = String::new();
|
||||
write!(w, "{}{}{}",
|
||||
VisSpace(&it.visibility),
|
||||
if structhead {"union "} else {""},
|
||||
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 {
|
||||
write!(w, "{}", g)?;
|
||||
write!(w, "{}", WhereClause(g))?;
|
||||
plain.push_str(&format!("{:#}", g));
|
||||
write!(w, "{}", WhereClause(g, plain.len() + 1))?;
|
||||
}
|
||||
|
||||
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, "<span id='{}' class='invisible'>", ns_id)?;
|
||||
write!(w, "<code>")?;
|
||||
render_assoc_item(w, item, link.anchor(&id))?;
|
||||
render_assoc_item(w, item, link.anchor(&id), ItemType::Impl)?;
|
||||
write!(w, "</code>")?;
|
||||
render_stability_since_raw(w, item.stable_since(), outer_version)?;
|
||||
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,
|
||||
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>",
|
||||
it.name.as_ref().unwrap(),
|
||||
t.generics,
|
||||
where_clause = WhereClause(&t.generics),
|
||||
where_clause = WhereClause(&t.generics, indent),
|
||||
type_ = t.type_)?;
|
||||
|
||||
document(w, cx, it)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue