diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index bea0e75832c33..60106f3b7ae12 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -105,6 +105,10 @@ impl Buffer {
crate fn is_for_html(&self) -> bool {
self.for_html
}
+
+ crate fn reserve(&mut self, additional: usize) {
+ self.buffer.reserve(additional)
+ }
}
/// Wrapper struct for properly emitting a function or method declaration.
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 4e762a40f0849..375cf1d0c8f2e 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2999,18 +2999,25 @@ fn render_assoc_item(
href(did, cx.cache()).map(|p| format!("{}#{}.{}", p.0, ty, name)).unwrap_or(anchor)
}
};
- let mut header_len = format!(
- "{}{}{}{}{}{:#}fn {}{:#}",
- meth.visibility.print_with_space(cx.tcx(), meth.def_id, cx.cache()),
- header.constness.print_with_space(),
- header.asyncness.print_with_space(),
- header.unsafety.print_with_space(),
- print_default_space(meth.is_default()),
- print_abi_with_space(header.abi),
- name,
- g.print(cx.cache())
- )
- .len();
+ let tcx = cx.tcx();
+ let vis = meth.visibility.print_with_space(tcx, meth.def_id, cx.cache()).to_string();
+ let constness = header.constness.print_with_space();
+ let asyncness = header.asyncness.print_with_space();
+ let unsafety = header.unsafety.print_with_space();
+ let defaultness = print_default_space(meth.is_default());
+ let abi = print_abi_with_space(header.abi).to_string();
+ // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`.
+ let generics_len = format!("{:#}", g.print(cx.cache())).len();
+ let mut header_len = "fn ".len()
+ + vis.len()
+ + constness.len()
+ + asyncness.len()
+ + unsafety.len()
+ + defaultness.len()
+ + abi.len()
+ + name.as_str().len()
+ + generics_len;
+
let (indent, end_newline) = if parent == ItemType::Trait {
header_len += 4;
(4, false)
@@ -3018,17 +3025,18 @@ fn render_assoc_item(
(0, true)
};
render_attributes(w, meth, false);
+ w.reserve(header_len + "{".len() + "".len());
write!(
w,
"{}{}{}{}{}{}{}fn {name}\
{generics}{decl}{spotlight}{where_clause}",
if parent == ItemType::Trait { " " } else { "" },
- meth.visibility.print_with_space(cx.tcx(), meth.def_id, cx.cache()),
- header.constness.print_with_space(),
- header.asyncness.print_with_space(),
- header.unsafety.print_with_space(),
- print_default_space(meth.is_default()),
- print_abi_with_space(header.abi),
+ vis,
+ constness,
+ asyncness,
+ unsafety,
+ defaultness,
+ abi,
href = href,
name = name,
generics = g.print(cx.cache()),