about summary refs log tree commit diff
path: root/src/librustdoc
diff options
context:
space:
mode:
authorMark Rousskov <mark.simulacrum@gmail.com>2019-09-12 19:59:14 -0400
committerMark Rousskov <mark.simulacrum@gmail.com>2019-09-13 19:44:44 -0400
commit04b27efa00799f984b7ebc50d37a2d571db9235f (patch)
treeeb42c95dc90fa5c493905e8cce5b28742ab2ad09 /src/librustdoc
parenteb48d6bdee6c655d71f26594d47d232adf3e4e93 (diff)
Move to print functions on types instead of impl fmt::Display
This will eventually allow us to easily pass in more parameters to the
functions without TLS or other such hacks
Diffstat (limited to 'src/librustdoc')
-rw-r--r--src/librustdoc/clean/mod.rs14
-rw-r--r--src/librustdoc/html/format.rs881
-rw-r--r--src/librustdoc/html/item_type.rs39
-rw-r--r--src/librustdoc/html/render.rs127
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs7
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/librustdoc/passes/mod.rs4
-rw-r--r--src/librustdoc/passes/strip_hidden.rs2
8 files changed, 553 insertions, 523 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ae70fdc530b..10c4231b82e 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1849,7 +1849,7 @@ fn get_real_types(
     cx: &DocContext<'_>,
     recurse: i32,
 ) -> FxHashSet<Type> {
-    let arg_s = arg.to_string();
+    let arg_s = arg.print().to_string();
     let mut res = FxHashSet::default();
     if recurse >= 10 { // FIXME: remove this whole recurse thing when the recursion bug is fixed
         return res;
@@ -3573,16 +3573,6 @@ pub enum GenericArg {
     Const(Constant),
 }
 
-impl fmt::Display for GenericArg {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            GenericArg::Lifetime(lt) => lt.fmt(f),
-            GenericArg::Type(ty) => ty.fmt(f),
-            GenericArg::Const(ct) => ct.fmt(f),
-        }
-    }
-}
-
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum GenericArgs {
     AngleBracketed {
@@ -4274,7 +4264,7 @@ fn resolve_type(cx: &DocContext<'_>,
             return Generic(kw::SelfUpper.to_string());
         }
         Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
-            return Generic(format!("{:#}", path));
+            return Generic(format!("{:#}", path.print()));
         }
         Res::SelfTy(..)
         | Res::Def(DefKind::TyParam, _)
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index dcd32192ff3..9baa69d981b 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -99,10 +99,6 @@ impl Buffer {
         self.into_inner()
     }
 
-    crate fn with_formatter<T: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result>(&mut self, t: T) {
-        self.from_display(display_fn(move |f| (t)(f)));
-    }
-
     crate fn from_display<T: std::fmt::Display>(&mut self, t: T) {
         if self.for_html {
             write!(self, "{}", t);
@@ -131,8 +127,6 @@ pub struct AsyncSpace(pub hir::IsAsync);
 /// Similar to VisSpace, but used for mutability
 #[derive(Copy, Clone)]
 pub struct MutableSpace(pub clean::Mutability);
-/// Wrapper struct for emitting type parameter bounds.
-pub struct GenericBounds<'a>(pub &'a [clean::GenericBound]);
 pub struct AbiSpace(pub Abi);
 pub struct DefaultSpace(pub bool);
 
@@ -161,102 +155,89 @@ pub struct WhereClause<'a>{
     pub end_newline: bool,
 }
 
-impl<'a> VisSpace<'a> {
-    pub fn get(self) -> &'a Option<clean::Visibility> {
-        let VisSpace(v) = self; v
-    }
-}
-
-impl UnsafetySpace {
-    pub fn get(&self) -> hir::Unsafety {
-        let UnsafetySpace(v) = *self; v
-    }
-}
-
-impl ConstnessSpace {
-    pub fn get(&self) -> hir::Constness {
-        let ConstnessSpace(v) = *self; v
-    }
-}
-
-fn comma_sep<T: fmt::Display>(items: &[T]) -> impl fmt::Display + '_ {
+fn comma_sep<T: fmt::Display>(items: impl Iterator<Item=T>) -> impl fmt::Display {
     display_fn(move |f| {
-        for (i, item) in items.iter().enumerate() {
+        for (i, item) in items.enumerate() {
             if i != 0 { write!(f, ", ")?; }
-            fmt::Display::fmt(item, f)?;
+            fmt::Display::fmt(&item, f)?;
         }
         Ok(())
     })
 }
 
-impl<'a> fmt::Display for GenericBounds<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+crate fn print_generic_bounds(bounds: &[clean::GenericBound]) -> impl fmt::Display + '_ {
+    display_fn(move |f| {
         let mut bounds_dup = FxHashSet::default();
-        let &GenericBounds(bounds) = self;
 
-        for (i, bound) in bounds.iter().filter(|b| bounds_dup.insert(b.to_string())).enumerate() {
+        for (i, bound) in bounds.iter().filter(|b| {
+            bounds_dup.insert(b.print().to_string())
+        }).enumerate() {
             if i > 0 {
                 f.write_str(" + ")?;
             }
-            fmt::Display::fmt(bound, f)?;
+            fmt::Display::fmt(&bound.print(), f)?;
         }
         Ok(())
-    }
+    })
 }
 
-impl fmt::Display for clean::GenericParamDef {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.kind {
-            clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name),
-            clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => {
-                f.write_str(&self.name)?;
+impl clean::GenericParamDef {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            match self.kind {
+                clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name),
+                clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => {
+                    f.write_str(&self.name)?;
 
-                if !bounds.is_empty() {
-                    if f.alternate() {
-                        write!(f, ": {:#}", GenericBounds(bounds))?;
-                    } else {
-                        write!(f, ":&nbsp;{}", GenericBounds(bounds))?;
+                    if !bounds.is_empty() {
+                        if f.alternate() {
+                            write!(f, ": {:#}", print_generic_bounds(bounds))?;
+                        } else {
+                            write!(f, ":&nbsp;{}", print_generic_bounds(bounds))?;
+                        }
+                    }
+
+                    if let Some(ref ty) = default {
+                        if f.alternate() {
+                            write!(f, " = {:#}", ty.print())?;
+                        } else {
+                            write!(f, "&nbsp;=&nbsp;{}", ty.print())?;
+                        }
                     }
+
+                    Ok(())
                 }
+                clean::GenericParamDefKind::Const { ref ty, .. } => {
+                    f.write_str("const ")?;
+                    f.write_str(&self.name)?;
 
-                if let Some(ref ty) = default {
                     if f.alternate() {
-                        write!(f, " = {:#}", ty)?;
+                        write!(f, ": {:#}", ty.print())
                     } else {
-                        write!(f, "&nbsp;=&nbsp;{}", ty)?;
+                        write!(f, ":&nbsp;{}", ty.print())
                     }
                 }
-
-                Ok(())
-            }
-            clean::GenericParamDefKind::Const { ref ty, .. } => {
-                f.write_str("const ")?;
-                f.write_str(&self.name)?;
-
-                if f.alternate() {
-                    write!(f, ": {:#}", ty)
-                } else {
-                    write!(f, ":&nbsp;{}", ty)
-                }
             }
-        }
+        })
     }
 }
 
-impl fmt::Display for clean::Generics {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let real_params = self.params
-            .iter()
-            .filter(|p| !p.is_synthetic_type_param())
-            .collect::<Vec<_>>();
-        if real_params.is_empty() {
-            return Ok(());
-        }
-        if f.alternate() {
-            write!(f, "<{:#}>", comma_sep(&real_params))
-        } else {
-            write!(f, "&lt;{}&gt;", comma_sep(&real_params))
-        }
+impl clean::Generics {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            let real_params = self.params
+                .iter()
+                .filter(|p| !p.is_synthetic_type_param())
+                .collect::<Vec<_>>();
+            if real_params.is_empty() {
+                return Ok(());
+            }
+            if f.alternate() {
+                write!(f, "<{:#}>", comma_sep(real_params.iter().map(|g| g.print())))
+            } else {
+                write!(f, "&lt;{}&gt;", comma_sep(real_params.iter().map(|g| g.print())))
+            }
+        })
     }
 }
 
