Skip to content

Commit 95b20e4

Browse files
committed
make doc_impl_item and render_default_items receive impl fmt::Write
1 parent 73339a1 commit 95b20e4

File tree

2 files changed

+110
-128
lines changed

2 files changed

+110
-128
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -1057,9 +1057,9 @@ checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d"
10571057

10581058
[[package]]
10591059
name = "either"
1060-
version = "1.13.0"
1060+
version = "1.15.0"
10611061
source = "registry+https://github.com/rust-lang/crates.io-index"
1062-
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
1062+
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
10631063

10641064
[[package]]
10651065
name = "elsa"

src/librustdoc/html/render/mod.rs

+108-126
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use std::iter::Peekable;
4343
use std::path::PathBuf;
4444
use std::{fs, str};
4545

46+
use itertools::Either;
4647
use rinja::Template;
4748
use rustc_attr_parsing::{
4849
ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince,
@@ -1647,8 +1648,8 @@ fn render_impl(
16471648
// `containing_item` is used for rendering stability info. If the parent is a trait impl,
16481649
// `containing_item` will the grandparent, since trait impls can't have stability attached.
16491650
fn doc_impl_item(
1650-
boring: &mut String,
1651-
interesting: &mut String,
1651+
boring: impl fmt::Write,
1652+
interesting: impl fmt::Write,
16521653
cx: &Context<'_>,
16531654
item: &clean::Item,
16541655
parent: &clean::Item,
@@ -1657,7 +1658,7 @@ fn render_impl(
16571658
is_default_item: bool,
16581659
trait_: Option<&clean::Trait>,
16591660
rendering_params: ImplRenderingParameters,
1660-
) {
1661+
) -> fmt::Result {
16611662
let item_type = item.type_();
16621663
let name = item.name.as_ref().unwrap();
16631664

@@ -1732,15 +1733,16 @@ fn render_impl(
17321733
);
17331734
}
17341735
}
1735-
let w = if short_documented && trait_.is_some() { interesting } else { boring };
1736+
let mut w = if short_documented && trait_.is_some() {
1737+
Either::Left(interesting)
1738+
} else {
1739+
Either::Right(boring)
1740+
};
17361741

17371742
let toggled = !doc_buffer.is_empty();
17381743
if toggled {
17391744
let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
1740-
write_str(
1741-
w,
1742-
format_args!("<details class=\"toggle{method_toggle_class}\" open><summary>"),
1743-
);
1745+
write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>")?;
17441746
}
17451747
match &item.kind {
17461748
clean::MethodItem(..) | clean::RequiredMethodItem(_) => {
@@ -1755,172 +1757,151 @@ fn render_impl(
17551757
.find(|item| item.name.map(|n| n == *name).unwrap_or(false))
17561758
})
17571759
.map(|item| format!("{}.{name}", item.type_()));
1758-
write_str(
1760+
write!(
17591761
w,
1760-
format_args!(
1761-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1762+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
17621763
{}",
1763-
render_rightside(cx, item, render_mode)
1764-
),
1765-
);
1764+
render_rightside(cx, item, render_mode)
1765+
)?;
17661766
if trait_.is_some() {
17671767
// Anchors are only used on trait impls.
1768-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1768+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
17691769
}
1770-
write_str(
1770+
write!(
17711771
w,
1772-
format_args!(
1773-
"<h4 class=\"code-header\">{}</h4></section>",
1774-
render_assoc_item(
1775-
item,
1776-
link.anchor(source_id.as_ref().unwrap_or(&id)),
1777-
ItemType::Impl,
1778-
cx,
1779-
render_mode,
1780-
),
1772+
"<h4 class=\"code-header\">{}</h4></section>",
1773+
render_assoc_item(
1774+
item,
1775+
link.anchor(source_id.as_ref().unwrap_or(&id)),
1776+
ItemType::Impl,
1777+
cx,
1778+
render_mode,
17811779
),
1782-
);
1780+
)?;
17831781
}
17841782
}
17851783
clean::RequiredAssocConstItem(generics, ty) => {
17861784
let source_id = format!("{item_type}.{name}");
17871785
let id = cx.derive_id(&source_id);
1788-
write_str(
1786+
write!(
17891787
w,
1790-
format_args!(
1791-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1788+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
17921789
{}",
1793-
render_rightside(cx, item, render_mode)
1794-
),
1795-
);
1790+
render_rightside(cx, item, render_mode)
1791+
)?;
17961792
if trait_.is_some() {
17971793
// Anchors are only used on trait impls.
1798-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1794+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
17991795
}
1800-
write_str(
1796+
write!(
18011797
w,
1802-
format_args!(
1803-
"<h4 class=\"code-header\">{}</h4></section>",
1804-
assoc_const(
1805-
item,
1806-
generics,
1807-
ty,
1808-
AssocConstValue::None,
1809-
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1810-
0,
1811-
cx,
1812-
)
1798+
"<h4 class=\"code-header\">{}</h4></section>",
1799+
assoc_const(
1800+
item,
1801+
generics,
1802+
ty,
1803+
AssocConstValue::None,
1804+
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1805+
0,
1806+
cx,
18131807
),
1814-
);
1808+
)?;
18151809
}
18161810
clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => {
18171811
let source_id = format!("{item_type}.{name}");
18181812
let id = cx.derive_id(&source_id);
1819-
write_str(
1813+
write!(
18201814
w,
1821-
format_args!(
1822-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1815+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
18231816
{}",
1824-
render_rightside(cx, item, render_mode)
1825-
),
1826-
);
1817+
render_rightside(cx, item, render_mode),
1818+
)?;
18271819
if trait_.is_some() {
18281820
// Anchors are only used on trait impls.
1829-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1821+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
18301822
}
1831-
write_str(
1823+
write!(
18321824
w,
1833-
format_args!(
1834-
"<h4 class=\"code-header\">{}</h4></section>",
1835-
assoc_const(
1836-
item,
1837-
&ci.generics,
1838-
&ci.type_,
1839-
match item.kind {
1840-
clean::ProvidedAssocConstItem(_) =>
1841-
AssocConstValue::TraitDefault(&ci.kind),
1842-
clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
1843-
_ => unreachable!(),
1844-
},
1845-
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1846-
0,
1847-
cx,
1848-
)
1825+
"<h4 class=\"code-header\">{}</h4></section>",
1826+
assoc_const(
1827+
item,
1828+
&ci.generics,
1829+
&ci.type_,
1830+
match item.kind {
1831+
clean::ProvidedAssocConstItem(_) =>
1832+
AssocConstValue::TraitDefault(&ci.kind),
1833+
clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
1834+
_ => unreachable!(),
1835+
},
1836+
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1837+
0,
1838+
cx,
18491839
),
1850-
);
1840+
)?;
18511841
}
18521842
clean::RequiredAssocTypeItem(generics, bounds) => {
18531843
let source_id = format!("{item_type}.{name}");
18541844
let id = cx.derive_id(&source_id);
1855-
write_str(
1845+
write!(
18561846
w,
1857-
format_args!(
1858-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1847+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
18591848
{}",
1860-
render_rightside(cx, item, render_mode)
1861-
),
1862-
);
1849+
render_rightside(cx, item, render_mode),
1850+
)?;
18631851
if trait_.is_some() {
18641852
// Anchors are only used on trait impls.
1865-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1853+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
18661854
}
1867-
write_str(
1855+
write!(
18681856
w,
1869-
format_args!(
1870-
"<h4 class=\"code-header\">{}</h4></section>",
1871-
assoc_type(
1872-
item,
1873-
generics,
1874-
bounds,
1875-
None,
1876-
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1877-
0,
1878-
cx,
1879-
)
1857+
"<h4 class=\"code-header\">{}</h4></section>",
1858+
assoc_type(
1859+
item,
1860+
generics,
1861+
bounds,
1862+
None,
1863+
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1864+
0,
1865+
cx,
18801866
),
1881-
);
1867+
)?;
18821868
}
18831869
clean::AssocTypeItem(tydef, _bounds) => {
18841870
let source_id = format!("{item_type}.{name}");
18851871
let id = cx.derive_id(&source_id);
1886-
write_str(
1872+
write!(
18871873
w,
1888-
format_args!(
1889-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1874+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
18901875
{}",
1891-
render_rightside(cx, item, render_mode)
1892-
),
1893-
);
1876+
render_rightside(cx, item, render_mode),
1877+
)?;
18941878
if trait_.is_some() {
18951879
// Anchors are only used on trait impls.
1896-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1880+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
18971881
}
1898-
write_str(
1882+
write!(
18991883
w,
1900-
format_args!(
1901-
"<h4 class=\"code-header\">{}</h4></section>",
1902-
assoc_type(
1903-
item,
1904-
&tydef.generics,
1905-
&[], // intentionally leaving out bounds
1906-
Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)),
1907-
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1908-
0,
1909-
cx,
1910-
)
1884+
"<h4 class=\"code-header\">{}</h4></section>",
1885+
assoc_type(
1886+
item,
1887+
&tydef.generics,
1888+
&[], // intentionally leaving out bounds
1889+
Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)),
1890+
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1891+
0,
1892+
cx,
19111893
),
1912-
);
1894+
)?;
19131895
}
1914-
clean::StrippedItem(..) => return,
1896+
clean::StrippedItem(..) => return Ok(()),
19151897
_ => panic!("can't make docs for trait item with name {:?}", item.name),
19161898
}
19171899

1918-
w.push_str(&info_buffer);
1900+
w.write_str(&info_buffer)?;
19191901
if toggled {
1920-
w.push_str("</summary>");
1921-
w.push_str(&doc_buffer);
1922-
w.push_str("</details>");
1902+
write!(w, "</summary>{doc_buffer}</details>")?;
19231903
}
1904+
Ok(())
19241905
}
19251906

