Skip to content

Commit 4d4d8fd

Browse files
committed
Auto merge of rust-lang#117007 - notriddle:notriddle/format-links-with-display, r=<try>
[perf run] rustdoc: avoid allocating strings primitive link printing This is aimed at hitting the allocator less in a function that gets called a lot.
2 parents 249624b + 7af1b2f commit 4d4d8fd

File tree

1 file changed

+43
-23
lines changed

1 file changed

+43
-23
lines changed

Diff for: src/librustdoc/html/format.rs

+43-23
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ fn resolved_path<'cx>(
847847
fn primitive_link(
848848
f: &mut fmt::Formatter<'_>,
849849
prim: clean::PrimitiveType,
850-
name: &str,
850+
name: &dyn std::fmt::Display,
851851
cx: &Context<'_>,
852852
) -> fmt::Result {
853853
primitive_link_fragment(f, prim, name, "", cx)
@@ -856,7 +856,7 @@ fn primitive_link(
856856
fn primitive_link_fragment(
857857
f: &mut fmt::Formatter<'_>,
858858
prim: clean::PrimitiveType,
859-
name: &str,
859+
name: &dyn std::fmt::Display,
860860
fragment: &str,
861861
cx: &Context<'_>,
862862
) -> fmt::Result {
@@ -907,7 +907,7 @@ fn primitive_link_fragment(
907907
None => {}
908908
}
909909
}
910-
f.write_str(name)?;
910+
name.fmt(f)?;
911911
if needs_termination {
912912
write!(f, "</a>")?;
913913
}
@@ -977,9 +977,9 @@ fn fmt_type<'cx>(
977977
}
978978
clean::Infer => write!(f, "_"),
979979
clean::Primitive(clean::PrimitiveType::Never) => {
980-
primitive_link(f, PrimitiveType::Never, "!", cx)
980+
primitive_link(f, PrimitiveType::Never, &"!", cx)
981981
}
982-
clean::Primitive(prim) => primitive_link(f, prim, prim.as_sym().as_str(), cx),
982+
clean::Primitive(prim) => primitive_link(f, prim, &prim.as_sym().as_str(), cx),
983983
clean::BareFunction(ref decl) => {
984984
if f.alternate() {
985985
write!(
@@ -998,16 +998,21 @@ fn fmt_type<'cx>(
998998
decl.unsafety.print_with_space(),
999999
print_abi_with_space(decl.abi)
10001000
)?;
1001-
primitive_link(f, PrimitiveType::Fn, "fn", cx)?;
1001+
primitive_link(f, PrimitiveType::Fn, &"fn", cx)?;
10021002
write!(f, "{}", decl.decl.print(cx))
10031003
}
10041004
}
10051005
clean::Tuple(ref typs) => {
10061006
match &typs[..] {
1007-
&[] => primitive_link(f, PrimitiveType::Unit, "()", cx),
1007+
&[] => primitive_link(f, PrimitiveType::Unit, &"()", cx),
10081008
[one] => {
10091009
if let clean::Generic(name) = one {
1010-
primitive_link(f, PrimitiveType::Tuple, &format!("({name},)"), cx)
1010+
primitive_link(
1011+
f,
1012+
PrimitiveType::Tuple,
1013+
&display_fn(|f| write!(f, "({name},)")),
1014+
cx,
1015+
)
10111016
} else {
10121017
write!(f, "(")?;
10131018
// Carry `f.alternate()` into this display w/o branching manually.
@@ -1028,7 +1033,13 @@ fn fmt_type<'cx>(
10281033
primitive_link(
10291034
f,
10301035
PrimitiveType::Tuple,
1031-
&format!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")),
1036+
&display_fn(|f| {
1037+
write!(
1038+
f,
1039+
"({})",
1040+
generic_names.iter().map(|s| s.as_str()).join(", ")
1041+
)
1042+
}),
10321043
cx,
10331044
)
10341045
} else {
@@ -1047,7 +1058,7 @@ fn fmt_type<'cx>(
10471058
}
10481059
clean::Slice(ref t) => match **t {
10491060
clean::Generic(name) => {
1050-
primitive_link(f, PrimitiveType::Slice, &format!("[{name}]"), cx)
1061+
primitive_link(f, PrimitiveType::Slice, &display_fn(|f| write!(f, "[{name}]")), cx)
10511062
}
10521063
_ => {
10531064
write!(f, "[")?;
@@ -1059,7 +1070,7 @@ fn fmt_type<'cx>(
10591070
clean::Generic(name) if !f.alternate() => primitive_link(
10601071
f,
10611072
PrimitiveType::Array,
1062-
&format!("[{name}; {n}]", n = Escape(n)),
1073+
&display_fn(|f| write!(f, "[{name}; {n}]", n = Escape(n))),
10631074
cx,
10641075
),
10651076
_ => {
@@ -1069,7 +1080,12 @@ fn fmt_type<'cx>(
10691080
write!(f, "; {n}")?;
10701081
} else {
10711082
write!(f, "; ")?;
1072-
primitive_link(f, PrimitiveType::Array, &format!("{n}", n = Escape(n)), cx)?;
1083+
primitive_link(
1084+
f,
1085+
PrimitiveType::Array,
1086+
&display_fn(|f| write!(f, "{n}", n = Escape(n))),
1087+
cx,
1088+
)?;
10731089
}
10741090
write!(f, "]")
10751091
}
@@ -1081,30 +1097,34 @@ fn fmt_type<'cx>(
10811097
};
10821098

10831099
if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
1084-
let text = if f.alternate() {
1085-
format!("*{m} {ty:#}", ty = t.print(cx))
1100+
let (f1, f2);
1101+
let display: &dyn std::fmt::Display = if f.alternate() {
1102+
f1 = display_fn(|f| write!(f, "*{m} {ty:#}", ty = t.print(cx)));
1103+
&f1
10861104
} else {
1087-
format!("*{m} {ty}", ty = t.print(cx))
1105+
f2 = display_fn(|f| write!(f, "*{m} {ty}", ty = t.print(cx)));
1106+
&f2
10881107
};
1089-
primitive_link(f, clean::PrimitiveType::RawPointer, &text, cx)
1108+
primitive_link(f, clean::PrimitiveType::RawPointer, display, cx)
10901109
} else {
1091-
primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{m} "), cx)?;
1110+
let display = display_fn(|f| write!(f, "*{m} "));
1111+
primitive_link(f, clean::PrimitiveType::RawPointer, &display, cx)?;
10921112
fmt::Display::fmt(&t.print(cx), f)
10931113
}
10941114
}
10951115
clean::BorrowedRef { lifetime: ref l, mutability, type_: ref ty } => {
1096-
let lt = match l {
1097-
Some(l) => format!("{} ", l.print()),
1098-
_ => String::new(),
1099-
};
1116+
let lt = display_fn(|f| match l {
1117+
Some(l) => write!(f, "{} ", l.print()),
1118+
_ => Ok(()),
1119+
});
11001120
let m = mutability.print_with_space();
11011121
let amp = if f.alternate() { "&" } else { "&amp;" };
11021122

11031123
if let clean::Generic(name) = **ty {
11041124
return primitive_link(
11051125
f,
11061126
PrimitiveType::Reference,
1107-
&format!("{amp}{lt}{m}{name}"),
1127+
&display_fn(|f| write!(f, "{amp}{lt}{m}{name}")),
11081128
cx,
11091129
);
11101130
}
@@ -1665,7 +1685,7 @@ impl clean::ImportSource {
16651685
}
16661686
let name = self.path.last();
16671687
if let hir::def::Res::PrimTy(p) = self.path.res {
1668-
primitive_link(f, PrimitiveType::from(p), name.as_str(), cx)?;
1688+
primitive_link(f, PrimitiveType::from(p), &name.as_str(), cx)?;
16691689
} else {
16701690
f.write_str(name.as_str())?;
16711691
}

0 commit comments

Comments
 (0)