Skip to content

Commit e228982

Browse files
Auto merge of #146942 - yotamofek:pr/rustdoc/finish_deprecating_write_str, r=<try>
[rustdoc] Finish getting rid of usages `write_str`
2 parents 4056082 + 8f2e717 commit e228982

File tree

2 files changed

+90
-113
lines changed

2 files changed

+90
-113
lines changed

src/librustdoc/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ path = "lib.rs"
1212
arrayvec = { version = "0.7", default-features = false }
1313
askama = { version = "0.14", default-features = false, features = ["alloc", "config", "derive"] }
1414
base64 = "0.21.7"
15-
indexmap = "2"
15+
indexmap = { version = "2", features = ["serde"] }
1616
itertools = "0.12"
1717
minifier = { version = "0.3.5", default-features = false }
1818
pulldown-cmark-escape = { version = "0.11.0", features = ["simd"] }

src/librustdoc/html/render/mod.rs

Lines changed: 89 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use std::path::PathBuf;
4848
use std::{fs, str};
4949

5050
use askama::Template;
51+
use indexmap::IndexMap;
5152
use itertools::Either;
5253
use rustc_ast::join_path_syms;
5354
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
@@ -58,8 +59,6 @@ use rustc_middle::ty::print::PrintTraitRefExt;
5859
use rustc_middle::ty::{self, TyCtxt};
5960
use rustc_span::symbol::{Symbol, sym};
6061
use rustc_span::{BytePos, DUMMY_SP, FileName, RealFileName};
61-
use serde::ser::SerializeMap;
62-
use serde::{Serialize, Serializer};
6362
use tracing::{debug, info};
6463

6564
pub(crate) use self::context::*;
@@ -75,7 +74,6 @@ use crate::html::escape::Escape;
7574
use crate::html::format::{
7675
Ending, HrefError, PrintWithSpace, href, print_abi_with_space, print_constness_with_space,
7776
print_default_space, print_generic_bounds, print_where_clause, visibility_print_with_space,
78-
write_str,
7977
};
8078
use crate::html::markdown::{
8179
HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine,
@@ -1507,12 +1505,10 @@ fn render_assoc_items_inner(
15071505
)
15081506
}
15091507
};
1510-
let mut impls_buf = String::new();
1511-
for i in &non_trait {
1512-
write_str(
1513-
&mut impls_buf,
1514-
format_args!(
1515-
"{}",
1508+
let impls_buf = fmt::from_fn(|f| {
1509+
non_trait
1510+
.iter()
1511+
.map(|i| {
15161512
render_impl(
15171513
cx,
15181514
i,
@@ -1528,9 +1524,11 @@ fn render_assoc_items_inner(
15281524
toggle_open_by_default: true,
15291525
},
15301526
)
1531-
),
1532-
);
1533-
}
1527+
})
1528+
.joined("", f)
1529+
})
1530+
.to_string();
1531+
15341532
if !impls_buf.is_empty() {
15351533
write!(
15361534
w,
@@ -1682,91 +1680,85 @@ fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Option<impl fmt:
16821680
}
16831681

16841682
fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
1685-
let mut out = String::new();
1686-
16871683
let did = ty.def_id(cx.cache()).expect("notable_traits_button already checked this");
16881684

16891685
let impls = cx.cache().impls.get(&did).expect("notable_traits_button already checked this");
16901686

1691-
for i in impls {
1692-
let impl_ = i.inner_impl();
1693-
if impl_.polarity != ty::ImplPolarity::Positive {
1694-
continue;
1695-
}
1696-
1697-
if !ty.is_doc_subtype_of(&impl_.for_, cx.cache()) {
1698-
// Two different types might have the same did,
1699-
// without actually being the same.
1700-
continue;
1701-
}
1702-
if let Some(trait_) = &impl_.trait_ {
1703-
let trait_did = trait_.def_id();
1704-
1705-
if cx.cache().traits.get(&trait_did).is_some_and(|t| t.is_notable_trait(cx.tcx())) {
1706-
if out.is_empty() {
1707-
write_str(
1708-
&mut out,
1709-
format_args!(
1710-
"<h3>Notable traits for <code>{}</code></h3>\
1711-
<pre><code>",
1712-
impl_.for_.print(cx)
1713-
),
1714-
);
1687+
let out = fmt::from_fn(|f| {
1688+
let mut notable_impls = impls
1689+
.iter()
1690+
.map(|impl_| impl_.inner_impl())
1691+
.filter(|impl_| impl_.polarity == ty::ImplPolarity::Positive)
1692+
.filter(|impl_| {
1693+
// Two different types might have the same did, without actually being the same.
1694+
ty.is_doc_subtype_of(&impl_.for_, cx.cache())
1695+
})
1696+
.filter_map(|impl_| {
1697+
if let Some(trait_) = &impl_.trait_
1698+
&& let trait_did = trait_.def_id()
1699+
&& let Some(trait_) = cx.cache().traits.get(&trait_did)
1700+
&& trait_.is_notable_trait(cx.tcx())
1701+
{
1702+
Some((impl_, trait_did))
1703+
} else {
1704+
None
17151705
}
1706+
})
1707+
.peekable();
17161708

1717-
write_str(
1718-
&mut out,
1719-
format_args!("<div class=\"where\">{}</div>", impl_.print(false, cx)),
1720-
);
1721-
for it in &impl_.items {
1722-
if let clean::AssocTypeItem(ref tydef, ref _bounds) = it.kind {
1723-
let empty_set = FxIndexSet::default();
1724-
let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);
1725-
write_str(
1726-
&mut out,
1727-
format_args!(
1728-
"<div class=\"where\"> {};</div>",
1729-
assoc_type(
1730-
it,
1731-
&tydef.generics,
1732-
&[], // intentionally leaving out bounds
1733-
Some(&tydef.type_),
1734-
src_link,
1735-
0,
1736-
cx,
1737-
)
1738-
),
1739-
);
1740-
}
1741-
}
1709+
let has_notable_impl = if let Some((impl_, _)) = notable_impls.peek() {
1710+
write!(
1711+
f,
1712+
"<h3>Notable traits for <code>{}</code></h3>\
1713+
<pre><code>",
1714+
impl_.for_.print(cx)
1715+
)?;
1716+
true
1717+
} else {
1718+
false
1719+
};
1720+
1721+
for (impl_, trait_did) in notable_impls {
1722+
write!(f, "<div class=\"where\">{}</div>", impl_.print(false, cx))?;
1723+
for it in &impl_.items {
1724+
let clean::AssocTypeItem(tydef, ..) = &it.kind else {
1725+
continue;
1726+
};
1727+
1728+
let empty_set = FxIndexSet::default();
1729+
let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);
1730+
1731+
write!(
1732+
f,
1733+
"<div class=\"where\"> {};</div>",
1734+
assoc_type(
1735+
it,
1736+
&tydef.generics,
1737+
&[], // intentionally leaving out bounds
1738+
Some(&tydef.type_),
1739+
src_link,
1740+
0,
1741+
cx,
1742+
)
1743+
)?;
17421744
}
17431745
}
1744-
}
1745-
if out.is_empty() {
1746-
out.push_str("</code></pre>");
1747-
}
1746+
1747+
if !has_notable_impl {
1748+
f.write_str("</code></pre>")?;
1749+
}
1750+
1751+
Ok(())
1752+
})
1753+
.to_string();
17481754

17491755
(format!("{:#}", ty.print(cx)), out)
17501756
}
17511757

17521758
fn notable_traits_json<'a>(tys: impl Iterator<Item = &'a clean::Type>, cx: &Context<'_>) -> String {
1753-
let mut mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect();
1754-
mp.sort_by(|(name1, _html1), (name2, _html2)| name1.cmp(name2));
1755-
struct NotableTraitsMap(Vec<(String, String)>);
1756-
impl Serialize for NotableTraitsMap {
1757-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1758-
where
1759-
S: Serializer,
1760-
{
1761-
let mut map = serializer.serialize_map(Some(self.0.len()))?;
1762-
for item in &self.0 {
1763-
map.serialize_entry(&item.0, &item.1)?;
1764-
}
1765-
map.end()
1766-
}
1767-
}
1768-
serde_json::to_string(&NotableTraitsMap(mp))
1769-
.expect("serialize (string, string) -> json object cannot fail")
1759+
let mut mp = tys.map(|ty| notable_traits_decl(ty, cx)).collect::<IndexMap<_, _>>();
1760+
mp.sort_unstable_keys();
1761+
serde_json::to_string(&mp).expect("serialize (string, string) -> json object cannot fail")
17701762
}
17711763