@@ -287,24 +268,26 @@ impl<'a> fmt::Display for WhereClause<'a> {
                 &clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => {
                     let bounds = bounds;
                     if f.alternate() {
-                        clause.push_str(&format!("{:#}: {:#}", ty, GenericBounds(bounds)));
+                        clause.push_str(&format!("{:#}: {:#}",
+                                ty.print(), print_generic_bounds(bounds)));
                     } else {
-                        clause.push_str(&format!("{}: {}", ty, GenericBounds(bounds)));
+                        clause.push_str(&format!("{}: {}",
+                                ty.print(), print_generic_bounds(bounds)));
                     }
                 }
                 &clean::WherePredicate::RegionPredicate { ref lifetime, ref bounds } => {
                     clause.push_str(&format!("{}: {}",
-                                                lifetime,
+                                                lifetime.print(),
                                                 bounds.iter()
-                                                    .map(|b| b.to_string())
+                                                    .map(|b| b.print().to_string())
                                                     .collect::<Vec<_>>()
                                                     .join(" + ")));
                 }
                 &clean::WherePredicate::EqPredicate { ref lhs, ref rhs } => {
                     if f.alternate() {
-                        clause.push_str(&format!("{:#} == {:#}", lhs, rhs));
+                        clause.push_str(&format!("{:#} == {:#}", lhs.print(), rhs.print()));
                     } else {
-                        clause.push_str(&format!("{} == {}", lhs, rhs));
+                        clause.push_str(&format!("{} == {}", lhs.print(), rhs.print()));
                     }
                 }
             }
@@ -336,153 +319,164 @@ impl<'a> fmt::Display for WhereClause<'a> {
     }
 }
 
-impl fmt::Display for clean::Lifetime {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.get_ref())?;
-        Ok(())
+impl clean::Lifetime {
+    crate fn print(&self) -> &str {
+        self.get_ref()
     }
 }
 
-impl fmt::Display for clean::Constant {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(&self.expr, f)
+impl clean::Constant {
+    crate fn print(&self) -> &str {
+        &self.expr
     }
 }
 
-impl fmt::Display for clean::PolyTrait {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if !self.generic_params.is_empty() {
+impl clean::PolyTrait {
+    fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            if !self.generic_params.is_empty() {
+                if f.alternate() {
+                    write!(f, "for<{:#}> ",
+                        comma_sep(self.generic_params.iter().map(|g| g.print())))?;
+                } else {
+                    write!(f, "for&lt;{}&gt; ",
+                        comma_sep(self.generic_params.iter().map(|g| g.print())))?;
+                }
+            }
             if f.alternate() {
-                write!(f, "for<{:#}> ", comma_sep(&self.generic_params))?;
+                write!(f, "{:#}", self.trait_.print())
             } else {
-                write!(f, "for&lt;{}&gt; ", comma_sep(&self.generic_params))?;
+                write!(f, "{}", self.trait_.print())
             }
-        }
-        if f.alternate() {
-            write!(f, "{:#}", self.trait_)
-        } else {
-            write!(f, "{}", self.trait_)
-        }
+        })
     }
 }
 
-impl fmt::Display for clean::GenericBound {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            clean::GenericBound::Outlives(ref lt) => {
-                write!(f, "{}", *lt)
-            }
-            clean::GenericBound::TraitBound(ref ty, modifier) => {
-                let modifier_str = match modifier {
-                    hir::TraitBoundModifier::None => "",
-                    hir::TraitBoundModifier::Maybe => "?",
-                };
-                if f.alternate() {
-                    write!(f, "{}{:#}", modifier_str, *ty)
-                } else {
-                    write!(f, "{}{}", modifier_str, *ty)
+impl clean::GenericBound {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            match self {
+                clean::GenericBound::Outlives(lt) => {
+                    write!(f, "{}", lt.print())
+                }
+                clean::GenericBound::TraitBound(ty, modifier) => {
+                    let modifier_str = match modifier {
+                        hir::TraitBoundModifier::None => "",
+                        hir::TraitBoundModifier::Maybe => "?",
+                    };
+                    if f.alternate() {
+                        write!(f, "{}{:#}", modifier_str, ty.print())
+                    } else {
+                        write!(f, "{}{}", modifier_str, ty.print())
+                    }
                 }
             }
-        }
+        })
     }
 }
 
-impl fmt::Display for clean::GenericArgs {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            clean::GenericArgs::AngleBracketed { ref args, ref bindings } => {
-                if !args.is_empty() || !bindings.is_empty() {
-                    if f.alternate() {
-                        f.write_str("<")?;
-                    } else {
-                        f.write_str("&lt;")?;
-                    }
-                    let mut comma = false;
-                    for arg in args {
-                        if comma {
-                            f.write_str(", ")?;
+impl clean::GenericArgs {
+    fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            match *self {
+                clean::GenericArgs::AngleBracketed { ref args, ref bindings } => {
+                    if !args.is_empty() || !bindings.is_empty() {
+                        if f.alternate() {
+                            f.write_str("<")?;
+                        } else {
+                            f.write_str("&lt;")?;
+                        }
+                        let mut comma = false;
+                        for arg in args {
+                            if comma {
+                                f.write_str(", ")?;
+                            }
+                            comma = true;
+                            if f.alternate() {
+                                write!(f, "{:#}", arg.print())?;
+                            } else {
+                                write!(f, "{}", arg.print())?;
+                            }
+                        }
+                        for binding in bindings {
+                            if comma {
+                                f.write_str(", ")?;
+                            }
+                            comma = true;
+                            if f.alternate() {
+                                write!(f, "{:#}", binding.print())?;
+                            } else {
+                                write!(f, "{}", binding.print())?;
+                            }
                         }
-                        comma = true;
                         if f.alternate() {
-                            write!(f, "{:#}", *arg)?;
+                            f.write_str(">")?;
                         } else {
-                            write!(f, "{}", *arg)?;
+                            f.write_str("&gt;")?;
                         }
                     }
-                    for binding in bindings {
+                }
+                clean::GenericArgs::Parenthesized { ref inputs, ref output } => {
+                    f.write_str("(")?;
+                    let mut comma = false;
+                    for ty in inputs {
                         if comma {
                             f.write_str(", ")?;
                         }
                         comma = true;
                         if f.alternate() {
-                            write!(f, "{:#}", *binding)?;
+                            write!(f, "{:#}", ty.print())?;
                         } else {
-                            write!(f, "{}", *binding)?;
+                            write!(f, "{}", ty.print())?;
                         }
                     }
-                    if f.alternate() {
-                        f.write_str(">")?;
-                    } else {
-                        f.write_str("&gt;")?;
-                    }
-                }
-            }
-            clean::GenericArgs::Parenthesized { ref inputs, ref output } => {
-                f.write_str("(")?;
-                let mut comma = false;
-                for ty in inputs {
-                    if comma {
-                        f.write_str(", ")?;
-                    }
-                    comma = true;
-                    if f.alternate() {
-                        write!(f, "{:#}", *ty)?;
-                    } else {
-                        write!(f, "{}", *ty)?;
-                    }
-                }
-                f.write_str(")")?;
-                if let Some(ref ty) = *output {
-                    if f.alternate() {
-                        write!(f, " -> {:#}", ty)?;
-                    } else {
-                        write!(f, " -&gt; {}", ty)?;
+                    f.write_str(")")?;
+                    if let Some(ref ty) = *output {
+                        if f.alternate() {
+                            write!(f, " -> {:#}", ty.print())?;
+                        } else {
+                            write!(f, " -&gt; {}", ty.print())?;
+                        }
                     }
                 }
             }
-        }
-        Ok(())
+            Ok(())
+        })
     }
 }
 
-impl fmt::Display for clean::PathSegment {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.name)?;
-        if f.alternate() {
-            write!(f, "{:#}", self.args)
-        } else {
-            write!(f, "{}", self.args)
-        }
+impl clean::PathSegment {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            f.write_str(&self.name)?;
+            if f.alternate() {
+                write!(f, "{:#}", self.args.print())
+            } else {
+                write!(f, "{}", self.args.print())
+            }
+        })
     }
 }
 
