Skip to content

Commit 147bc29

Browse files
committed
rustdoc: Use Itertools::format instead of re-implementing it multiple times
Also, utilize the fact that `Symbol` impls `Display`, no need to go through `as_str()`
1 parent 04afec1 commit 147bc29

File tree

3 files changed

+113
-148
lines changed

3 files changed

+113
-148
lines changed

src/librustdoc/clean/cfg.rs

+57-35
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use std::fmt::{self, Write};
77
use std::{mem, ops};
88

9+
use itertools::Itertools;
910
use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit};
1011
use rustc_data_structures::fx::FxHashSet;
1112
use rustc_feature::Features;
@@ -396,11 +397,20 @@ impl fmt::Display for Display<'_> {
396397
Cfg::Any(ref sub_cfgs) => {
397398
let separator =
398399
if sub_cfgs.iter().all(Cfg::is_simple) { " nor " } else { ", nor " };
399-
for (i, sub_cfg) in sub_cfgs.iter().enumerate() {
400-
fmt.write_str(if i == 0 { "neither " } else { separator })?;
401-
write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?;
402-
}
403-
Ok(())
400+
fmt.write_str("neither ")?;
401+
sub_cfgs
402+
.iter()
403+
.map(|sub_cfg| {
404+
fmt::from_fn(|fmt| {
405+
write_with_opt_paren(
406+
fmt,
407+
!sub_cfg.is_all(),
408+
Display(sub_cfg, self.1),
409+
)
410+
})
411+
})
412+
.format(separator)
413+
.fmt(fmt)
404414
}
405415
ref simple @ Cfg::Cfg(..) => write!(fmt, "non-{}", Display(simple, self.1)),
406416
ref c => write!(fmt, "not ({})", Display(c, self.1)),
@@ -428,21 +438,27 @@ impl fmt::Display for Display<'_> {
428438
}
429439
};
430440

431-
for (i, sub_cfg) in sub_cfgs.iter().enumerate() {
432-
if i != 0 {
433-
fmt.write_str(separator)?;
434-
}
435-
if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) {
436-
if self.1.is_html() {
437-
write!(fmt, "<code>{feat}</code>")?;
438-
} else {
439-
write!(fmt, "`{feat}`")?;
440-
}
441-
} else {
442-
write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?;
443-
}
444-
}
445-
Ok(())
441+
sub_cfgs
442+
.iter()
443+
.map(|sub_cfg| {
444+
fmt::from_fn(move |fmt| {
445+
if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) {
446+
if self.1.is_html() {
447+
write!(fmt, "<code>{feat}</code>")
448+
} else {
449+
write!(fmt, "`{feat}`")
450+
}
451+
} else {
452+
write_with_opt_paren(
453+
fmt,
454+
!sub_cfg.is_all(),
455+
Display(sub_cfg, self.1),
456+
)
457+
}
458+
})
459+
})
460+
.format(separator)
461+
.fmt(fmt)
446462
}
447463

448464
Cfg::All(ref sub_cfgs) => {
@@ -465,21 +481,27 @@ impl fmt::Display for Display<'_> {
465481
}
466482
};
467483

468-
for (i, sub_cfg) in sub_cfgs.iter().enumerate() {
469-
if i != 0 {
470-
fmt.write_str(" and ")?;
471-
}
472-
if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) {
473-
if self.1.is_html() {
474-
write!(fmt, "<code>{feat}</code>")?;
475-
} else {
476-
write!(fmt, "`{feat}`")?;
477-
}
478-
} else {
479-
write_with_opt_paren(fmt, !sub_cfg.is_simple(), Display(sub_cfg, self.1))?;
480-
}
481-
}
482-
Ok(())
484+
sub_cfgs
485+
.iter()
486+
.map(|sub_cfg| {
487+
fmt::from_fn(move |fmt| {
488+
if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) {
489+
if self.1.is_html() {
490+
write!(fmt, "<code>{feat}</code>")
491+
} else {
492+
write!(fmt, "`{feat}`")
493+
}
494+
} else {
495+
write_with_opt_paren(
496+
fmt,
497+
!sub_cfg.is_simple(),
498+
Display(sub_cfg, self.1),
499+
)
500+
}
501+
})
502+
})
503+
.format(" and ")
504+
.fmt(fmt)
483505
}
484506

485507
Cfg::True => fmt.write_str("everywhere"),

src/librustdoc/html/format.rs

+34-82
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
//! not be used external to this module.
99
1010
use std::borrow::Cow;
11-
use std::cell::Cell;
1211
use std::cmp::Ordering;
1312
use std::fmt::{self, Display, Write};
1413
use std::iter::{self, once};
@@ -146,36 +145,19 @@ impl Buffer {
146145
}
147146
}
148147

