Skip to content

Commit 1dee842

Browse files
committed
rustdoc: use std's (unstable) fmt::from_fn instead of open-coding it
1 parent 73fc7af commit 1dee842

File tree

7 files changed

+73
-91
lines changed

7 files changed

+73
-91
lines changed

src/librustdoc/html/format.rs

+37-53
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,9 @@ pub(crate) fn comma_sep<T: Display>(
150150
items: impl Iterator<Item = T>,
151151
space_after_comma: bool,
152152
) -> impl Display {
153-
display_fn(move |f| {
154-
for (i, item) in items.enumerate() {
153+
let items = Cell::new(Some(items));
154+
fmt::from_fn(move |f| {
155+
for (i, item) in items.take().unwrap().enumerate() {
155156
if i != 0 {
156157
write!(f, ",{}", if space_after_comma { " " } else { "" })?;
157158
}
@@ -165,7 +166,7 @@ pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>(
165166
bounds: &'a [clean::GenericBound],
166167
cx: &'a Context<'tcx>,
167168
) -> impl Display + 'a + Captures<'tcx> {
168-
display_fn(move |f| {
169+
fmt::from_fn(move |f| {
169170
let mut bounds_dup = FxHashSet::default();
170171

171172
for (i, bound) in bounds.iter().filter(|b| bounds_dup.insert(*b)).enumerate() {
@@ -183,7 +184,7 @@ impl clean::GenericParamDef {
183184
&'a self,
184185
cx: &'a Context<'tcx>,
185186
) -> impl Display + 'a + Captures<'tcx> {
186-
display_fn(move |f| match &self.kind {
187+
fmt::from_fn(move |f| match &self.kind {
187188
clean::GenericParamDefKind::Lifetime { outlives } => {
188189
write!(f, "{}", self.name)?;
189190

@@ -238,7 +239,7 @@ impl clean::Generics {
238239
&'a self,
239240
cx: &'a Context<'tcx>,
240241
) -> impl Display + 'a + Captures<'tcx> {
241-
display_fn(move |f| {
242+
fmt::from_fn(move |f| {
242243
let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
243244
if real_params.peek().is_none() {
244245
return Ok(());
@@ -268,12 +269,12 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
268269
indent: usize,
269270
ending: Ending,
270271
) -> impl Display + 'a + Captures<'tcx> {
271-
display_fn(move |f| {
272+
fmt::from_fn(move |f| {
272273
let mut where_predicates = gens
273274
.where_predicates
274275
.iter()
275276
.map(|pred| {
276-
display_fn(move |f| {
277+
fmt::from_fn(move |f| {
277278
if f.alternate() {
278279
f.write_str(" ")?;
279280
} else {
@@ -376,17 +377,15 @@ impl clean::Lifetime {
376377
impl clean::ConstantKind {
377378
pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display + '_ {
378379
let expr = self.expr(tcx);
379-
display_fn(
380-
move |f| {
381-
if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) }
382-
},
383-
)
380+
fmt::from_fn(move |f| {
381+
if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) }
382+
})
384383
}
385384
}
386385

387386
impl clean::PolyTrait {
388387
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
389-
display_fn(move |f| {
388+
fmt::from_fn(move |f| {
390389
print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?;
391390
self.trait_.print(cx).fmt(f)
392391
})
@@ -398,7 +397,7 @@ impl clean::GenericBound {
398397
&'a self,
399398
cx: &'a Context<'tcx>,
400399
) -> impl Display + 'a + Captures<'tcx> {
401-
display_fn(move |f| match self {
400+
fmt::from_fn(move |f| match self {
402401
clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()),
403402
clean::GenericBound::TraitBound(ty, modifiers) => {
404403
// `const` and `~const` trait bounds are experimental; don't render them.
@@ -430,7 +429,7 @@ impl clean::GenericBound {
430429

431430
impl clean::GenericArgs {
432431
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
433-
display_fn(move |f| {
432+
fmt::from_fn(move |f| {
434433
match self {
435434
clean::GenericArgs::AngleBracketed { args, constraints } => {
436435
if !args.is_empty() || !constraints.is_empty() {
@@ -950,7 +949,7 @@ fn tybounds<'a, 'tcx: 'a>(
950949
lt: &'a Option<clean::Lifetime>,
951950
cx: &'a Context<'tcx>,
952951
) -> impl Display + 'a + Captures<'tcx> {
953-
display_fn(move |f| {
952+
fmt::from_fn(move |f| {
954953
for (i, bound) in bounds.iter().enumerate() {
955954
if i > 0 {
956955
write!(f, " + ")?;
@@ -971,7 +970,7 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
971970
cx: &'a Context<'tcx>,
972971
keyword: &'static str,
973972
) -> impl Display + 'a + Captures<'tcx> {
974-
display_fn(move |f| {
973+
fmt::from_fn(move |f| {
975974
if !params.is_empty() {
976975
f.write_str(keyword)?;
977976
f.write_str(if f.alternate() { "<" } else { "&lt;" })?;
@@ -982,13 +981,13 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
982981
})
983982
}
984983

985-
pub(crate) fn anchor<'a, 'cx: 'a>(
984+
pub(crate) fn anchor<'a: 'cx, 'cx>(
986985
did: DefId,
987986
text: Symbol,
988-
cx: &'cx Context<'_>,
989-
) -> impl Display + 'a {
990-
let parts = href(did, cx);
991-
display_fn(move |f| {
987+
cx: &'cx Context<'a>,
988+
) -> impl Display + Captures<'a> + 'cx {
989+
fmt::from_fn(move |f| {
990+
let parts = href(did, cx);
992991
if let Ok((url, short_ty, fqp)) = parts {
993992
write!(
994993
f,
@@ -1150,7 +1149,7 @@ fn fmt_type(
11501149
}
11511150
}
11521151
clean::BorrowedRef { lifetime: ref l, mutability, type_: ref ty } => {
1153-
let lt = display_fn(|f| match l {
1152+
let lt = fmt::from_fn(|f| match l {
11541153
Some(l) => write!(f, "{} ", l.print()),
11551154
_ => Ok(()),
11561155
});
@@ -1270,7 +1269,7 @@ impl clean::Type {
12701269
&'a self,
12711270
cx: &'a Context<'tcx>,
12721271
) -> impl Display + 'b + Captures<'tcx> {
1273-
display_fn(move |f| fmt_type(self, f, false, cx))
1272+
fmt::from_fn(move |f| fmt_type(self, f, false, cx))
12741273
}
12751274
}
12761275

@@ -1279,7 +1278,7 @@ impl clean::Path {
12791278
&'a self,
12801279
cx: &'a Context<'tcx>,
12811280
) -> impl Display + 'b + Captures<'tcx> {
1282-
display_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
1281+
fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
12831282
}
12841283
}
12851284

@@ -1289,7 +1288,7 @@ impl clean::Impl {
12891288
use_absolute: bool,
12901289
cx: &'a Context<'tcx>,
12911290
) -> impl Display + 'a + Captures<'tcx> {
1292-
display_fn(move |f| {
1291+
fmt::from_fn(move |f| {
12931292
f.write_str("impl")?;
12941293
self.generics.print(cx).fmt(f)?;
12951294
f.write_str(" ")?;
@@ -1407,7 +1406,7 @@ impl clean::Arguments {
14071406
&'a self,
14081407
cx: &'a Context<'tcx>,
14091408
) -> impl Display + 'a + Captures<'tcx> {
1410-
display_fn(move |f| {
1409+
fmt::from_fn(move |f| {
14111410
for (i, input) in self.values.iter().enumerate() {
14121411
write!(f, "{}: ", input.name)?;
14131412
input.type_.print(cx).fmt(f)?;
@@ -1447,7 +1446,7 @@ impl clean::FnDecl {
14471446
&'a self,
14481447
cx: &'a Context<'tcx>,
14491448
) -> impl Display + 'b + Captures<'tcx> {
1450-
display_fn(move |f| {
1449+
fmt::from_fn(move |f| {
14511450
let ellipsis = if self.c_variadic { ", ..." } else { "" };
14521451
if f.alternate() {
14531452
write!(
@@ -1481,10 +1480,10 @@ impl clean::FnDecl {
14811480
indent: usize,
14821481
cx: &'a Context<'tcx>,
14831482
) -> impl Display + 'a + Captures<'tcx> {
1484-
display_fn(move |f| {
1483+
fmt::from_fn(move |f| {
14851484
// First, generate the text form of the declaration, with no line wrapping, and count the bytes.
14861485
let mut counter = WriteCounter(0);
1487-
write!(&mut counter, "{:#}", display_fn(|f| { self.inner_full_print(None, f, cx) }))
1486+
write!(&mut counter, "{:#}", fmt::from_fn(|f| { self.inner_full_print(None, f, cx) }))
14881487
.unwrap();
14891488
// If the text form was over 80 characters wide, we will line-wrap our output.
14901489
let line_wrapping_indent =
@@ -1566,7 +1565,7 @@ impl clean::FnDecl {
15661565
&'a self,
15671566
cx: &'a Context<'tcx>,
15681567
) -> impl Display + 'a + Captures<'tcx> {
1569-
display_fn(move |f| match &self.output {
1568+
fmt::from_fn(move |f| match &self.output {
15701569
clean::Tuple(tys) if tys.is_empty() => Ok(()),
15711570
ty if f.alternate() => {
15721571
write!(f, " -> {:#}", ty.print(cx))
@@ -1618,7 +1617,7 @@ pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
16181617
};
16191618

16201619
let is_doc_hidden = item.is_doc_hidden();
1621-
display_fn(move |f| {
1620+
fmt::from_fn(move |f| {
16221621
if is_doc_hidden {
16231622
f.write_str("#[doc(hidden)] ")?;
16241623
}
@@ -1692,7 +1691,7 @@ impl clean::Import {
16921691
&'a self,
16931692
cx: &'a Context<'tcx>,
16941693
) -> impl Display + 'a + Captures<'tcx> {
1695-
display_fn(move |f| match self.kind {
1694+
fmt::from_fn(move |f| match self.kind {
16961695
clean::ImportKind::Simple(name) => {
16971696
if name == self.source.path.last() {
16981697
write!(f, "use {};", self.source.print(cx))
@@ -1716,7 +1715,7 @@ impl clean::ImportSource {
17161715
&'a self,
17171716
cx: &'a Context<'tcx>,
17181717
) -> impl Display + 'a + Captures<'tcx> {
1719-
display_fn(move |f| match self.did {
1718+
fmt::from_fn(move |f| match self.did {
17201719
Some(did) => resolved_path(f, did, &self.path, true, false, cx),
17211720
_ => {
17221721
for seg in &self.path.segments[..self.path.segments.len() - 1] {
@@ -1744,7 +1743,7 @@ impl clean::AssocItemConstraint {
17441743
&'a self,
17451744
cx: &'a Context<'tcx>,
17461745
) -> impl Display + 'a + Captures<'tcx> {
1747-
display_fn(move |f| {
1746+
fmt::from_fn(move |f| {
17481747
f.write_str(self.assoc.name.as_str())?;
17491748
self.assoc.args.print(cx).fmt(f)?;
17501749
match self.kind {
@@ -1765,7 +1764,7 @@ impl clean::AssocItemConstraint {
17651764
}
17661765

17671766
pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display {
1768-
display_fn(move |f| {
1767+
fmt::from_fn(move |f| {
17691768
let quot = if f.alternate() { "\"" } else { "&quot;" };
17701769
match abi {
17711770
ExternAbi::Rust => Ok(()),
@@ -1783,7 +1782,7 @@ impl clean::GenericArg {
17831782
&'a self,
17841783
cx: &'a Context<'tcx>,
17851784
) -> impl Display + 'a + Captures<'tcx> {
1786-
display_fn(move |f| match self {
1785+
fmt::from_fn(move |f| match self {
17871786
clean::GenericArg::Lifetime(lt) => lt.print().fmt(f),
17881787
clean::GenericArg::Type(ty) => ty.print(cx).fmt(f),
17891788
clean::GenericArg::Const(ct) => ct.print(cx.tcx()).fmt(f),
@@ -1797,24 +1796,9 @@ impl clean::Term {
17971796
&'a self,
17981797
cx: &'a Context<'tcx>,
17991798
) -> impl Display + 'a + Captures<'tcx> {
1800-
display_fn(move |f| match self {
1799+
fmt::from_fn(move |f| match self {
18011800
clean::Term::Type(ty) => ty.print(cx).fmt(f),
18021801
clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f),
18031802
})
18041803
}
18051804
}
1806-
1807-
pub(crate) fn display_fn(f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl Display {
1808-
struct WithFormatter<F>(Cell<Option<F>>);
1809-
1810-
impl<F> Display for WithFormatter<F>
1811-
where
1812-
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
1813-
{
1814-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1815-
(self.0.take()).unwrap()(f)
1816-
}
1817-
}
1818-
1819-
WithFormatter(Cell::new(Some(f)))
1820-
}

src/librustdoc/html/render/mod.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ use crate::formats::cache::Cache;
6969
use crate::formats::item_type::ItemType;
7070
use crate::html::escape::Escape;
7171
use crate::html::format::{
72-
Buffer, Ending, HrefError, PrintWithSpace, display_fn, href, join_with_double_colon,
73-
print_abi_with_space, print_constness_with_space, print_default_space, print_generic_bounds,
74-
print_where_clause, visibility_print_with_space,
72+
Buffer, Ending, HrefError, PrintWithSpace, href, join_with_double_colon, print_abi_with_space,
73+
print_constness_with_space, print_default_space, print_generic_bounds, print_where_clause,
74+
visibility_print_with_space,
7575
};
7676
use crate::html::markdown::{
7777
HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine,
@@ -82,13 +82,14 @@ use crate::scrape_examples::{CallData, CallLocation};
8282
use crate::{DOC_RUST_LANG_ORG_CHANNEL, try_none};
8383

8484
pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
85-
crate::html::format::display_fn(move |f| {
85+
fmt::from_fn(move |f| {
8686
if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) }
8787
})
8888
}
8989

9090
/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
9191
/// impl.
92+
#[derive(Copy, Clone)]
9293
pub(crate) enum AssocItemRender<'a> {
9394
All,
9495
DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
@@ -309,9 +310,7 @@ impl ItemEntry {
309310

310311
impl ItemEntry {
311312
pub(crate) fn print(&self) -> impl fmt::Display + '_ {
312-
crate::html::format::display_fn(move |f| {
313-
write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name))
314-
})
313+
fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name)))
315314
}
316315
}
317316

@@ -513,7 +512,7 @@ fn document<'a, 'cx: 'a>(
513512
info!("Documenting {name}");
514513
}
515514

516-
display_fn(move |f| {
515+
fmt::from_fn(move |f| {
517516
document_item_info(cx, item, parent).render_into(f).unwrap();
518517
if parent.is_none() {
519518
write!(f, "{}", document_full_collapsible(item, cx, heading_offset))
@@ -530,7 +529,7 @@ fn render_markdown<'a, 'cx: 'a>(
530529
links: Vec<RenderedLink>,
531530
heading_offset: HeadingOffset,
532531
) -> impl fmt::Display + 'a + Captures<'cx> {
533-
display_fn(move |f| {
532+
fmt::from_fn(move |f| {
534533
write!(
535534
f,
536535
"<div class=\"docblock\">{}</div>",
@@ -557,7 +556,7 @@ fn document_short<'a, 'cx: 'a>(
557556
parent: &'a clean::Item,
558557
show_def_docs: bool,
559558
) -> impl fmt::Display + 'a + Captures<'cx> {
560-
display_fn(move |f| {
559+
fmt::from_fn(move |f| {
561560
document_item_info(cx, item, Some(parent)).render_into(f).unwrap();
562561
if !show_def_docs {
563562
return Ok(());
@@ -605,7 +604,7 @@ fn document_full_inner<'a, 'cx: 'a>(
605604
is_collapsible: bool,
606605
heading_offset: HeadingOffset,
607606
) -> impl fmt::Display + 'a + Captures<'cx> {
608-
display_fn(move |f| {
607+
fmt::from_fn(move |f| {
609608
if let Some(s) = item.opt_doc_value() {
610609
debug!("Doc block: =====\n{s}\n=====");
611610
if is_collapsible {
@@ -1159,7 +1158,7 @@ fn render_attributes_in_pre<'a, 'tcx: 'a>(
11591158
prefix: &'a str,
11601159
cx: &'a Context<'tcx>,
11611160
) -> impl fmt::Display + Captures<'a> + Captures<'tcx> {
1162-
crate::html::format::display_fn(move |f| {
1161+
fmt::from_fn(move |f| {
11631162
for a in it.attributes(cx.tcx(), cx.cache(), false) {
11641163
writeln!(f, "{prefix}{a}")?;
11651164
}
@@ -1256,9 +1255,9 @@ fn render_assoc_items<'a, 'cx: 'a>(
12561255
it: DefId,
12571256
what: AssocItemRender<'a>,
12581257
) -> impl fmt::Display + 'a + Captures<'cx> {
1259-
let mut derefs = DefIdSet::default();
1260-
derefs.insert(it);
1261-
display_fn(move |f| {
1258+
fmt::from_fn(move |f| {
1259+
let mut derefs = DefIdSet::default();
1260+
derefs.insert(it);
12621261
render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs);
12631262
Ok(())
12641263
})

0 commit comments

Comments
 (0)