diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index bea0e75832c33e3c3db2acc41be3fbfff029628d..60106f3b7ae12f77cbd9f34d3b16a0d53d0b0fa0 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 66c47f14655baaea4a1c607e4655b4e0fb1740c3..128eac8cb0a513143e6acd9e5b9d259765e9cf1a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1009,18 +1009,25 @@ fn method( 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) @@ -1028,17 +1035,18 @@ fn method( (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()),