Skip to content

Commit

Permalink
rustdoc: avoid allocating strings primitive link printing
Browse files Browse the repository at this point in the history
This is aimed at hitting the allocator less in a function that
gets called a lot.
  • Loading branch information
notriddle committed Oct 21, 2023
1 parent 249624b commit 7af1b2f
Showing 1 changed file with 43 additions and 23 deletions.
66 changes: 43 additions & 23 deletions src/librustdoc/html/format.rs
Expand Up @@ -847,7 +847,7 @@ fn resolved_path<'cx>(
fn primitive_link(
f: &mut fmt::Formatter<'_>,
prim: clean::PrimitiveType,
name: &str,
name: &dyn std::fmt::Display,
cx: &Context<'_>,
) -> fmt::Result {
primitive_link_fragment(f, prim, name, "", cx)
Expand All @@ -856,7 +856,7 @@ fn primitive_link(
fn primitive_link_fragment(
f: &mut fmt::Formatter<'_>,
prim: clean::PrimitiveType,
name: &str,
name: &dyn std::fmt::Display,
fragment: &str,
cx: &Context<'_>,
) -> fmt::Result {
Expand Down Expand Up @@ -907,7 +907,7 @@ fn primitive_link_fragment(
None => {}
}
}
f.write_str(name)?;
name.fmt(f)?;
if needs_termination {
write!(f, "</a>")?;
}
Expand Down Expand Up @@ -977,9 +977,9 @@ fn fmt_type<'cx>(
}
clean::Infer => write!(f, "_"),
clean::Primitive(clean::PrimitiveType::Never) => {
primitive_link(f, PrimitiveType::Never, "!", cx)
primitive_link(f, PrimitiveType::Never, &"!", cx)
}
clean::Primitive(prim) => primitive_link(f, prim, prim.as_sym().as_str(), cx),
clean::Primitive(prim) => primitive_link(f, prim, &prim.as_sym().as_str(), cx),
clean::BareFunction(ref decl) => {
if f.alternate() {
write!(
Expand All @@ -998,16 +998,21 @@ fn fmt_type<'cx>(
decl.unsafety.print_with_space(),
print_abi_with_space(decl.abi)
)?;
primitive_link(f, PrimitiveType::Fn, "fn", cx)?;
primitive_link(f, PrimitiveType::Fn, &"fn", cx)?;
write!(f, "{}", decl.decl.print(cx))
}
}
clean::Tuple(ref typs) => {
match &typs[..] {
&[] => primitive_link(f, PrimitiveType::Unit, "()", cx),
&[] => primitive_link(f, PrimitiveType::Unit, &"()", cx),
[one] => {
if let clean::Generic(name) = one {
primitive_link(f, PrimitiveType::Tuple, &format!("({name},)"), cx)
primitive_link(
f,
PrimitiveType::Tuple,
&display_fn(|f| write!(f, "({name},)")),
cx,
)
} else {
write!(f, "(")?;
// Carry `f.alternate()` into this display w/o branching manually.
Expand All @@ -1028,7 +1033,13 @@ fn fmt_type<'cx>(
primitive_link(
f,
PrimitiveType::Tuple,
&format!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")),
&display_fn(|f| {
write!(
f,
"({})",
generic_names.iter().map(|s| s.as_str()).join(", ")
)
}),
cx,
)
} else {
Expand All @@ -1047,7 +1058,7 @@ fn fmt_type<'cx>(
}
clean::Slice(ref t) => match **t {
clean::Generic(name) => {
primitive_link(f, PrimitiveType::Slice, &format!("[{name}]"), cx)
primitive_link(f, PrimitiveType::Slice, &display_fn(|f| write!(f, "[{name}]")), cx)
}
_ => {
write!(f, "[")?;
Expand All @@ -1059,7 +1070,7 @@ fn fmt_type<'cx>(
clean::Generic(name) if !f.alternate() => primitive_link(
f,
PrimitiveType::Array,
&format!("[{name}; {n}]", n = Escape(n)),
&display_fn(|f| write!(f, "[{name}; {n}]", n = Escape(n))),
cx,
),
_ => {
Expand All @@ -1069,7 +1080,12 @@ fn fmt_type<'cx>(
write!(f, "; {n}")?;
} else {
write!(f, "; ")?;
primitive_link(f, PrimitiveType::Array, &format!("{n}", n = Escape(n)), cx)?;
primitive_link(
f,
PrimitiveType::Array,
&display_fn(|f| write!(f, "{n}", n = Escape(n))),
cx,
)?;
}
write!(f, "]")
}
Expand All @@ -1081,30 +1097,34 @@ fn fmt_type<'cx>(
};

if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
let text = if f.alternate() {
format!("*{m} {ty:#}", ty = t.print(cx))
let (f1, f2);
let display: &dyn std::fmt::Display = if f.alternate() {
f1 = display_fn(|f| write!(f, "*{m} {ty:#}", ty = t.print(cx)));
&f1
} else {
format!("*{m} {ty}", ty = t.print(cx))
f2 = display_fn(|f| write!(f, "*{m} {ty}", ty = t.print(cx)));
&f2
};
primitive_link(f, clean::PrimitiveType::RawPointer, &text, cx)
primitive_link(f, clean::PrimitiveType::RawPointer, display, cx)
} else {
primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{m} "), cx)?;
let display = display_fn(|f| write!(f, "*{m} "));
primitive_link(f, clean::PrimitiveType::RawPointer, &display, cx)?;
fmt::Display::fmt(&t.print(cx), f)
}
}
clean::BorrowedRef { lifetime: ref l, mutability, type_: ref ty } => {
let lt = match l {
Some(l) => format!("{} ", l.print()),
_ => String::new(),
};
let lt = display_fn(|f| match l {
Some(l) => write!(f, "{} ", l.print()),
_ => Ok(()),
});
let m = mutability.print_with_space();
let amp = if f.alternate() { "&" } else { "&amp;" };

if let clean::Generic(name) = **ty {
return primitive_link(
f,
PrimitiveType::Reference,
&format!("{amp}{lt}{m}{name}"),
&display_fn(|f| write!(f, "{amp}{lt}{m}{name}")),
cx,
);
}
Expand Down Expand Up @@ -1665,7 +1685,7 @@ impl clean::ImportSource {
}
let name = self.path.last();
if let hir::def::Res::PrimTy(p) = self.path.res {
primitive_link(f, PrimitiveType::from(p), name.as_str(), cx)?;
primitive_link(f, PrimitiveType::from(p), &name.as_str(), cx)?;
} else {
f.write_str(name.as_str())?;
}
Expand Down

0 comments on commit 7af1b2f

Please sign in to comment.