From 4a6921e10e6134212867df96a8035576759e9d4b Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 13 Oct 2016 10:17:25 -0500 Subject: [PATCH 1/6] rustdoc: add line breaks to where clauses a la rustfmt --- src/librustdoc/html/format.rs | 34 ++++++++++++++++++++++----------- src/test/rustdoc/line-breaks.rs | 19 ++++++++++++++++++ 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 625acce27bd64..092e1548446e3 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -161,48 +161,60 @@ impl<'a> fmt::Display for WhereClause<'a> { if gens.where_predicates.is_empty() { return Ok(()); } + let mut clause = String::new(); if f.alternate() { - f.write_str(" ")?; + clause.push_str(" where "); } else { - f.write_str(" where ")?; + clause.push_str(" where "); } for (i, pred) in gens.where_predicates.iter().enumerate() { if i > 0 { - f.write_str(", ")?; + if f.alternate() { + clause.push_str(", "); + } else { + clause.push_str(",
"); + } } match pred { &clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => { let bounds = bounds; if f.alternate() { - write!(f, "{:#}: {:#}", ty, TyParamBounds(bounds))?; + clause.push_str(&format!("{:#}: {:#}", ty, TyParamBounds(bounds))); } else { - write!(f, "{}: {}", ty, TyParamBounds(bounds))?; + clause.push_str(&format!("{}: {}", ty, TyParamBounds(bounds))); } } &clean::WherePredicate::RegionPredicate { ref lifetime, ref bounds } => { - write!(f, "{}: ", lifetime)?; + clause.push_str(&format!("{}: ", lifetime)); for (i, lifetime) in bounds.iter().enumerate() { if i > 0 { - f.write_str(" + ")?; + clause.push_str(" + "); } - write!(f, "{}", lifetime)?; + clause.push_str(&format!("{}", lifetime)); } } &clean::WherePredicate::EqPredicate { ref lhs, ref rhs } => { if f.alternate() { - write!(f, "{:#} == {:#}", lhs, rhs)?; + clause.push_str(&format!("{:#} == {:#}", lhs, rhs)); } else { - write!(f, "{} == {}", lhs, rhs)?; + clause.push_str(&format!("{} == {}", lhs, rhs)); } } } } if !f.alternate() { f.write_str("
")?; + let plain = format!("{:#}", self); + if plain.len() > 80 { + let padding = repeat(" ").take(8).collect::(); + clause = clause.replace("
", &format!("
{}", padding)); + } else { + clause = clause.replace("
", " "); + } } - Ok(()) + write!(f, "{}", clause) } } diff --git a/src/test/rustdoc/line-breaks.rs b/src/test/rustdoc/line-breaks.rs index cc608a2447574..a1eabb515a5ce 100644 --- a/src/test/rustdoc/line-breaks.rs +++ b/src/test/rustdoc/line-breaks.rs @@ -10,6 +10,9 @@ #![crate_name = "foo"] +use std::ops::Add; +use std::fmt::Display; + //@count foo/fn.function_with_a_really_long_name.html //pre/br 2 pub fn function_with_a_really_long_name(parameter_one: 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 pub fn short_name(param: i32) -> i32 { param + 1 } + +//@count foo/fn.where_clause.html //pre/br 4 +pub fn where_clause(param_one: T, + param_two: U) + where T: Add + Display + Copy, + U: Add + Display + Copy, + T::Output: Display + Add + Copy, + >::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); +} From c6ab68528a468aab1c501f9572926ca64dbdaced Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 13 Oct 2016 13:58:04 -0500 Subject: [PATCH 2/6] fix spurious
appearing before the opening tag --- src/librustdoc/html/format.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 092e1548446e3..6d96b172a2e61 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -205,7 +205,7 @@ impl<'a> fmt::Display for WhereClause<'a> { } } if !f.alternate() { - f.write_str("")?; + clause.push_str(""); let plain = format!("{:#}", self); if plain.len() > 80 { let padding = repeat(" ").take(8).collect::(); From 42f28d31bf68abc03141d62054625c50d002c872 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Sat, 15 Oct 2016 09:46:43 -0500 Subject: [PATCH 3/6] rustdoc: apply proper indent when where clauses aren't on their own line --- src/librustdoc/html/format.rs | 34 ++++++++++--- src/librustdoc/html/render.rs | 92 ++++++++++++++++++++++++++--------- 2 files changed, 96 insertions(+), 30 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6d96b172a2e61..3b2f2430993a1 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -50,7 +50,7 @@ pub struct MutableSpace(pub clean::Mutability); #[derive(Copy, Clone)] pub struct RawMutableSpace(pub clean::Mutability); /// 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 String); /// Wrapper struct for emitting type parameter bounds. pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]); /// Wrapper struct for emitting a comma-separated list of items @@ -157,7 +157,7 @@ impl fmt::Display for clean::Generics { impl<'a> fmt::Display for WhereClause<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let &WhereClause(gens) = self; + let &WhereClause(gens, ref pad) = self; if gens.where_predicates.is_empty() { return Ok(()); } @@ -207,8 +207,8 @@ impl<'a> fmt::Display for WhereClause<'a> { if !f.alternate() { clause.push_str(""); let plain = format!("{:#}", self); - if plain.len() > 80 { - let padding = repeat(" ").take(8).collect::(); + if plain.len() + pad.len() > 80 { + let padding = repeat(" ").take(pad.len() + 6).collect::(); clause = clause.replace("
", &format!("
{}", padding)); } else { clause = clause.replace("
", " "); @@ -730,30 +730,44 @@ impl fmt::Display for clean::Type { } fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool) -> fmt::Result { + let mut plain = String::new(); + if f.alternate() { write!(f, "impl{:#} ", i.generics)?; } else { write!(f, "impl{} ", i.generics)?; } + plain.push_str(&format!("impl{:#} ", i.generics)); + if let Some(ref ty) = i.trait_ { - write!(f, "{}", - if i.polarity == Some(clean::ImplPolarity::Negative) { "!" } else { "" })?; + if i.polarity == Some(clean::ImplPolarity::Negative) { + write!(f, "!")?; + plain.push_str("!"); + } + if link_trait { fmt::Display::fmt(ty, f)?; + plain.push_str(&format!("{:#}", ty)); } else { match *ty { 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)?; + plain.push_str(&format!("{:#}{:#}", last.name, last.params)); } _ => unreachable!(), } } write!(f, " for ")?; + plain.push_str(" for "); } + fmt::Display::fmt(&i.for_, f)?; - fmt::Display::fmt(&WhereClause(&i.generics), f)?; + plain.push_str(&format!("{:#}", i.for_)); + + let pad = repeat(" ").take(plain.len() + 1).collect::(); + fmt::Display::fmt(&WhereClause(&i.generics, pad), f)?; Ok(()) } @@ -899,7 +913,11 @@ impl<'a> fmt::Display for Method<'a> { } else { output = output.replace("
", ""); } - write!(f, "{}", output) + if f.alternate() { + write!(f, "{}", output.replace("
", "\n")) + } else { + write!(f, "{}", output) + } } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d8dba00e7d578..067cffc877934 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1983,7 +1983,7 @@ 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), + where_clause = WhereClause(&f.generics, " ".to_string()), decl = Method(&f.decl, &indent))?; document(w, cx, it) } @@ -1991,17 +1991,27 @@ fn item_function(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 { 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)); } } + // Where clauses in traits are indented nine spaces, per rustdoc.css + let indent = " ".to_string(); + // Output the trait definition write!(w, "
{}{}trait {}{}{}{} ",
            VisSpace(&it.visibility),
@@ -2009,7 +2019,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
            it.name.as_ref().unwrap(),
            t.generics,
            bounds,
-           WhereClause(&t.generics))?;
+           WhereClause(&t.generics, indent))?;
 
     let types = t.items.iter().filter(|m| m.is_associated_type()).collect::>();
     let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>();
@@ -2023,7 +2033,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() {
@@ -2031,7 +2041,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() {
@@ -2039,7 +2049,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() {
@@ -2047,7 +2057,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, "}}")?;
@@ -2068,7 +2078,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, "")?;
         render_stability_since(w, m, t)?;
         write!(w, "")?;
@@ -2222,7 +2232,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,
@@ -2230,7 +2241,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);
@@ -2260,7 +2272,17 @@ fn render_assoc_item(w: &mut fmt::Formatter,
                              AbiSpace(abi),
                              name,
                              *g);
-        let indent = repeat(" ").take(prefix.len()).collect::();
+        let mut indent = repeat(" ").take(prefix.len()).collect::();
+        let where_indent = if parent == ItemType::Trait {
+            indent += "    ";
+            "        ".to_string()
+        } else if parent == ItemType::Impl {
+            "  ".to_string()
+        } else {
+            let prefix = prefix + &format!("{:#}", Method(d, &indent));
+            let prefix = prefix.lines().last().unwrap();
+            repeat(" ").take(prefix.len() + 1).collect::()
+        };
         write!(w, "{}{}{}fn {name}\
                    {generics}{decl}{where_clause}",
                ConstnessSpace(vis_constness),
@@ -2270,18 +2292,17 @@ fn render_assoc_item(w: &mut fmt::Formatter,
                name = name,
                generics = *g,
                decl = Method(d, &indent),
-               where_clause = WhereClause(g))
+               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)
@@ -2378,11 +2399,15 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
              e: &clean::Enum) -> fmt::Result {
     write!(w, "
")?;
     render_attributes(w, it)?;
+    let padding = format!("{}enum {}{:#} ",
+                          VisSpace(&it.visibility),
+                          it.name.as_ref().unwrap(),
+                          e.generics);
     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 {
@@ -2517,17 +2542,24 @@ 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))?
+                let pad = repeat(" ").take(plain.len() + 1).collect::();
+                write!(w, "{}", WhereClause(g, pad))?
             }
             let mut has_visible_fields = false;
             write!(w, " {{")?;
@@ -2556,30 +2588,37 @@ 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))?
+                let pad = repeat(" ").take(plain.len() + 1).collect::();
+                write!(w, "{}", WhereClause(g, pad))?
             }
             write!(w, ";")?;
         }
         doctree::Unit => {
             // Needed for PhantomData.
             if let Some(g) = g {
-                write!(w, "{}", WhereClause(g))?
+                let pad = repeat(" ").take(plain.len() + 1).collect::();
+                write!(w, "{}", WhereClause(g, pad))?
             }
             write!(w, ";")?;
         }
@@ -2592,13 +2631,20 @@ 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));
+        let pad = repeat(" ").take(plain.len() + 1).collect::();
+        write!(w, "{}", WhereClause(g, pad))?;
     }
 
     write!(w, " {{\n{}", tab)?;
@@ -2789,7 +2835,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
                     write!(w, "

", id, item_type)?; write!(w, "

\n")?; @@ -2899,10 +2945,12 @@ 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); + let indent = repeat(" ").take(indent.len()).collect::(); write!(w, "
type {}{}{where_clause} = {type_};
", 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) From 07b27bb34c4ce32152369d202cac7a4e0c9878af Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Sat, 15 Oct 2016 10:29:47 -0500 Subject: [PATCH 4/6] rustdoc: break where clauses onto their own line if they don't have enough room --- src/librustdoc/html/format.rs | 7 ++++++- src/librustdoc/html/static/rustdoc.css | 12 ++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 3b2f2430993a1..5fb99a2031fb5 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -208,7 +208,12 @@ impl<'a> fmt::Display for WhereClause<'a> { clause.push_str(""); let plain = format!("{:#}", self); if plain.len() + pad.len() > 80 { - let padding = repeat(" ").take(pad.len() + 6).collect::(); + let padding = if pad.len() + 25 > 80 { + clause = clause.replace("class='where'", "class='where fmt-newline'"); + repeat(" ").take(8).collect::() + } else { + repeat(" ").take(pad.len() + 6).collect::() + }; clause = clause.replace("
", &format!("
{}", padding)); } else { clause = clause.replace("
", " "); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index f8133ea49ceba..3b6ffa4a462f6 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -361,9 +361,17 @@ h4 > code, h3 > code, .invisible > code { position: relative; } /* 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 */ -.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; } From 43abad45837a15c62828b700aff7efd8eee76cfd Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Sat, 15 Oct 2016 21:52:18 -0500 Subject: [PATCH 5/6] rustdoc: if a where clause gets any lines, it gets its own line --- src/librustdoc/html/format.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 5fb99a2031fb5..c4a4817195b65 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -208,7 +208,9 @@ impl<'a> fmt::Display for WhereClause<'a> { clause.push_str(""); let plain = format!("{:#}", self); if plain.len() + pad.len() > 80 { - let padding = if pad.len() + 25 > 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.len() > 10 { clause = clause.replace("class='where'", "class='where fmt-newline'"); repeat(" ").take(8).collect::() } else { From 61cc8700dfcecde9e7de132356f3c32eb01b147e Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 17 Oct 2016 09:55:18 -0500 Subject: [PATCH 6/6] rustdoc: make Method/WhereClause wrappers use usize for indents --- src/librustdoc/html/format.rs | 25 ++++++++++--------- src/librustdoc/html/render.rs | 47 ++++++++++++++--------------------- 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index c4a4817195b65..eef530081abe3 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -42,7 +42,7 @@ pub struct UnsafetySpace(pub hir::Unsafety); #[derive(Copy, Clone)] pub struct ConstnessSpace(pub hir::Constness); /// 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 #[derive(Copy, Clone)] pub struct MutableSpace(pub clean::Mutability); @@ -50,7 +50,7 @@ pub struct MutableSpace(pub clean::Mutability); #[derive(Copy, Clone)] pub struct RawMutableSpace(pub clean::Mutability); /// Wrapper struct for emitting a where clause from Generics. -pub struct WhereClause<'a>(pub &'a clean::Generics, pub String); +pub struct WhereClause<'a>(pub &'a clean::Generics, pub usize); /// Wrapper struct for emitting type parameter bounds. pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]); /// Wrapper struct for emitting a comma-separated list of items @@ -157,7 +157,7 @@ impl fmt::Display for clean::Generics { impl<'a> fmt::Display for WhereClause<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let &WhereClause(gens, ref pad) = self; + let &WhereClause(gens, pad) = self; if gens.where_predicates.is_empty() { return Ok(()); } @@ -207,14 +207,14 @@ impl<'a> fmt::Display for WhereClause<'a> { if !f.alternate() { clause.push_str(""); let plain = format!("{:#}", self); - if plain.len() + pad.len() > 80 { + 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.len() > 10 { + let padding = if pad > 10 { clause = clause.replace("class='where'", "class='where fmt-newline'"); repeat(" ").take(8).collect::() } else { - repeat(" ").take(pad.len() + 6).collect::() + repeat(" ").take(pad + 6).collect::() }; clause = clause.replace("
", &format!("
{}", padding)); } else { @@ -773,8 +773,7 @@ fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool) -> fmt::R fmt::Display::fmt(&i.for_, f)?; plain.push_str(&format!("{:#}", i.for_)); - let pad = repeat(" ").take(plain.len() + 1).collect::(); - fmt::Display::fmt(&WhereClause(&i.generics, pad), f)?; + fmt::Display::fmt(&WhereClause(&i.generics, plain.len() + 1), f)?; Ok(()) } @@ -903,19 +902,21 @@ impl<'a> fmt::Display for Method<'a> { let mut output: String; let plain: String; + let pad = repeat(" ").take(indent).collect::(); if arrow.is_empty() { output = format!("({})", args); - plain = format!("{}({})", indent.replace(" ", " "), args_plain); + plain = format!("{}({})", pad, args_plain); } else { output = format!("({args})
{arrow}", args = args, arrow = arrow); - plain = format!("{indent}({args}){arrow}", - indent = indent.replace(" ", " "), + plain = format!("{pad}({args}){arrow}", + pad = pad, args = args_plain, arrow = arrow_plain); } if plain.len() > 80 { - let pad = format!("
{}", indent); + let pad = repeat(" ").take(indent).collect::(); + let pad = format!("
{}", pad); output = output.replace("
", &pad); } else { output = output.replace("
", ""); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 067cffc877934..c0a1abd4aec3f 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1967,14 +1967,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::(); + f.generics).len(); write!(w, "
{vis}{constness}{unsafety}{abi}fn \
                {name}{generics}{decl}{where_clause}
", vis = VisSpace(&it.visibility), @@ -1983,8 +1982,8 @@ 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, " ".to_string()), - decl = Method(&f.decl, &indent))?; + where_clause = WhereClause(&f.generics, 2), + decl = Method(&f.decl, indent))?; document(w, cx, it) } @@ -2009,9 +2008,6 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } } - // Where clauses in traits are indented nine spaces, per rustdoc.css - let indent = " ".to_string(); - // Output the trait definition write!(w, "
{}{}trait {}{}{}{} ",
            VisSpace(&it.visibility),
@@ -2019,7 +2015,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
            it.name.as_ref().unwrap(),
            t.generics,
            bounds,
-           WhereClause(&t.generics, indent))?;
+           // 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::>();
     let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>();
@@ -2272,16 +2269,15 @@ fn render_assoc_item(w: &mut fmt::Formatter,
                              AbiSpace(abi),
                              name,
                              *g);
-        let mut indent = repeat(" ").take(prefix.len()).collect::();
+        let mut indent = prefix.len();
         let where_indent = if parent == ItemType::Trait {
-            indent += "    ";
-            "        ".to_string()
+            indent += 4;
+            8
         } else if parent == ItemType::Impl {
-            "  ".to_string()
+            2
         } else {
-            let prefix = prefix + &format!("{:#}", Method(d, &indent));
-            let prefix = prefix.lines().last().unwrap();
-            repeat(" ").take(prefix.len() + 1).collect::()
+            let prefix = prefix + &format!("{:#}", Method(d, indent));
+            prefix.lines().last().unwrap().len() + 1
         };
         write!(w, "{}{}{}fn {name}\
                    {generics}{decl}{where_clause}",
@@ -2291,7 +2287,7 @@ fn render_assoc_item(w: &mut fmt::Formatter,
                href = href,
                name = name,
                generics = *g,
-               decl = Method(d, &indent),
+               decl = Method(d, indent),
                where_clause = WhereClause(g, where_indent))
     }
     match item.inner {
@@ -2402,7 +2398,7 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     let padding = format!("{}enum {}{:#} ",
                           VisSpace(&it.visibility),
                           it.name.as_ref().unwrap(),
-                          e.generics);
+                          e.generics).len();
     write!(w, "{}enum {}{}{}",
            VisSpace(&it.visibility),
            it.name.as_ref().unwrap(),
@@ -2558,8 +2554,7 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
     match ty {
         doctree::Plain => {
             if let Some(g) = g {
-                let pad = repeat(" ").take(plain.len() + 1).collect::();
-                write!(w, "{}", WhereClause(g, pad))?
+                write!(w, "{}", WhereClause(g, plain.len() + 1))?
             }
             let mut has_visible_fields = false;
             write!(w, " {{")?;
@@ -2609,16 +2604,14 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
             write!(w, ")")?;
             plain.push_str(")");
             if let Some(g) = g {
-                let pad = repeat(" ").take(plain.len() + 1).collect::();
-                write!(w, "{}", WhereClause(g, pad))?
+                write!(w, "{}", WhereClause(g, plain.len() + 1))?
             }
             write!(w, ";")?;
         }
         doctree::Unit => {
             // Needed for PhantomData.
             if let Some(g) = g {
-                let pad = repeat(" ").take(plain.len() + 1).collect::();
-                write!(w, "{}", WhereClause(g, pad))?
+                write!(w, "{}", WhereClause(g, plain.len() + 1))?
             }
             write!(w, ";")?;
         }
@@ -2643,8 +2636,7 @@ fn render_union(w: &mut fmt::Formatter, it: &clean::Item,
     if let Some(g) = g {
         write!(w, "{}", g)?;
         plain.push_str(&format!("{:#}", g));
-        let pad = repeat(" ").take(plain.len() + 1).collect::();
-        write!(w, "{}", WhereClause(g, pad))?;
+        write!(w, "{}", WhereClause(g, plain.len() + 1))?;
     }
 
     write!(w, " {{\n{}", tab)?;
@@ -2945,8 +2937,7 @@ 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);
-    let indent = repeat(" ").take(indent.len()).collect::();
+    let indent = format!("type {}{:#} ", it.name.as_ref().unwrap(), t.generics).len();
     write!(w, "
type {}{}{where_clause} = {type_};
", it.name.as_ref().unwrap(), t.generics,