149-
pub(crate) fn comma_sep<T: Display>(
150-
items: impl Iterator<Item = T>,
151-
space_after_comma: bool,
152-
) -> impl Display {
153-
let items = Cell::new(Some(items));
154-
fmt::from_fn(move |f| {
155-
for (i, item) in items.take().unwrap().enumerate() {
156-
if i != 0 {
157-
write!(f, ",{}", if space_after_comma { " " } else { "" })?;
158-
}
159-
item.fmt(f)?;
160-
}
161-
Ok(())
162-
})
163-
}
164-
165148
pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>(
166149
bounds: &'a [clean::GenericBound],
167150
cx: &'a Context<'tcx>,
168151
) -> impl Display + 'a + Captures<'tcx> {
169152
fmt::from_fn(move |f| {
170153
let mut bounds_dup = FxHashSet::default();
171154

172-
for (i, bound) in bounds.iter().filter(|b| bounds_dup.insert(*b)).enumerate() {
173-
if i > 0 {
174-
f.write_str(" + ")?;
175-
}
176-
bound.print(cx).fmt(f)?;
177-
}
178-
Ok(())
155+
bounds
156+
.iter()
157+
.filter(|b| bounds_dup.insert(*b))
158+
.map(|bound| bound.print(cx))
159+
.format(" + ")
160+
.fmt(f)
179161
})
180162
}
181163

@@ -190,12 +172,7 @@ impl clean::GenericParamDef {
190172

191173
if !outlives.is_empty() {
192174
f.write_str(": ")?;
193-
for (i, lt) in outlives.iter().enumerate() {
194-
if i != 0 {
195-
f.write_str(" + ")?;
196-
}
197-
write!(f, "{}", lt.print())?;
198-
}
175+
write!(f, "{}", outlives.iter().map(|lt| lt.print()).format(" + "))?;
199176
}
200177

201178
Ok(())
@@ -246,9 +223,9 @@ impl clean::Generics {
246223
}
247224

248225
if f.alternate() {
249-
write!(f, "<{:#}>", comma_sep(real_params.map(|g| g.print(cx)), true))
226+
write!(f, "<{:#}>", real_params.map(|g| g.print(cx)).format(", "))
250227
} else {
251-
write!(f, "&lt;{}&gt;", comma_sep(real_params.map(|g| g.print(cx)), true))
228+
write!(f, "&lt;{}&gt;", real_params.map(|g| g.print(cx)).format(", "))
252229
}
253230
})
254231
}
@@ -318,7 +295,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
318295
return Ok(());
319296
}
320297