-impl fmt::Display for clean::Path {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if self.global {
-            f.write_str("::")?
-        }
-
-        for (i, seg) in self.segments.iter().enumerate() {
-            if i > 0 {
+impl clean::Path {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            if self.global {
                 f.write_str("::")?
             }
-            if f.alternate() {
-                write!(f, "{:#}", seg)?;
-            } else {
-                write!(f, "{}", seg)?;
+
+            for (i, seg) in self.segments.iter().enumerate() {
+                if i > 0 {
+                    f.write_str("::")?
+                }
+                if f.alternate() {
+                    write!(f, "{:#}", seg.print())?;
+                } else {
+                    write!(f, "{}", seg.print())?;
+                }
             }
-        }
-        Ok(())
+            Ok(())
+        })
     }
 }
 
@@ -516,7 +510,7 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
             url.push_str("/index.html");
         }
         _ => {
-            url.push_str(shortty.css_class());
+            url.push_str(shortty.as_str());
             url.push_str(".");
             url.push_str(fqp.last().unwrap());
             url.push_str(".html");
@@ -537,7 +531,7 @@ fn resolved_path(w: &mut fmt::Formatter<'_>, did: DefId, path: &clean::Path,
         }
     }
     if w.alternate() {
-        write!(w, "{}{:#}", &last.name, last.args)?;
+        write!(w, "{}{:#}", &last.name, last.args.print())?;
     } else {
         let path = if use_absolute {
             if let Some((_, _, fqp)) = href(did) {
@@ -550,7 +544,7 @@ fn resolved_path(w: &mut fmt::Formatter<'_>, did: DefId, path: &clean::Path,
         } else {
             anchor(did, &last.name).to_string()
         };
-        write!(w, "{}{}", path, last.args)?;
+        write!(w, "{}{}", path, last.args.print())?;
     }
     Ok(())
 }
@@ -606,7 +600,7 @@ fn tybounds(param_names: &Option<Vec<clean::GenericBound>>) -> impl fmt::Display
             Some(ref params) => {
                 for param in params {
                     write!(f, " + ")?;
-                    fmt::Display::fmt(param, f)?;
+                    fmt::Display::fmt(&param.print(), f)?;
                 }
                 Ok(())
             }
@@ -646,12 +640,12 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                 write!(f, "{}{:#}fn{:#}{:#}",
                        UnsafetySpace(decl.unsafety),
                        AbiSpace(decl.abi),
-                       comma_sep(&decl.generic_params),
-                       decl.decl)
+                       decl.print_generic_params(),
+                       decl.decl.print())
             } else {
                 write!(f, "{}{}", UnsafetySpace(decl.unsafety), AbiSpace(decl.abi))?;
                 primitive_link(f, PrimitiveType::Fn, "fn")?;
-                write!(f, "{}{}", comma_sep(&decl.generic_params), decl.decl)
+                write!(f, "{}{}", decl.print_generic_params(), decl.decl.print())
             }
         }
         clean::Tuple(ref typs) => {
@@ -660,24 +654,27 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                 &[ref one] => {
                     primitive_link(f, PrimitiveType::Tuple, "(")?;
                     // Carry `f.alternate()` into this display w/o branching manually.
-                    fmt::Display::fmt(one, f)?;
+                    fmt::Display::fmt(&one.print(), f)?;
                     primitive_link(f, PrimitiveType::Tuple, ",)")
                 }
                 many => {
                     primitive_link(f, PrimitiveType::Tuple, "(")?;
-                    fmt::Display::fmt(&comma_sep(many), f)?;
+                    for (i, item) in many.iter().enumerate() {
+                        if i != 0 { write!(f, ", ")?; }
+                        fmt::Display::fmt(&item.print(), f)?;
+                    }
                     primitive_link(f, PrimitiveType::Tuple, ")")
                 }
             }
         }
         clean::Slice(ref t) => {
             primitive_link(f, PrimitiveType::Slice, "[")?;
-            fmt::Display::fmt(t, f)?;
+            fmt::Display::fmt(&t.print(), f)?;
             primitive_link(f, PrimitiveType::Slice, "]")
         }
         clean::Array(ref t, ref n) => {
             primitive_link(f, PrimitiveType::Array, "[")?;
-            fmt::Display::fmt(t, f)?;
+            fmt::Display::fmt(&t.print(), f)?;
             primitive_link(f, PrimitiveType::Array, &format!("; {}]", n))
         }
         clean::Never => primitive_link(f, PrimitiveType::Never, "!"),
@@ -691,22 +688,22 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                 clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => {
                     if f.alternate() {
                         primitive_link(f, clean::PrimitiveType::RawPointer,
-                                       &format!("*{} {:#}", m, t))
+                                       &format!("*{} {:#}", m, t.print()))
                     } else {
                         primitive_link(f, clean::PrimitiveType::RawPointer,
-                                       &format!("*{} {}", m, t))
+                                       &format!("*{} {}", m, t.print()))
                     }
                 }
                 _ => {
                     primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{} ", m))?;
-                    fmt::Display::fmt(t, f)
+                    fmt::Display::fmt(&t.print(), f)
                 }
             }
         }
         clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => {
-            let lt = match *l {
-                Some(ref l) => format!("{} ", *l),
-                _ => String::new(),
+            let lt = match l {
+                Some(l) => format!("{} ", l.print()),
+                _ => String::new()
             };
             let m = MutableSpace(mutability);
             let amp = if f.alternate() {
@@ -720,19 +717,19 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                         clean::Generic(_) => {
                             if f.alternate() {
                                 primitive_link(f, PrimitiveType::Slice,
-                                    &format!("{}{}{}[{:#}]", amp, lt, m, **bt))
+                                    &format!("{}{}{}[{:#}]", amp, lt, m, bt.print()))
                             } else {
                                 primitive_link(f, PrimitiveType::Slice,
-                                    &format!("{}{}{}[{}]", amp, lt, m, **bt))
+                                    &format!("{}{}{}[{}]", amp, lt, m, bt.print()))
                             }
                         }
                         _ => {
                             primitive_link(f, PrimitiveType::Slice,
                                            &format!("{}{}{}[", amp, lt, m))?;
                             if f.alternate() {
-                                write!(f, "{:#}", **bt)?;
+                                write!(f, "{:#}", bt.print())?;
                             } else {
-                                write!(f, "{}", **bt)?;
+                                write!(f, "{}", bt.print())?;
                             }
                             primitive_link(f, PrimitiveType::Slice, "]")
                         }
@@ -756,9 +753,9 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
         }
         clean::ImplTrait(ref bounds) => {
             if f.alternate() {
-                write!(f, "impl {:#}", GenericBounds(bounds))
+                write!(f, "impl {:#}", print_generic_bounds(bounds))
             } else {
-                write!(f, "impl {}", GenericBounds(bounds))
+                write!(f, "impl {}", print_generic_bounds(bounds))
             }
         }
         clean::QPath { ref name, ref self_type, ref trait_ } => {
@@ -770,15 +767,15 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
             };
             if f.alternate() {
                 if should_show_cast {
-                    write!(f, "<{:#} as {:#}>::", self_type, trait_)?
+                    write!(f, "<{:#} as {:#}>::", self_type.print(), trait_.print())?
                 } else {
-                    write!(f, "{:#}::", self_type)?
+                    write!(f, "{:#}::", self_type.print())?
                 }
             } else {
                 if should_show_cast {
-                    write!(f, "&lt;{} as {}&gt;::", self_type, trait_)?
+                    write!(f, "&lt;{} as {}&gt;::", self_type.print(), trait_.print())?
                 } else {
-                    write!(f, "{}::", self_type)?
+                    write!(f, "{}::", self_type.print())?
                 }
             };
             match *trait_ {
@@ -818,55 +815,64 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
     }
 }
 
-impl fmt::Display for clean::Type {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt_type(self, f, false)
+impl clean::Type {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            fmt_type(self, f, false)
+        })
     }
 }
 