17721764
#[derive(Clone, Copy, Debug)]
@@ -1840,49 +1832,34 @@ fn render_impl(
18401832
document_item_info(cx, it, Some(parent))
18411833
.render_into(&mut info_buffer)
18421834
.unwrap();
1843-
write_str(
1844-
&mut doc_buffer,
1845-
format_args!("{}", document_full(item, cx, HeadingOffset::H5)),
1846-
);
1835+
doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string();
18471836
short_documented = false;
18481837
} else {
18491838
// In case the item isn't documented,
18501839
// provide short documentation from the trait.
1851-
write_str(
1852-
&mut doc_buffer,
1853-
format_args!(
1854-
"{}",
1855-
document_short(
1856-
it,
1857-
cx,
1858-
link,
1859-
parent,
1860-
rendering_params.show_def_docs,
1861-
)
1862-
),
1863-
);
1840+
doc_buffer = document_short(
1841+
it,
1842+
cx,
1843+
link,
1844+
parent,
1845+
rendering_params.show_def_docs,
1846+
)
1847+
.to_string();
18641848
}
18651849
}
18661850
} else {
18671851
document_item_info(cx, item, Some(parent))
18681852
.render_into(&mut info_buffer)
18691853
.unwrap();
18701854
if rendering_params.show_def_docs {
1871-
write_str(
1872-
&mut doc_buffer,
1873-
format_args!("{}", document_full(item, cx, HeadingOffset::H5)),
1874-
);
1855+
doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string();
18751856
short_documented = false;
18761857
}
18771858
}
18781859
} else {
1879-
write_str(
1880-
&mut doc_buffer,
1881-
format_args!(
1882-
"{}",
1883-
document_short(item, cx, link, parent, rendering_params.show_def_docs)
1884-
),
1885-
);
1860+
doc_buffer =
1861+
document_short(item, cx, link, parent, rendering_params.show_def_docs)
1862+
.to_string();
18861863
}
18871864
}
18881865
let mut w = if short_documented && trait_.is_some() {

0 commit comments

Comments
 (0)