19261907
let mut impl_items = String::new();
@@ -1963,7 +1944,7 @@ fn render_impl(
19631944
false,
19641945
trait_,
19651946
rendering_params,
1966-
);
1947+
)?;
19671948
}
19681949
_ => {}
19691950
}
@@ -1981,7 +1962,7 @@ fn render_impl(
19811962
false,
19821963
trait_,
19831964
rendering_params,
1984-
);
1965+
)?;
19851966
}
19861967
for method in methods {
19871968
doc_impl_item(
@@ -1995,20 +1976,20 @@ fn render_impl(
19951976
false,
19961977
trait_,
19971978
rendering_params,
1998-
);
1979+
)?;
19991980
}
20001981
}
20011982

20021983
fn render_default_items(
2003-
boring: &mut String,
2004-
interesting: &mut String,
1984+
mut boring: impl fmt::Write,
1985+
mut interesting: impl fmt::Write,
20051986
cx: &Context<'_>,
20061987
t: &clean::Trait,
20071988
i: &clean::Impl,
20081989
parent: &clean::Item,
20091990
render_mode: RenderMode,
20101991
rendering_params: ImplRenderingParameters,
2011-
) {
1992+
) -> fmt::Result {
20121993
for trait_item in &t.items {
20131994
// Skip over any default trait items that are impossible to reference
20141995
// (e.g. if it has a `Self: Sized` bound on an unsized type).
@@ -2028,8 +2009,8 @@ fn render_impl(
20282009
let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods);
20292010

20302011
doc_impl_item(
2031-
boring,
2032-
interesting,
2012+
&mut boring,
2013+
&mut interesting,
20332014
cx,
20342015
trait_item,
20352016
parent,
@@ -2038,8 +2019,9 @@ fn render_impl(
20382019
true,
20392020
Some(t),
20402021
rendering_params,
2041-
);
2022+
)?;
20422023
}
2024+
Ok(())
20432025
}
20442026

20452027
// If we've implemented a trait, then also emit documentation for all
@@ -2059,7 +2041,7 @@ fn render_impl(
20592041
&i.impl_item,
20602042
render_mode,
20612043
rendering_params,
2062-
);
2044+
)?;
20632045
}
20642046
}
20652047
if render_mode == RenderMode::Normal {

0 commit comments

Comments
 (0)