-fn fmt_impl(i: &clean::Impl,
-            f: &mut fmt::Formatter<'_>,
-            link_trait: bool,
-            use_absolute: bool) -> fmt::Result {
-    if f.alternate() {
-        write!(f, "impl{:#} ", i.generics)?;
-    } else {
-        write!(f, "impl{} ", i.generics)?;
+impl clean::Impl {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        self.print_inner(true, false)
     }
 
-    if let Some(ref ty) = i.trait_ {
-        if i.polarity == Some(clean::ImplPolarity::Negative) {
-            write!(f, "!")?;
-        }
+    fn print_inner(
+        &self,
+        link_trait: bool,
+        use_absolute: bool,
+    ) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            if f.alternate() {
+                write!(f, "impl{:#} ", self.generics.print())?;
+            } else {
+                write!(f, "impl{} ", self.generics.print())?;
+            }
 
-        if link_trait {
-            fmt::Display::fmt(ty, f)?;
-        } else {
-            match *ty {
-                clean::ResolvedPath { param_names: None, ref path, is_generic: false, .. } => {
-                    let last = path.segments.last().unwrap();
-                    fmt::Display::fmt(&last.name, f)?;
-                    fmt::Display::fmt(&last.args, f)?;
+            if let Some(ref ty) = self.trait_ {
+                if self.polarity == Some(clean::ImplPolarity::Negative) {
+                    write!(f, "!")?;
                 }
-                _ => unreachable!(),
-            }
-        }
-        write!(f, " for ")?;
-    }
 
-    if let Some(ref ty) = i.blanket_impl {
-        fmt_type(ty, f, use_absolute)?;
-    } else {
-        fmt_type(&i.for_, f, use_absolute)?;
-    }
+                if link_trait {
+                    fmt::Display::fmt(&ty.print(), f)?;
+                } else {
+                    match ty {
+                        clean::ResolvedPath { param_names: None, path, is_generic: false, .. } => {
+                            let last = path.segments.last().unwrap();
+                            fmt::Display::fmt(&last.name, f)?;
+                            fmt::Display::fmt(&last.args.print(), f)?;
+                        }
+                        _ => unreachable!(),
+                    }
+                }
+                write!(f, " for ")?;
+            }
 
-    fmt::Display::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }, f)?;
-    Ok(())
-}
+            if let Some(ref ty) = self.blanket_impl {
+                fmt_type(ty, f, use_absolute)?;
+            } else {
+                fmt_type(&self.for_, f, use_absolute)?;
+            }
 
-impl fmt::Display for clean::Impl {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt_impl(self, f, true, false)
+            fmt::Display::fmt(&WhereClause {
+                gens: &self.generics,
+                indent: 0,
+                end_newline: true,
+            }, f)?;
+            Ok(())
+        })
     }
 }
 
@@ -874,162 +880,193 @@ impl fmt::Display for clean::Impl {
 pub fn fmt_impl_for_trait_page(i: &clean::Impl,
                                f: &mut Buffer,
                                use_absolute: bool) {
-    f.with_formatter(|f| fmt_impl(i, f, false, use_absolute))
+    f.from_display(i.print_inner(false, use_absolute))
 }
 
-impl fmt::Display for clean::Arguments {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        for (i, input) in self.values.iter().enumerate() {
-            if !input.name.is_empty() {
-                write!(f, "{}: ", input.name)?;
-            }
-            if f.alternate() {
-                write!(f, "{:#}", input.type_)?;
-            } else {
-                write!(f, "{}", input.type_)?;
+impl clean::Arguments {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            for (i, input) in self.values.iter().enumerate() {
+                if !input.name.is_empty() {
+                    write!(f, "{}: ", input.name)?;
+                }
+                if f.alternate() {
+                    write!(f, "{:#}", input.type_.print())?;
+                } else {
+                    write!(f, "{}", input.type_.print())?;
+                }
+                if i + 1 < self.values.len() { write!(f, ", ")?; }
             }
-            if i + 1 < self.values.len() { write!(f, ", ")?; }
-        }
-        Ok(())
+            Ok(())
+        })
     }
 }
 
-impl fmt::Display for clean::FunctionRetTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            clean::Return(clean::Tuple(ref tys)) if tys.is_empty() => Ok(()),
-            clean::Return(ref ty) if f.alternate() => write!(f, " -> {:#}", ty),
-            clean::Return(ref ty) => write!(f, " -&gt; {}", ty),
-            clean::DefaultReturn => Ok(()),
-        }
+impl clean::FunctionRetTy {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            match self {
+                clean::Return(clean::Tuple(tys)) if tys.is_empty() => Ok(()),
+                clean::Return(ty) if f.alternate() => write!(f, " -> {:#}", ty.print()),
+                clean::Return(ty) => write!(f, " -&gt; {}", ty.print()),
+                clean::DefaultReturn => Ok(()),
+            }
+        })
     }
 }
 
-impl fmt::Display for clean::FnDecl {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if f.alternate() {
-            write!(f, "({args:#}){arrow:#}", args = self.inputs, arrow = self.output)
-        } else {
-            write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output)
-        }
+impl clean::BareFunctionDecl {
+    fn print_generic_params(&self) -> impl fmt::Display + '_ {
+        comma_sep(self.generic_params.iter().map(|g| g.print()))
     }
 }
 