321-
let where_preds = comma_sep(where_predicates, false);
298+
let where_preds = where_predicates.format(",");
322299
let clause = if f.alternate() {
323300
if ending == Ending::Newline {
324301
format!(" where{where_preds},")
@@ -415,12 +392,7 @@ impl clean::GenericBound {
415392
} else {
416393
f.write_str("use&lt;")?;
417394
}
418-
for (i, arg) in args.iter().enumerate() {
419-
if i > 0 {
420-
write!(f, ", ")?;
421-
}
422-
arg.fmt(f)?;
423-
}
395+
args.iter().format(", ").fmt(f)?;
424396
if f.alternate() { f.write_str(">") } else { f.write_str("&gt;") }
425397
}
426398
})
@@ -524,11 +496,7 @@ pub(crate) enum HrefError {
524496
// Panics if `syms` is empty.
525497
pub(crate) fn join_with_double_colon(syms: &[Symbol]) -> String {
526498
let mut s = String::with_capacity(estimate_item_path_byte_length(syms.len()));
527-
s.push_str(syms[0].as_str());
528-
for sym in &syms[1..] {
529-
s.push_str("::");
530-
s.push_str(sym.as_str());
531-
}
499+
write!(s, "{}", syms.iter().format("::")).unwrap();
532500
s
533501
}
534502

@@ -572,20 +540,20 @@ fn generate_macro_def_id_path(
572540
}
573541

574542
if let Some(last) = path.last_mut() {
575-
*last = Symbol::intern(&format!("macro.{}.html", last.as_str()));
543+
*last = Symbol::intern(&format!("macro.{last}.html"));
576544
}
577545

578546
let url = match cache.extern_locations[&def_id.krate] {
579547
ExternalLocation::Remote(ref s) => {
580548
// `ExternalLocation::Remote` always end with a `/`.
581-
format!("{s}{path}", path = path.iter().map(|p| p.as_str()).join("/"))
549+
format!("{s}{path}", path = path.iter().format("/"))
582550
}
583551
ExternalLocation::Local => {
584552
// `root_path` always end with a `/`.
585553
format!(
586554
"{root_path}{path}",
587555
root_path = root_path.unwrap_or(""),
588-
path = path.iter().map(|p| p.as_str()).join("/")
556+
path = path.iter().format("/")
589557
)
590558
}
591559
ExternalLocation::Unknown => {
@@ -682,9 +650,8 @@ fn make_href(
682650
url_parts.push("index.html");
683651
}
684652
_ => {
685-
let prefix = shortty.as_str();
686653
let last = fqp.last().unwrap();
687-
url_parts.push_fmt(format_args!("{prefix}.{last}.html"));
654+
url_parts.push_fmt(format_args!("{shortty}.{last}.html"));
688655
}
689656
}
690657
Ok((url_parts.finish(), shortty, fqp.to_vec()))
@@ -950,12 +917,7 @@ fn tybounds<'a, 'tcx: 'a>(
950917
cx: &'a Context<'tcx>,
951918
) -> impl Display + 'a + Captures<'tcx> {
952919
fmt::from_fn(move |f| {
953-
for (i, bound) in bounds.iter().enumerate() {
954-
if i > 0 {
955-
write!(f, " + ")?;
956-
}
957-
bound.print(cx).fmt(f)?;
958-
}
920+
bounds.iter().map(|bound| bound.print(cx)).format(" + ").fmt(f)?;
959921
if let Some(lt) = lt {
960922
// We don't need to check `alternate` since we can be certain that
961923
// the lifetime doesn't contain any characters which need escaping.
@@ -974,7 +936,7 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
974936
if !params.is_empty() {
975937
f.write_str(keyword)?;
976938
f.write_str(if f.alternate() { "<" } else { "&lt;" })?;
977-
comma_sep(params.iter().map(|lt| lt.print(cx)), true).fmt(f)?;
939+
params.iter().map(|lt| lt.print(cx)).format(", ").fmt(f)?;
978940
f.write_str(if f.alternate() { "> " } else { "&gt; " })?;
979941
}
980942
Ok(())
@@ -1025,9 +987,7 @@ fn fmt_type(
1025987
clean::Primitive(clean::PrimitiveType::Never) => {
1026988
primitive_link(f, PrimitiveType::Never, format_args!("!"), cx)
1027989
}
1028-
clean::Primitive(prim) => {
1029-
primitive_link(f, prim, format_args!("{}", prim.as_sym().as_str()), cx)
1030-
}
990+
clean::Primitive(prim) => primitive_link(f, prim, format_args!("{}", prim.as_sym()), cx),
1031991
clean::BareFunction(ref decl) => {
1032992
print_higher_ranked_params_with_space(&decl.generic_params, cx, "for").fmt(f)?;
1033993
decl.safety.print_with_space().fmt(f)?;
@@ -1067,18 +1027,13 @@ fn fmt_type(
10671027
primitive_link(
10681028
f,
10691029
PrimitiveType::Tuple,
1070-
format_args!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")),
1030+
format_args!("({})", generic_names.iter().format(", ")),
10711031
cx,
10721032
)
10731033
} else {
1074-
write!(f, "(")?;
1075-
for (i, item) in many.iter().enumerate() {
1076-
if i != 0 {
1077-
write!(f, ", ")?;
1078-
}
1079-
item.print(cx).fmt(f)?;
1080-
}
1081-
write!(f, ")")
1034+
f.write_str("(")?;
1035+
many.iter().map(|item| item.print(cx)).format(", ").fmt(f)?;
1036+
f.write_str(")")
10821037
}
10831038
}
10841039
},
@@ -1407,14 +1362,16 @@ impl clean::Arguments {
14071362
cx: &'a Context<'tcx>,
14081363
) -> impl Display + 'a + Captures<'tcx> {
14091364
fmt::from_fn(move |f| {
1410-
for (i, input) in self.values.iter().enumerate() {
1411-
write!(f, "{}: ", input.name)?;
1412-
input.type_.print(cx).fmt(f)?;
1413-
if i + 1 < self.values.len() {
1414-
write!(f, ", ")?;
1415-
}
1416-
}
1417-
Ok(())
1365+
self.values
1366+
.iter()
1367+
.map(|input| {
1368+
fmt::from_fn(|f| {
1369+
write!(f, "{}: ", input.name)?;
1370+
input.type_.print(cx).fmt(f)
1371+
})
1372+
})
1373+
.format(", ")
1374+
.fmt(f)
14181375
})
14191376
}
14201377
}
@@ -1714,12 +1671,7 @@ impl clean::ImportSource {
17141671
}
17151672
let name = self.path.last();
17161673
if let hir::def::Res::PrimTy(p) = self.path.res {
1717-
primitive_link(
1718-
f,
1719-
PrimitiveType::from(p),
1720-
format_args!("{}", name.as_str()),
1721-
cx,
1722-
)?;
1674+
primitive_link(f, PrimitiveType::from(p), format_args!("{name}"), cx)?;
17231675
} else {
17241676
f.write_str(name.as_str())?;
17251677
}

0 commit comments

Comments
 (0)