Skip to content

Commit cf9cf6b

Browse files
committed
lazify render_assoc_items_inner
1 parent 95b20e4 commit cf9cf6b

File tree

1 file changed

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

1 file changed

+54
-37
lines changed

Diff for: src/librustdoc/html/render/mod.rs

+54-37
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ mod span_map;
3737
mod type_layout;
3838
mod write_shared;
3939

40+
use std::borrow::Cow;
4041
use std::collections::VecDeque;
4142
use std::fmt::{self, Display as _, Write};
4243
use std::iter::Peekable;
@@ -96,6 +97,19 @@ pub(crate) enum AssocItemRender<'a> {
9697
DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
9798
}
9899

100+
impl AssocItemRender<'_> {
101+
fn render_mode(&self) -> RenderMode {
102+
match self {
103+
Self::All => RenderMode::Normal,
104+
&Self::DerefFor { deref_mut_, .. } => RenderMode::ForDeref { mut_: deref_mut_ },
105+
}
106+
}
107+
108+
fn class(&self) -> Option<&'static str> {
109+
if let Self::DerefFor { .. } = self { Some("impl-items") } else { None }
110+
}
111+
}
112+
99113
/// For different handling of associated items from the Deref target of a type rather than the type
100114
/// itself.
101115
#[derive(Copy, Clone, PartialEq)]
@@ -1208,7 +1222,7 @@ impl<'a> AssocItemLink<'a> {
12081222
}
12091223

12101224
pub fn write_section_heading(
1211-
title: &str,
1225+
title: impl fmt::Display,
12121226
id: &str,
12131227
extra_class: Option<&str>,
12141228
extra: impl fmt::Display,
@@ -1228,7 +1242,7 @@ pub fn write_section_heading(
12281242
})
12291243
}
12301244

1231-
fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display {
1245+
fn write_impl_section_heading(title: impl fmt::Display, id: &str) -> impl fmt::Display {
12321246
write_section_heading(title, id, None, "")
12331247
}
12341248

@@ -1305,20 +1319,17 @@ fn render_assoc_items_inner(
13051319
let (mut non_trait, traits): (Vec<_>, _) =
13061320
v.iter().partition(|i| i.inner_impl().trait_.is_none());
13071321
if !non_trait.is_empty() {
1308-
let mut close_tags = <Vec<&str>>::with_capacity(1);
1309-
let mut tmp_buf = String::new();
1310-
let (render_mode, id, class_html) = match what {
1311-
AssocItemRender::All => {
1312-
write_str(
1313-
&mut tmp_buf,
1314-
format_args!(
1315-
"{}",
1316-
write_impl_section_heading("Implementations", "implementations")
1317-
),
1318-
);
1319-
(RenderMode::Normal, "implementations-list".to_owned(), "")
1320-
}
1321-
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
1322+
let render_mode = what.render_mode();
1323+
let class_html = what
1324+
.class()
1325+
.map(|class| fmt::from_fn(move |f| write!(f, r#" class="{class}""#)))
1326+
.maybe_display();
1327+
let (section_heading, id) = match what {
1328+
AssocItemRender::All => (
1329+
Either::Left(write_impl_section_heading("Implementations", "implementations")),
1330+
Cow::Borrowed("implementations-list"),
1331+
),
1332+
AssocItemRender::DerefFor { trait_, type_, .. } => {
13221333
let id =
13231334
cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
13241335
// the `impls.get` above only looks at the outermost type,
@@ -1332,25 +1343,27 @@ fn render_assoc_items_inner(
13321343
type_.is_doc_subtype_of(&impl_.inner_impl().for_, &cx.shared.cache)
13331344
});
13341345
let derived_id = cx.derive_id(&id);
1335-
close_tags.push("</details>");
1336-
write_str(
1337-
&mut tmp_buf,
1338-
format_args!(
1339-
"<details class=\"toggle big-toggle\" open><summary>{}</summary>",
1340-
write_impl_section_heading(
1341-
&format!(
1342-
"<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>",
1343-
trait_ = trait_.print(cx),
1344-
type_ = type_.print(cx),
1345-
),
1346-
&id,
1347-
)
1348-
),
1349-
);
13501346
if let Some(def_id) = type_.def_id(cx.cache()) {
1351-
cx.deref_id_map.borrow_mut().insert(def_id, id);
1347+
cx.deref_id_map.borrow_mut().insert(def_id, id.clone());
13521348
}
1353-
(RenderMode::ForDeref { mut_: deref_mut_ }, derived_id, r#" class="impl-items""#)
1349+
(
1350+
Either::Right(fmt::from_fn(move |f| {
1351+
write!(
1352+
f,
1353+
"<details class=\"toggle big-toggle\" open><summary>{}</summary>",
1354+
write_impl_section_heading(
1355+
fmt::from_fn(|f| write!(
1356+
f,
1357+
"<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>",
1358+
trait_ = trait_.print(cx),
1359+
type_ = type_.print(cx),
1360+
)),
1361+
&id,
1362+
)
1363+
)
1364+
})),
1365+
Cow::Owned(derived_id),
1366+
)
13541367
}
13551368
};
13561369
let mut impls_buf = String::new();
@@ -1378,10 +1391,14 @@ fn render_assoc_items_inner(
13781391
);
13791392
}
13801393
if !impls_buf.is_empty() {
1381-
write!(w, "{tmp_buf}<div id=\"{id}\"{class_html}>{impls_buf}</div>").unwrap();
1382-
for tag in close_tags.into_iter().rev() {
1383-
w.write_str(tag).unwrap();
1384-
}
1394+
write!(
1395+
w,
1396+
"{section_heading}<div id=\"{id}\"{class_html}>{impls_buf}</div>{}",
1397+
matches!(what, AssocItemRender::DerefFor { .. })
1398+
.then_some("</details>")
1399+
.maybe_display(),
1400+
)
1401+
.unwrap();
13851402
}
13861403
}
13871404

0 commit comments

Comments
 (0)