-impl<'a> fmt::Display for Function<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let &Function { decl, header_len, indent, asyncness } = self;
-        let amp = if f.alternate() { "&" } else { "&amp;" };
-        let mut args = String::new();
-        let mut args_plain = String::new();
-        for (i, input) in decl.inputs.values.iter().enumerate() {
-            if i == 0 {
-                args.push_str("<br>");
+impl clean::FnDecl {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            if f.alternate() {
+                write!(f,
+                    "({args:#}){arrow:#}", args = self.inputs.print(), arrow = self.output.print())
+            } else {
+                write!(f,
+                    "({args}){arrow}", args = self.inputs.print(), arrow = self.output.print())
             }
+        })
+    }
+}
+
+
+impl Function<'_> {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            let &Function { decl, header_len, indent, asyncness } = self;
+            let amp = if f.alternate() { "&" } else { "&amp;" };
+            let mut args = String::new();
+            let mut args_plain = String::new();
+            for (i, input) in decl.inputs.values.iter().enumerate() {
+                if i == 0 {
+                    args.push_str("<br>");
+                }
 
-            if let Some(selfty) = input.to_self() {
-                match selfty {
-                    clean::SelfValue => {
-                        args.push_str("self");
-                        args_plain.push_str("self");
+                if let Some(selfty) = input.to_self() {
+                    match selfty {
+                        clean::SelfValue => {
+                            args.push_str("self");
+                            args_plain.push_str("self");
+                        }
+                        clean::SelfBorrowed(Some(ref lt), mtbl) => {
+                            args.push_str(
+                                &format!("{}{} {}self", amp, lt.print(), MutableSpace(mtbl)));
+                            args_plain.push_str(
+                                &format!("&{} {}self", lt.print(), MutableSpace(mtbl)));
+                        }
+                        clean::SelfBorrowed(None, mtbl) => {
+                            args.push_str(&format!("{}{}self", amp, MutableSpace(mtbl)));
+                            args_plain.push_str(&format!("&{}self", MutableSpace(mtbl)));
+                        }
+                        clean::SelfExplicit(ref typ) => {
+                            if f.alternate() {
+                                args.push_str(&format!("self: {:#}", typ.print()));
+                            } else {
+                                args.push_str(&format!("self: {}", typ.print()));
+                            }
+                            args_plain.push_str(&format!("self: {:#}", typ.print()));
+                        }
                     }
-                    clean::SelfBorrowed(Some(ref lt), mtbl) => {
-                        args.push_str(&format!("{}{} {}self", amp, *lt, MutableSpace(mtbl)));
-                        args_plain.push_str(&format!("&{} {}self", *lt, MutableSpace(mtbl)));
+                } else {
+                    if i > 0 {
+                        args.push_str(" <br>");
+                        args_plain.push_str(" ");
                     }
-                    clean::SelfBorrowed(None, mtbl) => {
-                        args.push_str(&format!("{}{}self", amp, MutableSpace(mtbl)));
-                        args_plain.push_str(&format!("&{}self", MutableSpace(mtbl)));
+                    if !input.name.is_empty() {
+                        args.push_str(&format!("{}: ", input.name));
+                        args_plain.push_str(&format!("{}: ", input.name));
                     }
-                    clean::SelfExplicit(ref typ) => {
-                        if f.alternate() {
-                            args.push_str(&format!("self: {:#}", *typ));
-                        } else {
-                            args.push_str(&format!("self: {}", *typ));
-                        }
-                        args_plain.push_str(&format!("self: {:#}", *typ));
+
+                    if f.alternate() {
+                        args.push_str(&format!("{:#}", input.type_.print()));
+                    } else {
+                        args.push_str(&input.type_.print().to_string());
                     }
+                    args_plain.push_str(&format!("{:#}", input.type_.print()));
                 }
-            } else {
-                if i > 0 {
-                    args.push_str(" <br>");
-                    args_plain.push_str(" ");
-                }
-                if !input.name.is_empty() {
-                    args.push_str(&format!("{}: ", input.name));
-                    args_plain.push_str(&format!("{}: ", input.name));
+                if i + 1 < decl.inputs.values.len() {
+                    args.push(',');
+                    args_plain.push(',');
                 }
-
-                if f.alternate() {
-                    args.push_str(&format!("{:#}", input.type_));
-                } else {
-                    args.push_str(&input.type_.to_string());
-                }
-                args_plain.push_str(&format!("{:#}", input.type_));
             }
-            if i + 1 < decl.inputs.values.len() {
-                args.push(',');
-                args_plain.push(',');
-            }
-        }
 
-        let args_plain = format!("({})", args_plain);
+            let args_plain = format!("({})", args_plain);
 
-        let output = if let hir::IsAsync::Async = asyncness {
-            Cow::Owned(decl.sugared_async_return_type())
-        } else {
-            Cow::Borrowed(&decl.output)
-        };
+            let output = if let hir::IsAsync::Async = asyncness {
+                Cow::Owned(decl.sugared_async_return_type())
+            } else {
+                Cow::Borrowed(&decl.output)
+            };
 
-        let arrow_plain = format!("{:#}", &output);
-        let arrow = if f.alternate() {
-            format!("{:#}", &output)
-        } else {
-            output.to_string()
-        };
+            let arrow_plain = format!("{:#}", &output.print());
+            let arrow = if f.alternate() {
+                format!("{:#}", &output.print())
+            } else {
+                output.print().to_string()
+            };
 
-        let declaration_len = header_len + args_plain.len() + arrow_plain.len();
-        let output = if declaration_len > 80 {
-            let full_pad = format!("<br>{}", "&nbsp;".repeat(indent + 4));
-            let close_pad = format!("<br>{}", "&nbsp;".repeat(indent));
-            format!("({args}{close}){arrow}",
-                    args = args.replace("<br>", &full_pad),
-                    close = close_pad,
-                    arrow = arrow)
-        } else {
-            format!("({args}){arrow}", args = args.replace("<br>", ""), arrow = arrow)
-        };
+            let declaration_len = header_len + args_plain.len() + arrow_plain.len();
+            let output = if declaration_len > 80 {
+                let full_pad = format!("<br>{}", "&nbsp;".repeat(indent + 4));
+                let close_pad = format!("<br>{}", "&nbsp;".repeat(indent));
+                format!("({args}{close}){arrow}",
+                        args = args.replace("<br>", &full_pad),
+                        close = close_pad,
+                        arrow = arrow)
+            } else {
+                format!("({args}){arrow}", args = args.replace("<br>", ""), arrow = arrow)
+            };
 
-        if f.alternate() {
-            write!(f, "{}", output.replace("<br>", "\n"))
-        } else {
-            write!(f, "{}", output)
-        }
+            if f.alternate() {
+                write!(f, "{}", output.replace("<br>", "\n"))
+            } else {
+                write!(f, "{}", output)
+            }
+        })
     }
 }
 
 impl<'a> fmt::Display for VisSpace<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self.get() {
-            Some(clean::Public) => f.write_str("pub "),
-            Some(clean::Inherited) | None => Ok(()),
-            Some(clean::Visibility::Crate) => write!(f, "pub(crate) "),
-            Some(clean::Visibility::Restricted(did, ref path)) => {
-                f.write_str("pub(")?;
-                if path.segments.len() != 1
-                    || (path.segments[0].name != "self" && path.segments[0].name != "super")
-                {
-                    f.write_str("in ")?;
+        if let Some(v) = self.0 {
+            fmt::Display::fmt(&v.print_with_space(), f)
+        } else {
+            Ok(())
+        }
+    }
+}
+
+impl clean::Visibility {
+    fn print_with_space(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            match *self {
+                clean::Public => f.write_str("pub "),
+                clean::Inherited => Ok(()),
+                clean::Visibility::Crate => write!(f, "pub(crate) "),
+                clean::Visibility::Restricted(did, ref path) => {
+                    f.write_str("pub(")?;
+                    if path.segments.len() != 1
+                        || (path.segments[0].name != "self" && path.segments[0].name != "super")
+                    {
+                        f.write_str("in ")?;
+                    }
+                    resolved_path(f, did, path, true, false)?;
+                    f.write_str(") ")
                 }
-                resolved_path(f, did, path, true, false)?;
-                f.write_str(") ")
             }
-        }
+        })
     }
 }
 
 impl fmt::Display for UnsafetySpace {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.get() {
+        match self.0 {
             hir::Unsafety::Unsafe => write!(f, "unsafe "),
             hir::Unsafety::Normal => Ok(())
         }
@@ -1038,7 +1075,7 @@ impl fmt::Display for UnsafetySpace {
 
 impl fmt::Display for ConstnessSpace {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.get() {
+        match self.0 {
             hir::Constness::Const => write!(f, "const "),
             hir::Constness::NotConst => Ok(())
         }
@@ -1054,66 +1091,72 @@ impl fmt::Display for AsyncSpace {
     }
 }
 
-impl fmt::Display for clean::Import {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            clean::Import::Simple(ref name, ref src) => {
-                if *name == src.path.last_name() {
-                    write!(f, "use {};", *src)
-                } else {
-                    write!(f, "use {} as {};", *src, *name)
+impl clean::Import {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            match *self {
+                clean::Import::Simple(ref name, ref src) => {
+                    if *name == src.path.last_name() {
+                        write!(f, "use {};", src.print())
+                    } else {
+                        write!(f, "use {} as {};", src.print(), *name)
+                    }
                 }
-            }
-            clean::Import::Glob(ref src) => {
-                if src.path.segments.is_empty() {
-                    write!(f, "use *;")
-                } else {
-                    write!(f, "use {}::*;", *src)
+                clean::Import::Glob(ref src) => {
+                    if src.path.segments.is_empty() {
+                        write!(f, "use *;")
+                    } else {
+                        write!(f, "use {}::*;", src.print())
+                    }
                 }
             }
-        }
+        })
     }
 }
 
-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, false),
-            _ => {
-                for (i, seg) in self.path.segments.iter().enumerate() {
-                    if i > 0 {
-                        write!(f, "::")?
+impl clean::ImportSource {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            match self.did {
+                Some(did) => resolved_path(f, did, &self.path, true, false),
+                _ => {
+                    for (i, seg) in self.path.segments.iter().enumerate() {
+                        if i > 0 {
+                            write!(f, "::")?
+                        }
+                        write!(f, "{}", seg.name)?;
                     }
-                    write!(f, "{}", seg.name)?;
+                    Ok(())
                 }
-                Ok(())
             }
-        }
+        })
     }
 }
 
-impl fmt::Display for clean::TypeBinding {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.name)?;
-        match self.kind {
-            clean::TypeBindingKind::Equality { ref ty } => {
-                if f.alternate() {
-                    write!(f, " = {:#}", ty)?;
-                } else {
-                    write!(f, " = {}", ty)?;
-                }
-            }
-            clean::TypeBindingKind::Constraint { ref bounds } => {
-                if !bounds.is_empty() {
+impl clean::TypeBinding {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            f.write_str(&self.name)?;
+            match self.kind {
+                clean::TypeBindingKind::Equality { ref ty } => {
                     if f.alternate() {
-                        write!(f, ": {:#}", GenericBounds(bounds))?;
+                        write!(f, " = {:#}", ty.print())?;
                     } else {
-                        write!(f, ":&nbsp;{}", GenericBounds(bounds))?;
+                        write!(f, " = {}", ty.print())?;
+                    }
+                }
+                clean::TypeBindingKind::Constraint { ref bounds } => {
+                    if !bounds.is_empty() {
+                        if f.alternate() {
+                            write!(f, ": {:#}", print_generic_bounds(bounds))?;
+                        } else {
+                            write!(f, ":&nbsp;{}", print_generic_bounds(bounds))?;
+                        }
                     }
                 }
             }
-        }
-        Ok(())
+            Ok(())
+        })
     }
 }
 
@@ -1146,6 +1189,18 @@ impl fmt::Display for DefaultSpace {
     }
 }
 
