Skip to content

Commit 1a30ed9

Browse files
committed
Auto merge of #157874 - yotamofek:pr/rustdoc/more-lazy-formatting, r=GuillaumeGomez
rustdoc: Cleanup and (micro-)optimize `print_where_clause` Remove a bunch of allocations, and also make the code slightly easier to follow. r? @GuillaumeGomez , as usual :)
2 parents 4f8ea98 + a6b8cfa commit 1a30ed9

2 files changed

Lines changed: 52 additions & 52 deletions

File tree

src/librustdoc/display.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,13 @@ impl WithOpts {
130130
})
131131
}
132132
}
133+
134+
/// Creates a [`Display`] implementation that repeats `t` `count` times.
135+
pub(crate) fn repeat(t: impl Display, count: usize) -> impl Display {
136+
fmt::from_fn(move |f| {
137+
for _ in 0..count {
138+
t.fmt(f)?;
139+
}
140+
Ok(())
141+
})
142+
}

src/librustdoc/html/format.rs

Lines changed: 42 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use tracing::{debug, trace};
2727
use super::url_parts_builder::UrlPartsBuilder;
2828
use crate::clean::types::ExternalLocation;
2929
use crate::clean::utils::find_nearest_parent_module;
30-
use crate::clean::{self, ExternalCrate, PrimitiveType};
30+
use crate::clean::{self, ExternalCrate, PrimitiveType, WherePredicate};
3131
use crate::display::{Joined as _, MaybeDisplay as _, WithOpts, Wrapped};
3232
use crate::formats::cache::Cache;
3333
use crate::formats::item_type::ItemType;
@@ -164,69 +164,59 @@ pub(crate) fn print_where_clause(
164164
return None;
165165
}
166166

167-
Some(fmt::from_fn(move |f| {
168-
let where_preds = fmt::from_fn(|f| {
169-
gens.where_predicates
170-
.iter()
171-
.map(|predicate| {
172-
fmt::from_fn(|f| {
173-
if f.alternate() {
174-
f.write_str(" ")?;
175-
} else {
176-
f.write_str("\n")?;
177-
}
178-
print_where_predicate(predicate, cx).fmt(f)
179-
})
180-
})
181-
.joined(",", f)
182-
});
167+
fn where_preds(
168+
predicates: &[WherePredicate],
169+
cx: &Context<'_>,
170+
sep: impl Display,
171+
) -> impl Display {
172+
fmt::from_fn(move |f| {
173+
predicates.iter().map(|predicate| print_where_predicate(predicate, cx)).joined(&sep, f)
174+
})
175+
}
176+
177+
let spaces = |n: usize| crate::display::repeat(' ', n);
183178

184-
let clause = if f.alternate() {
179+
Some(fmt::from_fn(move |f| {
180+
if f.alternate() {
181+
write!(f, " where {:#}", where_preds(&gens.where_predicates, cx, ", "))?;
185182
if ending == Ending::Newline {
186-
format!(" where{where_preds:#},")
187-
} else {
188-
format!(" where{where_preds:#}")
183+
f.write_char(',')?;
189184
}
190-
} else {
191-
let mut br_with_padding = String::with_capacity(6 * indent + 28);
192-
br_with_padding.push('\n');
185+
return Ok(());
186+
}
193187

194-
let where_indent = 3;
188+
const WHERE_INDENT: usize = 3;
189+
190+
let padding = {
195191
let padding_amount = if ending == Ending::Newline {
196192
indent + 4
197193
} else if indent == 0 {
198194
4
199195
} else {
200-
indent + where_indent + "where ".len()
196+
indent + WHERE_INDENT + "where ".len()
201197
};
198+
spaces(padding_amount)
199+
};
202200

203-
for _ in 0..padding_amount {
204-
br_with_padding.push(' ');
205-
}
206-
let where_preds = where_preds.to_string().replace('\n', &br_with_padding);
207-
208-
if ending == Ending::Newline {
209-
let mut clause = " ".repeat(indent.saturating_sub(1));
210-
write!(clause, "<div class=\"where\">where{where_preds},</div>")?;
211-
clause
212-
} else {
213-
// insert a newline after a single space but before multiple spaces at the start
214-
if indent == 0 {
215-
format!("\n<span class=\"where\">where{where_preds}</span>")
216-
} else {
217-
// put the first one on the same line as the 'where' keyword
218-
let where_preds = where_preds.replacen(&br_with_padding, " ", 1);
219-
220-
let mut clause = br_with_padding;
221-
// +1 is for `\n`.
222-
clause.truncate(indent + 1 + where_indent);
201+
let br_with_padding = format_args!("\n{padding}");
202+
let sep = format_args!(",{br_with_padding}");
203+
let where_preds = where_preds(&gens.where_predicates, cx, sep);
223204

224-
write!(clause, "<span class=\"where\">where{where_preds}</span>")?;
225-
clause
226-
}
227-
}
228-
};
229-
write!(f, "{clause}")
205+
if ending == Ending::Newline {
206+
write!(
207+
f,
208+
"{indent}<div class=\"where\">where{br_with_padding}{where_preds},</div>",
209+
indent = spaces(indent.saturating_sub(1)),
210+
)
211+
} else if indent == 0 {
212+
write!(f, "\n<span class=\"where\">where{br_with_padding}{where_preds}</span>")
213+
} else {
214+
write!(
215+
f,
216+
"\n{indent}<span class=\"where\">where {where_preds}</span>",
217+
indent = spaces(indent + WHERE_INDENT),
218+
)
219+
}
230220
}))
231221
}
232222

0 commit comments

Comments
 (0)