Skip to content

Commit 5157d93

Browse files
committed
Auto merge of #108098 - notriddle:notriddle/rustdoc-tooltip-alloc, r=GuillaumeGomez
rustdoc: reduce allocations when generating tooltips An attempt to reduce the perf regression in #108052 (comment)
2 parents fd1f1fa + 49d995a commit 5157d93

File tree

7 files changed

+40
-29
lines changed

7 files changed

+40
-29
lines changed

compiler/rustc_resolve/src/rustdoc.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,9 @@ fn strip_generics_from_path_segment(segment: Vec<char>) -> Result<String, Malfor
265265
}
266266
}
267267

268-
pub fn strip_generics_from_path(path_str: &str) -> Result<String, MalformedGenerics> {
268+
pub fn strip_generics_from_path(path_str: &str) -> Result<Box<str>, MalformedGenerics> {
269269
if !path_str.contains(['<', '>']) {
270-
return Ok(path_str.to_string());
270+
return Ok(path_str.into());
271271
}
272272
let mut stripped_segments = vec![];
273273
let mut path = path_str.chars().peekable();
@@ -322,7 +322,11 @@ pub fn strip_generics_from_path(path_str: &str) -> Result<String, MalformedGener
322322

323323
let stripped_path = stripped_segments.join("::");
324324

325-
if !stripped_path.is_empty() { Ok(stripped_path) } else { Err(MalformedGenerics::MissingType) }
325+
if !stripped_path.is_empty() {
326+
Ok(stripped_path.into())
327+
} else {
328+
Err(MalformedGenerics::MissingType)
329+
}
326330
}
327331

328332
/// Returns whether the first doc-comment is an inner attribute.
@@ -336,7 +340,7 @@ pub fn inner_docs(attrs: &[ast::Attribute]) -> bool {
336340
/// Simplified version of the corresponding function in rustdoc.
337341
/// If the rustdoc version returns a successful result, this function must return the same result.
338342
/// Otherwise this function may return anything.
339-
fn preprocess_link(link: &str) -> String {
343+
fn preprocess_link(link: &str) -> Box<str> {
340344
let link = link.replace('`', "");
341345
let link = link.split('#').next().unwrap();
342346
let link = link.trim();
@@ -345,7 +349,7 @@ fn preprocess_link(link: &str) -> String {
345349
let link = link.strip_suffix("{}").unwrap_or(link);
346350
let link = link.strip_suffix("[]").unwrap_or(link);
347351
let link = if link != "!" { link.strip_suffix('!').unwrap_or(link) } else { link };
348-
strip_generics_from_path(link).unwrap_or_else(|_| link.to_string())
352+
strip_generics_from_path(link).unwrap_or_else(|_| link.into())
349353
}
350354

351355
/// Keep inline and reference links `[]`,
@@ -365,7 +369,7 @@ pub fn may_be_doc_link(link_type: LinkType) -> bool {
365369

366370
/// Simplified version of `preprocessed_markdown_links` from rustdoc.
367371
/// Must return at least the same links as it, but may add some more links on top of that.
368-
pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<String> {
372+
pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<Box<str>> {
369373
let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
370374
let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap();
371375

src/librustdoc/clean/types.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1017,12 +1017,12 @@ pub(crate) fn collapse_doc_fragments(doc_strings: &[DocFragment]) -> String {
10171017
#[derive(Clone, Debug, PartialEq, Eq)]
10181018
pub(crate) struct ItemLink {
10191019
/// The original link written in the markdown
1020-
pub(crate) link: String,
1020+
pub(crate) link: Box<str>,
10211021
/// The link text displayed in the HTML.
10221022
///
10231023
/// This may not be the same as `link` if there was a disambiguator
10241024
/// in an intra-doc link (e.g. \[`fn@f`\])
1025-
pub(crate) link_text: String,
1025+
pub(crate) link_text: Box<str>,
10261026
/// The `DefId` of the Item whose **HTML Page** contains the item being
10271027
/// linked to. This will be different to `item_id` on item's that don't
10281028
/// have their own page, such as struct fields and enum variants.
@@ -1035,9 +1035,9 @@ pub struct RenderedLink {
10351035
/// The text the link was original written as.
10361036
///
10371037
/// This could potentially include disambiguators and backticks.
1038-
pub(crate) original_text: String,
1038+
pub(crate) original_text: Box<str>,
10391039
/// The text to display in the HTML
1040-
pub(crate) new_text: String,
1040+
pub(crate) new_text: Box<str>,
10411041
/// The URL to put in the `href`
10421042
pub(crate) href: String,
10431043
/// The tooltip.

src/librustdoc/html/format.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -772,14 +772,21 @@ pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Cont
772772
let Some((fqp, shortty)) = cache.paths.get(&did)
773773
.or_else(|| cache.external_paths.get(&did))
774774
else { return String::new() };
775-
let fqp = fqp.iter().map(|sym| sym.as_str()).join("::");
775+
let mut buf = Buffer::new();
776776
if let &Some(UrlFragment::Item(id)) = fragment {
777-
let name = cx.tcx().item_name(id);
778-
let descr = cx.tcx().def_descr(id);
779-
format!("{descr} {fqp}::{name}")
780-
} else {
781-
format!("{shortty} {fqp}")
777+
write!(buf, "{} ", cx.tcx().def_descr(id));
778+
for component in fqp {
779+
write!(buf, "{component}::");
780+
}
781+
write!(buf, "{}", cx.tcx().item_name(id));
782+
} else if !fqp.is_empty() {
783+
let mut fqp_it = fqp.into_iter();
784+
write!(buf, "{shortty} {}", fqp_it.next().unwrap());
785+
for component in fqp_it {
786+
write!(buf, "::{component}");
787+
}
782788
}
789+
buf.into_inner()
783790
}
784791

785792
/// Used to render a [`clean::Path`].

src/librustdoc/html/markdown.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ impl Markdown<'_> {
978978
let mut replacer = |broken_link: BrokenLink<'_>| {
979979
links
980980
.iter()
981-
.find(|link| link.original_text.as_str() == &*broken_link.reference)
981+
.find(|link| &*link.original_text == &*broken_link.reference)
982982
.map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
983983
};
984984

@@ -1061,7 +1061,7 @@ impl MarkdownSummaryLine<'_> {
10611061
let mut replacer = |broken_link: BrokenLink<'_>| {
10621062
links
10631063
.iter()
1064-
.find(|link| link.original_text.as_str() == &*broken_link.reference)
1064+
.find(|link| &*link.original_text == &*broken_link.reference)
10651065
.map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
10661066
};
10671067

@@ -1108,7 +1108,7 @@ fn markdown_summary_with_limit(
11081108
let mut replacer = |broken_link: BrokenLink<'_>| {
11091109
link_names
11101110
.iter()
1111-
.find(|link| link.original_text.as_str() == &*broken_link.reference)
1111+
.find(|link| &*link.original_text == &*broken_link.reference)
11121112
.map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
11131113
};
11141114

@@ -1189,7 +1189,7 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
11891189
let mut replacer = |broken_link: BrokenLink<'_>| {
11901190
link_names
11911191
.iter()
1192-
.find(|link| link.original_text.as_str() == &*broken_link.reference)
1192+
.find(|link| &*link.original_text == &*broken_link.reference)
11931193
.map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
11941194
};
11951195

src/librustdoc/json/conversions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl JsonRenderer<'_> {
3838
Some(UrlFragment::UserWritten(_)) | None => *page_id,
3939
};
4040

41-
(link.clone(), id_from_item_default(id.into(), self.tcx))
41+
(String::from(&**link), id_from_item_default(id.into(), self.tcx))
4242
})
4343
.collect();
4444
let docs = item.attrs.collapsed_doc_value();

src/librustdoc/passes/collect_intra_doc_links.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ struct ResolutionInfo {
228228
item_id: ItemId,
229229
module_id: DefId,
230230
dis: Option<Disambiguator>,
231-
path_str: String,
231+
path_str: Box<str>,
232232
extra_fragment: Option<String>,
233233
}
234234

@@ -849,10 +849,10 @@ impl PreprocessingError {
849849

850850
#[derive(Clone)]
851851
struct PreprocessingInfo {
852-
path_str: String,
852+
path_str: Box<str>,
853853
disambiguator: Option<Disambiguator>,
854854
extra_fragment: Option<String>,
855-
link_text: String,
855+
link_text: Box<str>,
856856
}
857857

858858
// Not a typedef to avoid leaking several private structures from this module.
@@ -937,7 +937,7 @@ fn preprocess_link(
937937
path_str,
938938
disambiguator,
939939
extra_fragment: extra_fragment.map(|frag| frag.to_owned()),
940-
link_text: link_text.to_owned(),
940+
link_text: Box::<str>::from(link_text),
941941
}))
942942
}
943943

@@ -993,7 +993,7 @@ impl LinkCollector<'_, '_> {
993993
item_id: item.item_id,
994994
module_id,
995995
dis: disambiguator,
996-
path_str: path_str.to_owned(),
996+
path_str: path_str.clone(),
997997
extra_fragment: extra_fragment.clone(),
998998
},
999999
diag_info.clone(), // this struct should really be Copy, but Range is not :(
@@ -1067,7 +1067,7 @@ impl LinkCollector<'_, '_> {
10671067
}
10681068

10691069
res.def_id(self.cx.tcx).map(|page_id| ItemLink {
1070-
link: ori_link.link.clone(),
1070+
link: Box::<str>::from(&*ori_link.link),
10711071
link_text: link_text.clone(),
10721072
page_id,
10731073
fragment,
@@ -1091,7 +1091,7 @@ impl LinkCollector<'_, '_> {
10911091

10921092
let page_id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id));
10931093
Some(ItemLink {
1094-
link: ori_link.link.clone(),
1094+
link: Box::<str>::from(&*ori_link.link),
10951095
link_text: link_text.clone(),
10961096
page_id,
10971097
fragment,

src/librustdoc/passes/lint/html_tags.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
113113
if let Some(link) =
114114
link_names.iter().find(|link| *link.original_text == *broken_link.reference)
115115
{
116-
Some((link.href.as_str().into(), link.new_text.as_str().into()))
116+
Some((link.href.as_str().into(), link.new_text.to_string().into()))
117117
} else if matches!(
118118
&broken_link.link_type,
119119
LinkType::Reference | LinkType::ReferenceUnknown

0 commit comments

Comments
 (0)