+impl clean::GenericArg {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        display_fn(move |f| {
+            match self {
+                clean::GenericArg::Lifetime(lt) => fmt::Display::fmt(&lt.print(), f),
+                clean::GenericArg::Type(ty) => fmt::Display::fmt(&ty.print(), f),
+                clean::GenericArg::Const(ct) => fmt::Display::fmt(&ct.print(), f),
+            }
+        })
+    }
+}
+
 crate fn display_fn(
     f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
 ) -> impl fmt::Display {
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index cf51a4eb5a5..5fb9afd6c49 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -46,14 +46,6 @@ pub enum ItemType {
 }
 
 
-#[derive(Copy, Eq, PartialEq, Clone)]
-pub enum NameSpace {
-    Type,
-    Value,
-    Macro,
-    Keyword,
-}
-
 impl<'a> From<&'a clean::Item> for ItemType {
     fn from(item: &'a clean::Item) -> ItemType {
         let inner = match item.inner {
@@ -120,7 +112,7 @@ impl From<clean::TypeKind> for ItemType {
 }
 
 impl ItemType {
-    pub fn css_class(&self) -> &'static str {
+    pub fn as_str(&self) -> &'static str {
         match *self {
             ItemType::Module          => "mod",
             ItemType::ExternCrate     => "externcrate",
@@ -151,7 +143,7 @@ impl ItemType {
         }
     }
 
-    pub fn name_space(&self) -> NameSpace {
+    pub fn name_space(&self) -> &'static str {
         match *self {
             ItemType::Struct |
             ItemType::Union |
@@ -163,7 +155,7 @@ impl ItemType {
             ItemType::AssocType |
             ItemType::OpaqueTy |
             ItemType::TraitAlias |
-            ItemType::ForeignType => NameSpace::Type,
+            ItemType::ForeignType => NAMESPACE_TYPE,
 
             ItemType::ExternCrate |
             ItemType::Import |
@@ -175,20 +167,20 @@ impl ItemType {
             ItemType::StructField |
             ItemType::Variant |
             ItemType::Constant |
-            ItemType::AssocConst => NameSpace::Value,
+            ItemType::AssocConst => NAMESPACE_VALUE,
 
             ItemType::Macro |
             ItemType::ProcAttribute |
-            ItemType::ProcDerive => NameSpace::Macro,
+            ItemType::ProcDerive => NAMESPACE_MACRO,
 
-            ItemType::Keyword => NameSpace::Keyword,
+            ItemType::Keyword => NAMESPACE_KEYWORD,
         }
     }
 }
 
 impl fmt::Display for ItemType {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.css_class().fmt(f)
+        write!(f, "{}", self.as_str())
     }
 }
 
@@ -196,20 +188,3 @@ pub const NAMESPACE_TYPE: &'static str = "t";
 pub const NAMESPACE_VALUE: &'static str = "v";
 pub const NAMESPACE_MACRO: &'static str = "m";
 pub const NAMESPACE_KEYWORD: &'static str = "k";
-
-impl NameSpace {
-    pub fn to_static_str(&self) -> &'static str {
-        match *self {
-            NameSpace::Type => NAMESPACE_TYPE,
-            NameSpace::Value => NAMESPACE_VALUE,
-            NameSpace::Macro => NAMESPACE_MACRO,
-            NameSpace::Keyword => NAMESPACE_KEYWORD,
-        }
-    }
-}
-
-impl fmt::Display for NameSpace {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.to_static_str().fmt(f)
-    }
-}
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 9846073cad4..7aaf04f34d3 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -66,7 +66,7 @@ use crate::doctree;
 use crate::fold::DocFolder;
 use crate::html::escape::Escape;
 use crate::html::format::{Buffer, AsyncSpace, ConstnessSpace};
-use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace, DefaultSpace};
+use crate::html::format::{print_generic_bounds, WhereClause, href, AbiSpace, DefaultSpace};
 use crate::html::format::{VisSpace, Function, UnsafetySpace, MutableSpace};
 use crate::html::format::fmt_impl_for_trait_page;
 use crate::html::item_type::ItemType;
@@ -1203,7 +1203,7 @@ themePicker.onblur = handleThemeButtonsBlur;
             if !imp.impl_item.def_id.is_local() { continue }
             have_impls = true;
             write!(implementors, "{{text:{},synthetic:{},types:{}}},",
-                   as_json(&imp.inner_impl().to_string()),
+                   as_json(&imp.inner_impl().print().to_string()),
                    imp.inner_impl().synthetic,
                    as_json(&collect_paths_for_type(imp.inner_impl().for_.clone()))).unwrap();
         }
@@ -1222,7 +1222,7 @@ themePicker.onblur = handleThemeButtonsBlur;
         }
         cx.shared.ensure_dir(&mydst)?;
         mydst.push(&format!("{}.{}.js",
-                            remote_item_type.css_class(),
+                            remote_item_type,
                             remote_path[remote_path.len() - 1]));
 
         let (mut all_implementors, _, _) = try_err!(collect(&mydst, &krate.name, "implementors",
@@ -1665,9 +1665,11 @@ impl ItemEntry {
     }
 }
 
-impl fmt::Display for ItemEntry {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "<a href='{}'>{}</a>", self.url, Escape(&self.name))
+impl ItemEntry {
+    crate fn print(&self) -> impl fmt::Display + '_ {
+        crate::html::format::display_fn(move |f| {
+            write!(f, "<a href='{}'>{}</a>", self.url, Escape(&self.name))
+        })
     }
 }
 
@@ -1759,7 +1761,7 @@ fn print_entries(f: &mut Buffer, e: &FxHashSet<ItemEntry>, title: &str, class: &
                title,
                Escape(title),
                class,
-               e.iter().map(|s| format!("<li>{}</li>", s)).collect::<String>());
+               e.iter().map(|s| format!("<li>{}</li>", s.print())).collect::<String>());
     }
 }
 
@@ -1939,7 +1941,7 @@ impl Context {
             title.push_str(it.name.as_ref().unwrap());
         }
         title.push_str(" - Rust");
-        let tyname = it.type_().css_class();
+        let tyname = it.type_();
         let desc = if it.is_crate() {
             format!("API documentation for the Rust `{}` crate.",
                     self.shared.layout.krate)
@@ -1949,7 +1951,7 @@ impl Context {
         };
         let keywords = make_item_keywords(it);
         let page = layout::Page {
-            css_class: tyname,
+            css_class: tyname.as_str(),
             root_path: &self.root_path(),
             static_root_path: self.shared.static_root_path.as_deref(),
             title: &title,
@@ -2090,7 +2092,7 @@ impl Context {
         for item in &m.items {
             if item.is_stripped() { continue }
 
-            let short = item.type_().css_class();
+            let short = item.type_();
             let myname = match item.name {
                 None => continue,
                 Some(ref s) => s.to_string(),
@@ -2285,7 +2287,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer) {
 fn item_path(ty: ItemType, name: &str) -> String {
     match ty {
         ItemType::Module => format!("{}index.html", SlashChecker(name)),
-        _ => format!("{}.{}.html", ty.css_class(), name),
+        _ => format!("{}.{}.html", ty, name),
     }
 }
 
@@ -2586,7 +2588,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
 
             clean::ImportItem(ref import) => {
                 write!(w, "<tr><td><code>{}{}</code></td></tr>",
-                       VisSpace(&myitem.visibility), *import);
+                       VisSpace(&myitem.visibility), import.print());
             }
 
             _ => {
@@ -2794,7 +2796,7 @@ fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Cons
                {name}: {typ}</pre>",
            vis = VisSpace(&it.visibility),
            name = it.name.as_ref().unwrap(),
-           typ = c.type_);
+           typ = c.type_.print());
     document(w, cx, it)
 }
 
@@ -2806,7 +2808,7 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static
            vis = VisSpace(&it.visibility),
            mutability = MutableSpace(s.mutability),
            name = it.name.as_ref().unwrap(),
-           typ = s.type_);
+           typ = s.type_.print());
     document(w, cx, it)
 }
 
