Skip to content

Commit 1b808f3

Browse files
committed
make doc_impl_item and render_default_items receive impl fmt::Write
1 parent 54f4588 commit 1b808f3

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,
@@ -1645,8 +1646,8 @@ fn render_impl(
16451646
// `containing_item` is used for rendering stability info. If the parent is a trait impl,
16461647
// `containing_item` will the grandparent, since trait impls can't have stability attached.
16471648
fn doc_impl_item(
1648-
boring: &mut String,
1649-
interesting: &mut String,
1649+
boring: impl fmt::Write,
1650+
interesting: impl fmt::Write,
16501651
cx: &Context<'_>,
16511652
item: &clean::Item,
16521653
parent: &clean::Item,
@@ -1655,7 +1656,7 @@ fn render_impl(
16551656
is_default_item: bool,
16561657
trait_: Option<&clean::Trait>,
16571658
rendering_params: ImplRenderingParameters,
1658-
) {
1659+
) -> fmt::Result {
16591660
let item_type = item.type_();
16601661
let name = item.name.as_ref().unwrap();
16611662

@@ -1730,15 +1731,16 @@ fn render_impl(
17301731
);
17311732
}
17321733
}
1733-
let w = if short_documented && trait_.is_some() { interesting } else { boring };
1734+
let mut w = if short_documented && trait_.is_some() {
1735+
Either::Left(interesting)
1736+
} else {
1737+
Either::Right(boring)
1738+
};
17341739

17351740
let toggled = !doc_buffer.is_empty();
17361741
if toggled {
17371742
let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
1738-
write_str(
1739-
w,
1740-
format_args!("<details class=\"toggle{method_toggle_class}\" open><summary>"),
1741-
);
1743+
write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>")?;
17421744
}
17431745
match &item.kind {
17441746
clean::MethodItem(..) | clean::RequiredMethodItem(_) => {
@@ -1753,172 +1755,151 @@ fn render_impl(
17531755
.find(|item| item.name.map(|n| n == *name).unwrap_or(false))
17541756
})
17551757
.map(|item| format!("{}.{name}", item.type_()));
1756-
write_str(
1758+
write!(
17571759
w,
1758-
format_args!(
1759-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1760+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
17601761
{}",
1761-
render_rightside(cx, item, render_mode)
1762-
),
1763-
);
1762+
render_rightside(cx, item, render_mode)
1763+
)?;
17641764
if trait_.is_some() {
17651765
// Anchors are only used on trait impls.
1766-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1766+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
17671767
}
1768-
write_str(
1768+
write!(
17691769
w,
1770-
format_args!(
1771-
"<h4 class=\"code-header\">{}</h4></section>",
1772-
render_assoc_item(
1773-
item,
1774-
link.anchor(source_id.as_ref().unwrap_or(&id)),
1775-
ItemType::Impl,
1776-
cx,
1777-
render_mode,
1778-
),
1770+
"<h4 class=\"code-header\">{}</h4></section>",
1771+
render_assoc_item(
1772+
item,
1773+
link.anchor(source_id.as_ref().unwrap_or(&id)),
1774+
ItemType::Impl,
1775+
cx,
1776+
render_mode,
17791777
),
1780-
);
1778+
)?;
17811779
}
17821780
}
17831781
clean::RequiredAssocConstItem(generics, ty) => {
17841782
let source_id = format!("{item_type}.{name}");
17851783
let id = cx.derive_id(&source_id);
1786-
write_str(
1784+
write!(
17871785
w,
1788-
format_args!(
1789-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1786+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
17901787
{}",
1791-
render_rightside(cx, item, render_mode)
1792-
),
1793-
);
1788+
render_rightside(cx, item, render_mode)
1789+
)?;
17941790
if trait_.is_some() {
17951791
// Anchors are only used on trait impls.
1796-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1792+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
17971793
}
1798-
write_str(
1794+
write!(
17991795
w,
1800-
format_args!(
1801-
"<h4 class=\"code-header\">{}</h4></section>",
1802-
assoc_const(
1803-
item,
1804-
generics,
1805-
ty,
1806-
AssocConstValue::None,
1807-
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1808-
0,
1809-
cx,
1810-
)
1796+
"<h4 class=\"code-header\">{}</h4></section>",
1797+
assoc_const(
1798+
item,
1799+
generics,
1800+
ty,
1801+
AssocConstValue::None,
1802+
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1803+
0,
1804+
cx,
18111805
),
1812-
);
1806+
)?;
18131807
}
18141808
clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => {
18151809
let source_id = format!("{item_type}.{name}");
18161810
let id = cx.derive_id(&source_id);
1817-
write_str(
1811+
write!(
18181812
w,
1819-
format_args!(
1820-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1813+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
18211814
{}",
1822-
render_rightside(cx, item, render_mode)
1823-
),
1824-
);
1815+
render_rightside(cx, item, render_mode),
1816+
)?;
18251817
if trait_.is_some() {
18261818
// Anchors are only used on trait impls.
1827-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1819+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
18281820
}
1829-
write_str(
1821+
write!(
18301822
w,
1831-
format_args!(
1832-
"<h4 class=\"code-header\">{}</h4></section>",
1833-
assoc_const(
1834-
item,
1835-
&ci.generics,
1836-
&ci.type_,
1837-
match item.kind {
1838-
clean::ProvidedAssocConstItem(_) =>
1839-
AssocConstValue::TraitDefault(&ci.kind),
1840-
clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
1841-
_ => unreachable!(),
1842-
},
1843-
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1844-
0,
1845-
cx,
1846-
)
1823+
"<h4 class=\"code-header\">{}</h4></section>",
1824+
assoc_const(
1825+
item,
1826+
&ci.generics,
1827+
&ci.type_,
1828+
match item.kind {
1829+
clean::ProvidedAssocConstItem(_) =>
1830+
AssocConstValue::TraitDefault(&ci.kind),
1831+
clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
1832+
_ => unreachable!(),
1833+
},
1834+
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1835+
0,
1836+
cx,
18471837
),
1848-
);
1838+
)?;
18491839
}
18501840
clean::RequiredAssocTypeItem(generics, bounds) => {
18511841
let source_id = format!("{item_type}.{name}");
18521842
let id = cx.derive_id(&source_id);
1853-
write_str(
1843+
write!(
18541844
w,
1855-
format_args!(
1856-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1845+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
18571846
{}",
1858-
render_rightside(cx, item, render_mode)
1859-
),
1860-
);
1847+
render_rightside(cx, item, render_mode),
1848+
)?;
18611849
if trait_.is_some() {
18621850
// Anchors are only used on trait impls.
1863-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1851+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
18641852
}
1865-
write_str(
1853+
write!(
18661854
w,
1867-
format_args!(
1868-
"<h4 class=\"code-header\">{}</h4></section>",
1869-
assoc_type(
1870-
item,
1871-
generics,
1872-
bounds,
1873-
None,
1874-
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1875-
0,
1876-
cx,
1877-
)
1855+
"<h4 class=\"code-header\">{}</h4></section>",
1856+
assoc_type(
1857+
item,
1858+
generics,
1859+
bounds,
1860+
None,
1861+
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1862+
0,
1863+
cx,
18781864
),
1879-
);
1865+
)?;
18801866
}
18811867
clean::AssocTypeItem(tydef, _bounds) => {
18821868
let source_id = format!("{item_type}.{name}");
18831869
let id = cx.derive_id(&source_id);
1884-
write_str(
1870+
write!(
18851871
w,
1886-
format_args!(
1887-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1872+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
18881873
{}",
1889-
render_rightside(cx, item, render_mode)
1890-
),
1891-
);
1874+
render_rightside(cx, item, render_mode),
1875+
)?;
18921876
if trait_.is_some() {
18931877
// Anchors are only used on trait impls.
1894-
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
1878+
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
18951879
}
1896-
write_str(
1880+
write!(
18971881
w,
1898-
format_args!(
1899-
"<h4 class=\"code-header\">{}</h4></section>",
1900-
assoc_type(
1901-
item,
1902-
&tydef.generics,
1903-
&[], // intentionally leaving out bounds
1904-
Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)),
1905-
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1906-
0,
1907-
cx,
1908-
)
1882+
"<h4 class=\"code-header\">{}</h4></section>",
1883+
assoc_type(
1884+
item,
1885+
&tydef.generics,
1886+
&[], // intentionally leaving out bounds
1887+
Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)),
1888+
link.anchor(if trait_.is_some() { &source_id } else { &id }),
1889+
0,
1890+
cx,
19091891
),
1910-
);
1892+
)?;
19111893
}
1912-
clean::StrippedItem(..) => return,
1894+
clean::StrippedItem(..) => return Ok(()),
19131895
_ => panic!("can't make docs for trait item with name {:?}", item.name),
19141896
}
19151897

