Skip to content

Commit 8dd1cbb

Browse files
committed
lazify render_assoc_items_inner
1 parent f7640d5 commit 8dd1cbb

File tree

1 file changed

+54
-37
lines changed
  • src/librustdoc/html/render

1 file changed

+54
-37
lines changed

src/librustdoc/html/render/mod.rs

+54-37
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ mod span_map;
4040
mod type_layout;
4141
mod write_shared;
4242

43+
use std::borrow::Cow;
4344
use std::collections::VecDeque;
4445
use std::fmt::{self, Display as _, Write};
4546
use std::iter::Peekable;
@@ -99,6 +100,19 @@ enum AssocItemRender<'a> {
99100
DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
100101
}
101102

103+
impl AssocItemRender<'_> {
104+
fn render_mode(&self) -> RenderMode {
105+
match self {
106+
Self::All => RenderMode::Normal,
107+
&Self::DerefFor { deref_mut_, .. } => RenderMode::ForDeref { mut_: deref_mut_ },
108+
}
109+
}
110+
111+
fn class(&self) -> Option<&'static str> {
112+
if let Self::DerefFor { .. } = self { Some("impl-items") } else { None }
113+
}
114+
}
115+
102116
/// For different handling of associated items from the Deref target of a type rather than the type
103117
/// itself.
104118
#[derive(Copy, Clone, PartialEq)]
@@ -1211,7 +1225,7 @@ impl<'a> AssocItemLink<'a> {
12111225
}
12121226

12131227
fn write_section_heading(
1214-
title: &str,
1228+
title: impl fmt::Display,
12151229
id: &str,
12161230
extra_class: Option<&str>,
12171231
extra: impl fmt::Display,
@@ -1231,7 +1245,7 @@ fn write_section_heading(
12311245
})
12321246
}
12331247

1234-
fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display {
1248+
fn write_impl_section_heading(title: impl fmt::Display, id: &str) -> impl fmt::Display {
12351249
write_section_heading(title, id, None, "")
12361250
}
12371251

@@ -1308,20 +1322,17 @@ fn render_assoc_items_inner(
13081322
let (mut non_trait, traits): (Vec<_>, _) =
13091323
v.iter().partition(|i| i.inner_impl().trait_.is_none());
13101324
if !non_trait.is_empty() {
1311-
let mut close_tags = <Vec<&str>>::with_capacity(1);
1312-
let mut tmp_buf = String::new();
1313-
let (render_mode, id, class_html) = match what {
1314-
AssocItemRender::All => {
1315-
write_str(
1316-
&mut tmp_buf,
1317-
format_args!(
1318-
"{}",
1319-
write_impl_section_heading("Implementations", "implementations")
1320-
),
1321-
);
1322-
(RenderMode::Normal, "implementations-list".to_owned(), "")
1323-
}
1324-
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
1325+
let render_mode = what.render_mode();
1326+
let class_html = what
1327+
.class()
1328+
.map(|class| fmt::from_fn(move |f| write!(f, r#" class="{class}""#)))
1329+
.maybe_display();
1330+
let (section_heading, id) = match what {
1331+
AssocItemRender::All => (
1332+
Either::Left(write_impl_section_heading("Implementations", "implementations")),
1333+
Cow::Borrowed("implementations-list"),
1334+
),
1335+
AssocItemRender::DerefFor { trait_, type_, .. } => {
13251336
let id =
13261337
cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
13271338
// the `impls.get` above only looks at the outermost type,
@@ -1335,25 +1346,27 @@ fn render_assoc_items_inner(
13351346
type_.is_doc_subtype_of(&impl_.inner_impl().for_, &cx.shared.cache)
13361347
});
13371348
let derived_id = cx.derive_id(&id);
1338-
close_tags.push("</details>");
1339-
write_str(
1340-
&mut tmp_buf,
1341-
format_args!(
1342-
"<details class=\"toggle big-toggle\" open><summary>{}</summary>",
1343-
write_impl_section_heading(
1344-
&format!(
1345-
"<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>",
1346-
trait_ = trait_.print(cx),
1347-
type_ = type_.print(cx),
1348-
),
1349-
&id,
1350-
)
1351-
),
1352-
);
13531349
if let Some(def_id) = type_.def_id(cx.cache()) {
1354-
cx.deref_id_map.borrow_mut().insert(def_id, id);
1350+
cx.deref_id_map.borrow_mut().insert(def_id, id.clone());
13551351
}
1356-
(RenderMode::ForDeref { mut_: deref_mut_ }, derived_id, r#" class="impl-items""#)
1352+
(
1353+
Either::Right(fmt::from_fn(move |f| {
1354+
write!(
1355+
f,
1356+
"<details class=\"toggle big-toggle\" open><summary>{}</summary>",
1357+
write_impl_section_heading(
1358+
fmt::from_fn(|f| write!(
1359+
f,
1360+
"<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>",
1361+
trait_ = trait_.print(cx),
1362+
type_ = type_.print(cx),
1363+
)),
1364+
&id,
1365+
)
1366+
)
1367+
})),
1368+
Cow::Owned(derived_id),
1369+
)
13571370
}
13581371
};
13591372
let mut impls_buf = String::new();
@@ -1381,10 +1394,14 @@ fn render_assoc_items_inner(
13811394
);
13821395
}
13831396
if !impls_buf.is_empty() {
1384-
write!(w, "{tmp_buf}<div id=\"{id}\"{class_html}>{impls_buf}</div>").unwrap();
1385-
for tag in close_tags.into_iter().rev() {
1386-
w.write_str(tag).unwrap();
1387-
}
1397+
write!(
1398+
w,
1399+
"{section_heading}<div id=\"{id}\"{class_html}>{impls_buf}</div>{}",
1400+
matches!(what, AssocItemRender::DerefFor { .. })
1401+
.then_some("</details>")
1402+
.maybe_display(),
1403+
)
1404+
.unwrap();
13881405
}
13891406
}
13901407

0 commit comments

Comments
 (0)