@@ -2819,7 +2821,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
         AsyncSpace(f.header.asyncness),
         AbiSpace(f.header.abi),
         it.name.as_ref().unwrap(),
-        f.generics
+        f.generics.print()
     ).len();
     write!(w, "{}<pre class='rust fn'>", render_spotlight_traits(it));
     render_attributes(w, it, false);
@@ -2832,14 +2834,14 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
            asyncness = AsyncSpace(f.header.asyncness),
            abi = AbiSpace(f.header.abi),
            name = it.name.as_ref().unwrap(),
-           generics = f.generics,
+           generics = f.generics.print(),
            where_clause = WhereClause { gens: &f.generics, indent: 0, end_newline: true },
            decl = Function {
               decl: &f.decl,
               header_len,
               indent: 0,
               asyncness: f.header.asyncness,
-           });
+           }.print());
     document(w, cx, it)
 }
 
@@ -2880,15 +2882,15 @@ fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool) -> String {
             if i > 0 {
                 bounds.push_str(" + ");
             }
-            bounds.push_str(&(*p).to_string());
+            bounds.push_str(&p.print().to_string());
         }
     }
     bounds
 }
 
 fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering {
-    let lhs = format!("{}", lhs.inner_impl());
-    let rhs = format!("{}", rhs.inner_impl());
+    let lhs = format!("{}", lhs.inner_impl().print());
+    let rhs = format!("{}", rhs.inner_impl().print());
 
     // lhs and rhs are formatted as HTML, which may be unnecessary
     name_key(&lhs).cmp(&name_key(&rhs))
@@ -2915,7 +2917,7 @@ fn item_trait(
                UnsafetySpace(t.unsafety),
                if t.is_auto { "auto " } else { "" },
                it.name.as_ref().unwrap(),
-               t.generics,
+               t.generics.print(),
                bounds);
 
         if !t.generics.where_predicates.is_empty() {
@@ -3142,7 +3144,7 @@ fn item_trait(
                let (ref path, _) = cache.external_paths[&it.def_id];
                path[..path.len() - 1].join("/")
            },
-           ty = it.type_().css_class(),
+           ty = it.type_(),
            name = *it.name.as_ref().unwrap());
 }
 
@@ -3176,7 +3178,7 @@ fn assoc_const(w: &mut Buffer,
            VisSpace(&it.visibility),
            naive_assoc_href(it, link),
            it.name.as_ref().unwrap(),
-           ty);
+           ty.print());
 }
 
 fn assoc_type(w: &mut Buffer, it: &clean::Item,
@@ -3189,10 +3191,10 @@ fn assoc_type(w: &mut Buffer, it: &clean::Item,
            naive_assoc_href(it, link),
            it.name.as_ref().unwrap());
     if !bounds.is_empty() {
-        write!(w, ": {}", GenericBounds(bounds))
+        write!(w, ": {}", print_generic_bounds(bounds))
     }
     if let Some(default) = default {
-        write!(w, " = {}", default)
+        write!(w, " = {}", default.print())
     }
 }
 
@@ -3245,7 +3247,7 @@ fn render_assoc_item(w: &mut Buffer,
             DefaultSpace(meth.is_default()),
             AbiSpace(header.abi),
             name,
-            *g
+            g.print()
         ).len();
         let (indent, end_newline) = if parent == ItemType::Trait {
             header_len += 4;
@@ -3265,13 +3267,13 @@ fn render_assoc_item(w: &mut Buffer,
                AbiSpace(header.abi),
                href = href,
                name = name,
-               generics = *g,
+               generics = g.print(),
                decl = Function {
                    decl: d,
                    header_len,
                    indent,
                    asyncness: header.asyncness,
-               },
+               }.print(),
                where_clause = WhereClause {
                    gens: g,
                    indent,
@@ -3340,7 +3342,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct
                        id = id,
                        ns_id = ns_id,
                        name = field.name.as_ref().unwrap(),
-                       ty = ty);
+                       ty = ty.print());
                 document(w, cx, field);
             }
         }
@@ -3381,7 +3383,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union)
                    id = id,
                    name = name,
                    shortty = ItemType::StructField,
-                   ty = ty);
+                   ty = ty.print());
             if let Some(stability_class) = field.stability_class() {
                 write!(w, "<span class='stab {stab}'></span>",
                     stab = stability_class);
@@ -3399,7 +3401,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) {
         write!(w, "{}enum {}{}{}",
                VisSpace(&it.visibility),
                it.name.as_ref().unwrap(),
-               e.generics,
+               e.generics.print(),
                WhereClause { gens: &e.generics, indent: 0, end_newline: true });
         if e.variants.is_empty() && !e.variants_stripped {
             write!(w, " {{}}");
@@ -3418,7 +3420,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) {
                                     if i > 0 {
                                         write!(w, ",&nbsp;")
                                     }
-                                    write!(w, "{}", *ty);
+                                    write!(w, "{}", ty.print());
                                 }
                                 write!(w, ")");
                             }
@@ -3472,7 +3474,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) {
                         if i > 0 {
                             write!(w, ",&nbsp;");
                         }
-                        write!(w, "{}", *ty);
+                        write!(w, "{}", ty.print());
                     }
                     write!(w, ")");
                 }
@@ -3510,7 +3512,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) {
                                id = id,
                                ns_id = ns_id,
                                f = field.name.as_ref().unwrap(),
-                               t = *ty);
+                               t = ty.print());
                         document(w, cx, field);
                     }
                 }
@@ -3590,7 +3592,7 @@ fn render_struct(w: &mut Buffer, it: &clean::Item,
            if structhead {"struct "} else {""},
            it.name.as_ref().unwrap());
     if let Some(g) = g {
-        write!(w, "{}", g)
+        write!(w, "{}", g.print())
     }
     match ty {
         doctree::Plain => {
@@ -3605,7 +3607,7 @@ fn render_struct(w: &mut Buffer, it: &clean::Item,
                            tab,
                            VisSpace(&field.visibility),
                            field.name.as_ref().unwrap(),
-                           *ty);
+                           ty.print());
                     has_visible_fields = true;
                 }
             }
@@ -3633,7 +3635,7 @@ fn render_struct(w: &mut Buffer, it: &clean::Item,
                         write!(w, "_")
                     }
                     clean::StructFieldItem(ref ty) => {
-                        write!(w, "{}{}", VisSpace(&field.visibility), *ty)
+                        write!(w, "{}{}", VisSpace(&field.visibility), ty.print())
                     }
                     _ => unreachable!()
                 }
@@ -3664,7 +3666,7 @@ fn render_union(w: &mut Buffer, it: &clean::Item,
            if structhead {"union "} else {""},
            it.name.as_ref().unwrap());
     if let Some(g) = g {
-        write!(w, "{}", g);
+        write!(w, "{}", g.print());
         write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: true });
     }
 
@@ -3674,7 +3676,7 @@ fn render_union(w: &mut Buffer, it: &clean::Item,
             write!(w, "    {}{}: {},\n{}",
                    VisSpace(&field.visibility),
                    field.name.as_ref().unwrap(),
-                   *ty,
+                   ty.print(),
                    tab);
         }
     }
@@ -3740,7 +3742,7 @@ fn render_assoc_items(w: &mut Buffer,
                       Methods from {}&lt;Target = {}&gt;\
                       <a href='#deref-methods' class='anchor'></a>\
                     </h2>\
-                ", trait_, type_);
+                ", trait_.print(), type_.print());
                 RenderMode::ForDeref { mut_: deref_mut_ }
             }
         };
@@ -3885,12 +3887,13 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
                         out.push_str(
                             &format!("<h3 class=\"important\">Important traits for {}</h3>\
                                       <code class=\"content\">",
-                                     impl_.for_));
-                        trait_.push_str(&impl_.for_.to_string());
+                                     impl_.for_.print()));
+                        trait_.push_str(&impl_.for_.print().to_string());
                     }
 
                     //use the "where" class here to make it small