1916-
w.push_str(&info_buffer);
1898+
w.write_str(&info_buffer)?;
19171899
if toggled {
1918-
w.push_str("</summary>");
1919-
w.push_str(&doc_buffer);
1920-
w.push_str("</details>");
1900+
write!(w, "</summary>{doc_buffer}</details>")?;
19211901
}
1902+
Ok(())
19221903
}
19231904

19241905
let mut impl_items = String::new();
@@ -1961,7 +1942,7 @@ fn render_impl(
19611942
false,
19621943
trait_,
19631944
rendering_params,
1964-
);
1945+
)?;
19651946
}
19661947
_ => {}
19671948
}
@@ -1979,7 +1960,7 @@ fn render_impl(
19791960
false,
19801961
trait_,
19811962
rendering_params,
1982-
);
1963+
)?;
19831964
}
19841965
for method in methods {
19851966
doc_impl_item(
@@ -1993,20 +1974,20 @@ fn render_impl(
19931974
false,
19941975
trait_,
19951976
rendering_params,
1996-
);
1977+
)?;
19971978
}
19981979
}
19991980

20001981
fn render_default_items(
2001-
boring: &mut String,
2002-
interesting: &mut String,
1982+
mut boring: impl fmt::Write,
1983+
mut interesting: impl fmt::Write,
20031984
cx: &Context<'_>,
20041985
t: &clean::Trait,
20051986
i: &clean::Impl,
20061987
parent: &clean::Item,
20071988
render_mode: RenderMode,
20081989
rendering_params: ImplRenderingParameters,
2009-
) {
1990+
) -> fmt::Result {
20101991
for trait_item in &t.items {
20111992
// Skip over any default trait items that are impossible to reference
20121993
// (e.g. if it has a `Self: Sized` bound on an unsized type).
@@ -2026,8 +2007,8 @@ fn render_impl(
20262007
let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods);
20272008

20282009
doc_impl_item(
2029-
boring,
2030-
interesting,
2010+
&mut boring,
2011+
&mut interesting,
20312012
cx,
20322013
trait_item,
20332014
parent,
@@ -2036,8 +2017,9 @@ fn render_impl(
20362017
true,
20372018
Some(t),
20382019
rendering_params,
2039-
);
2020+
)?;
20402021
}
2022+
Ok(())
20412023
}
20422024

20432025
// If we've implemented a trait, then also emit documentation for all
@@ -2057,7 +2039,7 @@ fn render_impl(
20572039
&i.impl_item,
20582040
render_mode,
20592041
rendering_params,
2060-
);
2042+
)?;
20612043
}
20622044
}
20632045
if render_mode == RenderMode::Normal {

0 commit comments

Comments
 (0)