-                    out.push_str(&format!("<span class=\"where fmt-newline\">{}</span>", impl_));
+                    out.push_str(
+                        &format!("<span class=\"where fmt-newline\">{}</span>", impl_.print()));
                     let t_did = impl_.trait_.def_id().unwrap();
                     for it in &impl_.items {
                         if let clean::TypedefItem(ref tydef, _) = it.inner {
@@ -3927,7 +3930,7 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>,
             Some(ref t) => if is_on_foreign_type {
                 get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t)
             } else {
-                format!("impl-{}", small_url_encode(&format!("{:#}", t)))
+                format!("impl-{}", small_url_encode(&format!("{:#}", t.print())))
             },
             None => "impl".to_string(),
         });
@@ -3948,7 +3951,7 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>,
             write!(w, "</code>");
         } else {
             write!(w, "<h3 id='{}' class='impl'><code class='in-band'>{}</code>",
-                id, i.inner_impl()
+                id, i.inner_impl().print()
             );
         }
         write!(w, "<a href='#{}' class='anchor'></a>", id);
@@ -3993,8 +3996,10 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>,
                 // Only render when the method is not static or we allow static methods
                 if render_method_item {
                     let id = cx.derive_id(format!("{}.{}", item_type, name));
-                    let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-                    write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
+                    let ns_id = cx.derive_id(format!("{}.{}",
+                            name, item_type.name_space()));
+                    write!(w, "<h4 id='{}' class=\"{}{}\">",
+                        id, item_type, extra_class);
                     write!(w, "{}", spotlight_decl(decl));
                     write!(w, "<code id='{}'>", ns_id);
                     render_assoc_item(w, item, link.anchor(&id), ItemType::Impl);
@@ -4125,7 +4130,7 @@ fn item_opaque_ty(
     render_attributes(w, it, false);
     write!(w, "type {}{}{where_clause} = impl {bounds};</pre>",
            it.name.as_ref().unwrap(),
-           t.generics,
+           t.generics.print(),
            where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true },
            bounds = bounds(&t.bounds, false));
 
@@ -4144,7 +4149,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item,
     render_attributes(w, it, false);
     write!(w, "trait {}{}{} = {};</pre>",
            it.name.as_ref().unwrap(),
-           t.generics,
+           t.generics.print(),
            WhereClause { gens: &t.generics, indent: 0, end_newline: true },
            bounds(&t.bounds, true));
 
@@ -4162,9 +4167,9 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed
     render_attributes(w, it, false);
     write!(w, "type {}{}{where_clause} = {type_};</pre>",
            it.name.as_ref().unwrap(),
-           t.generics,
+           t.generics.print(),
            where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true },
-           type_ = t.type_);
+           type_ = t.type_.print());
 
     document(w, cx, it);
 
@@ -4269,7 +4274,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) {
                 relpath: '{path}'\
             }};</script>",
             name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
-            ty = it.type_().css_class(),
+            ty = it.type_(),
             path = relpath);
     if parentlen == 0 {
         // There is no sidebar-items.js beyond the crate root path
@@ -4370,9 +4375,10 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
                     if let Some(impls) = inner_impl {
                         out.push_str("<a class=\"sidebar-title\" href=\"#deref-methods\">");
                         out.push_str(&format!("Methods from {}&lt;Target={}&gt;",
-                                              Escape(&format!("{:#}",
-                                                     impl_.inner_impl().trait_.as_ref().unwrap())),
-                                              Escape(&format!("{:#}", target))));
+                            Escape(&format!(
+                                "{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print()
+                            )),
+                            Escape(&format!("{:#}", target.print()))));
                         out.push_str("</a>");
                         let mut ret = impls.iter()
                                            .filter(|i| i.inner_impl().trait_.is_none())
@@ -4397,9 +4403,9 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
                     .filter_map(|i| {
                         let is_negative_impl = is_negative_impl(i.inner_impl());
                         if let Some(ref i) = i.inner_impl().trait_ {
-                            let i_display = format!("{:#}", i);
+                            let i_display = format!("{:#}", i.print());
                             let out = Escape(&i_display);
-                            let encoded = small_url_encode(&format!("{:#}", i));
+                            let encoded = small_url_encode(&format!("{:#}", i.print()));
                             let generated = format!("<a href=\"#impl-{}\">{}{}</a>",
                                                     encoded,
                                                     if is_negative_impl { "!" } else { "" },
@@ -4471,14 +4477,17 @@ fn sidebar_struct(buf: &mut Buffer, it: &clean::Item, s: &clean::Struct) {
 }
 
 fn get_id_for_impl_on_foreign_type(for_: &clean::Type, trait_: &clean::Type) -> String {
-    small_url_encode(&format!("impl-{:#}-for-{:#}", trait_, for_))
+    small_url_encode(&format!("impl-{:#}-for-{:#}", trait_.print(), for_.print()))
 }
 
 fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> {
     match item.inner {
         clean::ItemEnum::ImplItem(ref i) => {
             if let Some(ref trait_) = i.trait_ {
-                Some((format!("{:#}", i.for_), get_id_for_impl_on_foreign_type(&i.for_, trait_)))
+                Some((
+                    format!("{:#}", i.for_.print()),
+                    get_id_for_impl_on_foreign_type(&i.for_, trait_),
+                ))
             } else {
                 None
             }
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index 4ee09f7096b..dc1ca8d7668 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -142,7 +142,8 @@ impl fold::DocFolder for CoverageCalculator {
             }
             clean::ImplItem(ref impl_) => {
                 if let Some(ref tr) = impl_.trait_ {
-                    debug!("impl {:#} for {:#} in {}", tr, impl_.for_, i.source.filename);
+                    debug!("impl {:#} for {:#} in {}",
+                        tr.print(), impl_.for_.print(), i.source.filename);
 
                     // don't count trait impls, the missing-docs lint doesn't so we shouldn't
                     // either
@@ -151,11 +152,11 @@ impl fold::DocFolder for CoverageCalculator {
                     // inherent impls *can* be documented, and those docs show up, but in most
                     // cases it doesn't make sense, as all methods on a type are in one single
                     // impl block
-                    debug!("impl {:#} in {}", impl_.for_, i.source.filename);
+                    debug!("impl {:#} in {}", impl_.for_.print(), i.source.filename);
                 }
             }
             _ => {
-                debug!("counting {} {:?} in {}", i.type_(), i.name, i.source.filename);
+                debug!("counting {:?} {:?} in {}", i.type_(), i.name, i.source.filename);
                 self.items.entry(i.source.filename.clone())
                           .or_default()
                           .count_item(has_docs);
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index d6073cdc1e1..b67f39d3280 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -237,7 +237,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
         });
 
         if parent_node.is_some() {
-            debug!("got parent node for {} {:?}, id {:?}", item.type_(), item.name, item.def_id);
+            debug!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id);
         }
 
         let current_item = match item.inner {
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 14f8b16dc30..d0f2cdad8f3 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -153,7 +153,7 @@ impl<'a> DocFolder for Stripper<'a> {
                 // We need to recurse into stripped modules to strip things
                 // like impl methods but when doing so we must not add any
                 // items to the `retained` set.
-                debug!("Stripper: recursing into stripped {} {:?}", i.type_(), i.name);
+                debug!("Stripper: recursing into stripped {:?} {:?}", i.type_(), i.name);
                 let old = mem::replace(&mut self.update_retained, false);
                 let ret = self.fold_item_recur(i);
                 self.update_retained = old;
@@ -178,7 +178,7 @@ impl<'a> DocFolder for Stripper<'a> {
             | clean::ForeignTypeItem => {
                 if i.def_id.is_local() {
                     if !self.access_levels.is_exported(i.def_id) {
-                        debug!("Stripper: stripping {} {:?}", i.type_(), i.name);
+                        debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
                         return None;
                     }
                 }
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index da8977544f6..0159e03f6f2 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -39,7 +39,7 @@ struct Stripper<'a> {
 impl<'a> DocFolder for Stripper<'a> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         if i.attrs.lists(sym::doc).has_word(sym::hidden) {
-            debug!("strip_hidden: stripping {} {:?}", i.type_(), i.name);
+            debug!("strip_hidden: stripping {:?} {:?}", i.type_(), i.name);
             // use a dedicated hidden item for given item type if any
             match i.inner {
                 clean::StructFieldItem(..) | clean::ModuleItem(..) => {