Auto merge of #135494 - yotamofek:rustdoc-fmt-from_fn, r=fmease
Refactor `fmt::Display` impls in rustdoc This PR does a couple of things, with the intention of cleaning up and streamlining some of the `fmt::Display` impls in rustdoc: 1. Use the unstable [`fmt::from_fn`](https://github.com/rust-lang/rust/issues/117729) instead of open-coding it. 2. ~~Replace bespoke implementations of `Itertools::format` with the method itself.~~ 4. Some more minor cleanups - DRY, remove unnecessary calls to `Symbol::as_str()`, replace some `format!()` calls with lazier options The changes are mostly cosmetic but some of them might have a slight positive effect on performance.
This commit is contained in:
commit
fc0094f8d4
10 changed files with 127 additions and 172 deletions
|
@ -389,6 +389,49 @@ fn write_with_opt_paren<T: fmt::Display>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
impl Display<'_> {
|
||||
fn display_sub_cfgs(
|
||||
&self,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
sub_cfgs: &[Cfg],
|
||||
separator: &str,
|
||||
) -> fmt::Result {
|
||||
let short_longhand = self.1.is_long() && {
|
||||
let all_crate_features =
|
||||
sub_cfgs.iter().all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_))));
|
||||
let all_target_features = sub_cfgs
|
||||
.iter()
|
||||
.all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::target_feature, Some(_))));
|
||||
|
||||
if all_crate_features {
|
||||
fmt.write_str("crate features ")?;
|
||||
true
|
||||
} else if all_target_features {
|
||||
fmt.write_str("target features ")?;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
for (i, sub_cfg) in sub_cfgs.iter().enumerate() {
|
||||
if i != 0 {
|
||||
fmt.write_str(separator)?;
|
||||
}
|
||||
if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) {
|
||||
if self.1.is_html() {
|
||||
write!(fmt, "<code>{feat}</code>")?;
|
||||
} else {
|
||||
write!(fmt, "`{feat}`")?;
|
||||
}
|
||||
} else {
|
||||
write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Display<'_> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self.0 {
|
||||
|
@ -408,79 +451,9 @@ impl fmt::Display for Display<'_> {
|
|||
|
||||
Cfg::Any(ref sub_cfgs) => {
|
||||
let separator = if sub_cfgs.iter().all(Cfg::is_simple) { " or " } else { ", or " };
|
||||
|
||||
let short_longhand = self.1.is_long() && {
|
||||
let all_crate_features = sub_cfgs
|
||||
.iter()
|
||||
.all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_))));
|
||||
let all_target_features = sub_cfgs
|
||||
.iter()
|
||||
.all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::target_feature, Some(_))));
|
||||
|
||||
if all_crate_features {
|
||||
fmt.write_str("crate features ")?;
|
||||
true
|
||||
} else if all_target_features {
|
||||
fmt.write_str("target features ")?;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
for (i, sub_cfg) in sub_cfgs.iter().enumerate() {
|
||||
if i != 0 {
|
||||
fmt.write_str(separator)?;
|
||||
}
|
||||
if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) {
|
||||
if self.1.is_html() {
|
||||
write!(fmt, "<code>{feat}</code>")?;
|
||||
} else {
|
||||
write!(fmt, "`{feat}`")?;
|
||||
}
|
||||
} else {
|
||||
write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Cfg::All(ref sub_cfgs) => {
|
||||
let short_longhand = self.1.is_long() && {
|
||||
let all_crate_features = sub_cfgs
|
||||
.iter()
|
||||
.all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_))));
|
||||
let all_target_features = sub_cfgs
|
||||
.iter()
|
||||
.all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::target_feature, Some(_))));
|
||||
|
||||
if all_crate_features {
|
||||
fmt.write_str("crate features ")?;
|
||||
true
|
||||
} else if all_target_features {
|
||||
fmt.write_str("target features ")?;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
for (i, sub_cfg) in sub_cfgs.iter().enumerate() {
|
||||
if i != 0 {
|
||||
fmt.write_str(" and ")?;
|
||||
}
|
||||
if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) {
|
||||
if self.1.is_html() {
|
||||
write!(fmt, "<code>{feat}</code>")?;
|
||||
} else {
|
||||
write!(fmt, "`{feat}`")?;
|
||||
}
|
||||
} else {
|
||||
write_with_opt_paren(fmt, !sub_cfg.is_simple(), Display(sub_cfg, self.1))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
self.display_sub_cfgs(fmt, sub_cfgs, separator)
|
||||
}
|
||||
Cfg::All(ref sub_cfgs) => self.display_sub_cfgs(fmt, sub_cfgs, " and "),
|
||||
|
||||
Cfg::True => fmt.write_str("everywhere"),
|
||||
Cfg::False => fmt.write_str("nowhere"),
|
||||
|
|
|
@ -150,8 +150,9 @@ pub(crate) fn comma_sep<T: Display>(
|
|||
items: impl Iterator<Item = T>,
|
||||
space_after_comma: bool,
|
||||
) -> impl Display {
|
||||
display_fn(move |f| {
|
||||
for (i, item) in items.enumerate() {
|
||||
let items = Cell::new(Some(items));
|
||||
fmt::from_fn(move |f| {
|
||||
for (i, item) in items.take().unwrap().enumerate() {
|
||||
if i != 0 {
|
||||
write!(f, ",{}", if space_after_comma { " " } else { "" })?;
|
||||
}
|
||||
|
@ -165,7 +166,7 @@ pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>(
|
|||
bounds: &'a [clean::GenericBound],
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let mut bounds_dup = FxHashSet::default();
|
||||
|
||||
for (i, bound) in bounds.iter().filter(|b| bounds_dup.insert(*b)).enumerate() {
|
||||
|
@ -183,7 +184,7 @@ impl clean::GenericParamDef {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| match &self.kind {
|
||||
fmt::from_fn(move |f| match &self.kind {
|
||||
clean::GenericParamDefKind::Lifetime { outlives } => {
|
||||
write!(f, "{}", self.name)?;
|
||||
|
||||
|
@ -238,7 +239,7 @@ impl clean::Generics {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
|
||||
if real_params.peek().is_none() {
|
||||
return Ok(());
|
||||
|
@ -268,12 +269,12 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
|
|||
indent: usize,
|
||||
ending: Ending,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let mut where_predicates = gens
|
||||
.where_predicates
|
||||
.iter()
|
||||
.map(|pred| {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
if f.alternate() {
|
||||
f.write_str(" ")?;
|
||||
} else {
|
||||
|
@ -376,17 +377,15 @@ impl clean::Lifetime {
|
|||
impl clean::ConstantKind {
|
||||
pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display + '_ {
|
||||
let expr = self.expr(tcx);
|
||||
display_fn(
|
||||
move |f| {
|
||||
if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) }
|
||||
},
|
||||
)
|
||||
fmt::from_fn(move |f| {
|
||||
if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl clean::PolyTrait {
|
||||
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?;
|
||||
self.trait_.print(cx).fmt(f)
|
||||
})
|
||||
|
@ -398,7 +397,7 @@ impl clean::GenericBound {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| match self {
|
||||
fmt::from_fn(move |f| match self {
|
||||
clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()),
|
||||
clean::GenericBound::TraitBound(ty, modifiers) => {
|
||||
// `const` and `~const` trait bounds are experimental; don't render them.
|
||||
|
@ -430,7 +429,7 @@ impl clean::GenericBound {
|
|||
|
||||
impl clean::GenericArgs {
|
||||
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
match self {
|
||||
clean::GenericArgs::AngleBracketed { args, constraints } => {
|
||||
if !args.is_empty() || !constraints.is_empty() {
|
||||
|
@ -950,7 +949,7 @@ fn tybounds<'a, 'tcx: 'a>(
|
|||
lt: &'a Option<clean::Lifetime>,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
for (i, bound) in bounds.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, " + ")?;
|
||||
|
@ -971,7 +970,7 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
|
|||
cx: &'a Context<'tcx>,
|
||||
keyword: &'static str,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
if !params.is_empty() {
|
||||
f.write_str(keyword)?;
|
||||
f.write_str(if f.alternate() { "<" } else { "<" })?;
|
||||
|
@ -982,13 +981,13 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn anchor<'a, 'cx: 'a>(
|
||||
pub(crate) fn anchor<'a: 'cx, 'cx>(
|
||||
did: DefId,
|
||||
text: Symbol,
|
||||
cx: &'cx Context<'_>,
|
||||
) -> impl Display + 'a {
|
||||
let parts = href(did, cx);
|
||||
display_fn(move |f| {
|
||||
cx: &'cx Context<'a>,
|
||||
) -> impl Display + Captures<'a> + 'cx {
|
||||
fmt::from_fn(move |f| {
|
||||
let parts = href(did, cx);
|
||||
if let Ok((url, short_ty, fqp)) = parts {
|
||||
write!(
|
||||
f,
|
||||
|
@ -1150,7 +1149,7 @@ fn fmt_type(
|
|||
}
|
||||
}
|
||||
clean::BorrowedRef { lifetime: ref l, mutability, type_: ref ty } => {
|
||||
let lt = display_fn(|f| match l {
|
||||
let lt = fmt::from_fn(|f| match l {
|
||||
Some(l) => write!(f, "{} ", l.print()),
|
||||
_ => Ok(()),
|
||||
});
|
||||
|
@ -1270,7 +1269,7 @@ impl clean::Type {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'b + Captures<'tcx> {
|
||||
display_fn(move |f| fmt_type(self, f, false, cx))
|
||||
fmt::from_fn(move |f| fmt_type(self, f, false, cx))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1279,7 +1278,7 @@ impl clean::Path {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'b + Captures<'tcx> {
|
||||
display_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
|
||||
fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1289,7 +1288,7 @@ impl clean::Impl {
|
|||
use_absolute: bool,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
f.write_str("impl")?;
|
||||
self.generics.print(cx).fmt(f)?;
|
||||
f.write_str(" ")?;
|
||||
|
@ -1407,7 +1406,7 @@ impl clean::Arguments {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
for (i, input) in self.values.iter().enumerate() {
|
||||
write!(f, "{}: ", input.name)?;
|
||||
input.type_.print(cx).fmt(f)?;
|
||||
|
@ -1447,7 +1446,7 @@ impl clean::FnDecl {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'b + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let ellipsis = if self.c_variadic { ", ..." } else { "" };
|
||||
if f.alternate() {
|
||||
write!(
|
||||
|
@ -1481,10 +1480,10 @@ impl clean::FnDecl {
|
|||
indent: usize,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
// First, generate the text form of the declaration, with no line wrapping, and count the bytes.
|
||||
let mut counter = WriteCounter(0);
|
||||
write!(&mut counter, "{:#}", display_fn(|f| { self.inner_full_print(None, f, cx) }))
|
||||
write!(&mut counter, "{:#}", fmt::from_fn(|f| { self.inner_full_print(None, f, cx) }))
|
||||
.unwrap();
|
||||
// If the text form was over 80 characters wide, we will line-wrap our output.
|
||||
let line_wrapping_indent =
|
||||
|
@ -1566,7 +1565,7 @@ impl clean::FnDecl {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| match &self.output {
|
||||
fmt::from_fn(move |f| match &self.output {
|
||||
clean::Tuple(tys) if tys.is_empty() => Ok(()),
|
||||
ty if f.alternate() => {
|
||||
write!(f, " -> {:#}", ty.print(cx))
|
||||
|
@ -1618,7 +1617,7 @@ pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
|
|||
};
|
||||
|
||||
let is_doc_hidden = item.is_doc_hidden();
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
if is_doc_hidden {
|
||||
f.write_str("#[doc(hidden)] ")?;
|
||||
}
|
||||
|
@ -1692,7 +1691,7 @@ impl clean::Import {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| match self.kind {
|
||||
fmt::from_fn(move |f| match self.kind {
|
||||
clean::ImportKind::Simple(name) => {
|
||||
if name == self.source.path.last() {
|
||||
write!(f, "use {};", self.source.print(cx))
|
||||
|
@ -1716,7 +1715,7 @@ impl clean::ImportSource {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| match self.did {
|
||||
fmt::from_fn(move |f| match self.did {
|
||||
Some(did) => resolved_path(f, did, &self.path, true, false, cx),
|
||||
_ => {
|
||||
for seg in &self.path.segments[..self.path.segments.len() - 1] {
|
||||
|
@ -1744,7 +1743,7 @@ impl clean::AssocItemConstraint {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
f.write_str(self.assoc.name.as_str())?;
|
||||
self.assoc.args.print(cx).fmt(f)?;
|
||||
match self.kind {
|
||||
|
@ -1765,7 +1764,7 @@ impl clean::AssocItemConstraint {
|
|||
}
|
||||
|
||||
pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let quot = if f.alternate() { "\"" } else { """ };
|
||||
match abi {
|
||||
ExternAbi::Rust => Ok(()),
|
||||
|
@ -1783,7 +1782,7 @@ impl clean::GenericArg {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| match self {
|
||||
fmt::from_fn(move |f| match self {
|
||||
clean::GenericArg::Lifetime(lt) => lt.print().fmt(f),
|
||||
clean::GenericArg::Type(ty) => ty.print(cx).fmt(f),
|
||||
clean::GenericArg::Const(ct) => ct.print(cx.tcx()).fmt(f),
|
||||
|
@ -1797,24 +1796,9 @@ impl clean::Term {
|
|||
&'a self,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| match self {
|
||||
fmt::from_fn(move |f| match self {
|
||||
clean::Term::Type(ty) => ty.print(cx).fmt(f),
|
||||
clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn display_fn(f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl Display {
|
||||
struct WithFormatter<F>(Cell<Option<F>>);
|
||||
|
||||
impl<F> Display for WithFormatter<F>
|
||||
where
|
||||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
(self.0.take()).unwrap()(f)
|
||||
}
|
||||
}
|
||||
|
||||
WithFormatter(Cell::new(Some(f)))
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ pub(super) fn write_code(
|
|||
out: &mut impl Write,
|
||||
src: &str,
|
||||
href_context: Option<HrefContext<'_, '_>>,
|
||||
decoration_info: Option<DecorationInfo>,
|
||||
decoration_info: Option<&DecorationInfo>,
|
||||
) {
|
||||
// This replace allows to fix how the code source with DOS backline characters is displayed.
|
||||
let src = src.replace("\r\n", "\n");
|
||||
|
@ -510,12 +510,12 @@ struct Decorations {
|
|||
}
|
||||
|
||||
impl Decorations {
|
||||
fn new(info: DecorationInfo) -> Self {
|
||||
fn new(info: &DecorationInfo) -> Self {
|
||||
// Extract tuples (start, end, kind) into separate sequences of (start, kind) and (end).
|
||||
let (mut starts, mut ends): (Vec<_>, Vec<_>) = info
|
||||
.0
|
||||
.into_iter()
|
||||
.flat_map(|(kind, ranges)| ranges.into_iter().map(move |(lo, hi)| ((lo, kind), hi)))
|
||||
.iter()
|
||||
.flat_map(|(&kind, ranges)| ranges.into_iter().map(move |&(lo, hi)| ((lo, kind), hi)))
|
||||
.unzip();
|
||||
|
||||
// Sort the sequences in document order.
|
||||
|
@ -542,7 +542,7 @@ struct Classifier<'src> {
|
|||
impl<'src> Classifier<'src> {
|
||||
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
|
||||
/// file span which will be used later on by the `span_correspondence_map`.
|
||||
fn new(src: &str, file_span: Span, decoration_info: Option<DecorationInfo>) -> Classifier<'_> {
|
||||
fn new(src: &'src str, file_span: Span, decoration_info: Option<&DecorationInfo>) -> Self {
|
||||
let tokens = PeekIter::new(TokenIter { src, cursor: Cursor::new(src) });
|
||||
let decorations = decoration_info.map(Decorations::new);
|
||||
Classifier {
|
||||
|
|
|
@ -78,7 +78,7 @@ let a = 4;";
|
|||
decorations.insert("example2", vec![(22, 32)]);
|
||||
|
||||
let mut html = Buffer::new();
|
||||
write_code(&mut html, src, None, Some(DecorationInfo(decorations)));
|
||||
write_code(&mut html, src, None, Some(&DecorationInfo(decorations)));
|
||||
expect_file!["fixtures/decorations.html"].assert_eq(&html.into_inner());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -69,9 +69,9 @@ use crate::formats::cache::Cache;
|
|||
use crate::formats::item_type::ItemType;
|
||||
use crate::html::escape::Escape;
|
||||
use crate::html::format::{
|
||||
Buffer, Ending, HrefError, PrintWithSpace, display_fn, href, join_with_double_colon,
|
||||
print_abi_with_space, print_constness_with_space, print_default_space, print_generic_bounds,
|
||||
print_where_clause, visibility_print_with_space,
|
||||
Buffer, Ending, HrefError, PrintWithSpace, href, join_with_double_colon, print_abi_with_space,
|
||||
print_constness_with_space, print_default_space, print_generic_bounds, print_where_clause,
|
||||
visibility_print_with_space,
|
||||
};
|
||||
use crate::html::markdown::{
|
||||
HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine,
|
||||
|
@ -82,13 +82,14 @@ use crate::scrape_examples::{CallData, CallLocation};
|
|||
use crate::{DOC_RUST_LANG_ORG_CHANNEL, try_none};
|
||||
|
||||
pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
|
||||
crate::html::format::display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) }
|
||||
})
|
||||
}
|
||||
|
||||
/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
|
||||
/// impl.
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) enum AssocItemRender<'a> {
|
||||
All,
|
||||
DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
|
||||
|
@ -309,9 +310,7 @@ impl ItemEntry {
|
|||
|
||||
impl ItemEntry {
|
||||
pub(crate) fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate::html::format::display_fn(move |f| {
|
||||
write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name))
|
||||
})
|
||||
fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,7 +512,7 @@ fn document<'a, 'cx: 'a>(
|
|||
info!("Documenting {name}");
|
||||
}
|
||||
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
document_item_info(cx, item, parent).render_into(f).unwrap();
|
||||
if parent.is_none() {
|
||||
write!(f, "{}", document_full_collapsible(item, cx, heading_offset))
|
||||
|
@ -530,7 +529,7 @@ fn render_markdown<'a, 'cx: 'a>(
|
|||
links: Vec<RenderedLink>,
|
||||
heading_offset: HeadingOffset,
|
||||
) -> impl fmt::Display + 'a + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
write!(
|
||||
f,
|
||||
"<div class=\"docblock\">{}</div>",
|
||||
|
@ -557,7 +556,7 @@ fn document_short<'a, 'cx: 'a>(
|
|||
parent: &'a clean::Item,
|
||||
show_def_docs: bool,
|
||||
) -> impl fmt::Display + 'a + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
document_item_info(cx, item, Some(parent)).render_into(f).unwrap();
|
||||
if !show_def_docs {
|
||||
return Ok(());
|
||||
|
@ -605,7 +604,7 @@ fn document_full_inner<'a, 'cx: 'a>(
|
|||
is_collapsible: bool,
|
||||
heading_offset: HeadingOffset,
|
||||
) -> impl fmt::Display + 'a + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
if let Some(s) = item.opt_doc_value() {
|
||||
debug!("Doc block: =====\n{s}\n=====");
|
||||
if is_collapsible {
|
||||
|
@ -1159,7 +1158,7 @@ fn render_attributes_in_pre<'a, 'tcx: 'a>(
|
|||
prefix: &'a str,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> impl fmt::Display + Captures<'a> + Captures<'tcx> {
|
||||
crate::html::format::display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
for a in it.attributes(cx.tcx(), cx.cache(), false) {
|
||||
writeln!(f, "{prefix}{a}")?;
|
||||
}
|
||||
|
@ -1256,9 +1255,9 @@ fn render_assoc_items<'a, 'cx: 'a>(
|
|||
it: DefId,
|
||||
what: AssocItemRender<'a>,
|
||||
) -> impl fmt::Display + 'a + Captures<'cx> {
|
||||
let mut derefs = DefIdSet::default();
|
||||
derefs.insert(it);
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let mut derefs = DefIdSet::default();
|
||||
derefs.insert(it);
|
||||
render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs);
|
||||
Ok(())
|
||||
})
|
||||
|
@ -2577,7 +2576,7 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &Context<'_>, item: &clean
|
|||
file_span,
|
||||
cx,
|
||||
&cx.root_path(),
|
||||
highlight::DecorationInfo(decoration_info),
|
||||
&highlight::DecorationInfo(decoration_info),
|
||||
sources::SourceContext::Embedded(sources::ScrapedInfo {
|
||||
needs_expansion,
|
||||
offset: line_min,
|
||||
|
|
|
@ -30,7 +30,7 @@ use crate::formats::Impl;
|
|||
use crate::formats::item_type::ItemType;
|
||||
use crate::html::escape::{Escape, EscapeBodyTextWithWbr};
|
||||
use crate::html::format::{
|
||||
Buffer, Ending, PrintWithSpace, display_fn, join_with_double_colon, print_abi_with_space,
|
||||
Buffer, Ending, PrintWithSpace, join_with_double_colon, print_abi_with_space,
|
||||
print_constness_with_space, print_where_clause, visibility_print_with_space,
|
||||
};
|
||||
use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
|
||||
|
@ -92,7 +92,7 @@ macro_rules! item_template_methods {
|
|||
() => {};
|
||||
(document $($rest:tt)*) => {
|
||||
fn document<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let (item, cx) = self.item_and_cx();
|
||||
let v = document(cx, item, None, HeadingOffset::H2);
|
||||
write!(f, "{v}")
|
||||
|
@ -102,7 +102,7 @@ macro_rules! item_template_methods {
|
|||
};
|
||||
(document_type_layout $($rest:tt)*) => {
|
||||
fn document_type_layout<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let (item, cx) = self.item_and_cx();
|
||||
let def_id = item.item_id.expect_def_id();
|
||||
let v = document_type_layout(cx, def_id);
|
||||
|
@ -113,7 +113,7 @@ macro_rules! item_template_methods {
|
|||
};
|
||||
(render_attributes_in_pre $($rest:tt)*) => {
|
||||
fn render_attributes_in_pre<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let (item, cx) = self.item_and_cx();
|
||||
let v = render_attributes_in_pre(item, "", cx);
|
||||
write!(f, "{v}")
|
||||
|
@ -123,7 +123,7 @@ macro_rules! item_template_methods {
|
|||
};
|
||||
(render_assoc_items $($rest:tt)*) => {
|
||||
fn render_assoc_items<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let (item, cx) = self.item_and_cx();
|
||||
let def_id = item.item_id.expect_def_id();
|
||||
let v = render_assoc_items(cx, item, def_id, AssocItemRender::All);
|
||||
|
@ -520,13 +520,13 @@ fn extra_info_tags<'a, 'tcx: 'a>(
|
|||
parent: &'a clean::Item,
|
||||
import_def_id: Option<DefId>,
|
||||
) -> impl fmt::Display + 'a + Captures<'tcx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
fn tag_html<'a>(
|
||||
class: &'a str,
|
||||
title: &'a str,
|
||||
contents: &'a str,
|
||||
) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
write!(
|
||||
f,
|
||||
r#"<wbr><span class="stab {class}" title="{title}">{contents}</span>"#,
|
||||
|
@ -1375,7 +1375,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
|
|||
|
||||
impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
|
||||
fn render_union<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let v = render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
|
@ -1385,7 +1385,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
|
|||
&'b self,
|
||||
field: &'a clean::Item,
|
||||
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let v = document(self.cx, field, Some(self.it), HeadingOffset::H3);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
|
@ -1399,7 +1399,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
|
|||
&'b self,
|
||||
ty: &'a clean::Type,
|
||||
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
let v = ty.print(self.cx);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
|
@ -1426,7 +1426,7 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>(
|
|||
cx: &'a Context<'cx>,
|
||||
s: &'a [clean::Item],
|
||||
) -> impl fmt::Display + 'a + Captures<'cx> {
|
||||
display_fn(|f| {
|
||||
fmt::from_fn(|f| {
|
||||
if !s.is_empty()
|
||||
&& s.iter().all(|field| {
|
||||
matches!(field.kind, clean::StrippedItem(box clean::StructFieldItem(..)))
|
||||
|
@ -2151,7 +2151,7 @@ fn render_union<'a, 'cx: 'a>(
|
|||
fields: &'a [clean::Item],
|
||||
cx: &'a Context<'cx>,
|
||||
) -> impl fmt::Display + 'a + Captures<'cx> {
|
||||
display_fn(move |mut f| {
|
||||
fmt::from_fn(move |mut f| {
|
||||
write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?;
|
||||
|
||||
let where_displayed = g
|
||||
|
@ -2331,7 +2331,7 @@ fn document_non_exhaustive_header(item: &clean::Item) -> &str {
|
|||
}
|
||||
|
||||
fn document_non_exhaustive(item: &clean::Item) -> impl fmt::Display + '_ {
|
||||
display_fn(|f| {
|
||||
fmt::from_fn(|f| {
|
||||
if item.is_non_exhaustive() {
|
||||
write!(
|
||||
f,
|
||||
|
|
|
@ -100,18 +100,17 @@ impl<'a> Link<'a> {
|
|||
}
|
||||
|
||||
pub(crate) mod filters {
|
||||
use std::fmt::Display;
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
use rinja::filters::Safe;
|
||||
|
||||
use crate::html::escape::EscapeBodyTextWithWbr;
|
||||
use crate::html::render::display_fn;
|
||||
pub(crate) fn wrapped<T>(v: T) -> rinja::Result<Safe<impl Display>>
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
let string = v.to_string();
|
||||
Ok(Safe(display_fn(move |f| EscapeBodyTextWithWbr(&string).fmt(f))))
|
||||
Ok(Safe(fmt::from_fn(move |f| EscapeBodyTextWithWbr(&string).fmt(f))))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ use rustc_middle::ty::layout::LayoutError;
|
|||
use rustc_middle::ty::{self};
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
||||
use crate::html::format::display_fn;
|
||||
use crate::html::render::Context;
|
||||
|
||||
#[derive(Template)]
|
||||
|
@ -31,7 +30,7 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>(
|
|||
cx: &'a Context<'cx>,
|
||||
ty_def_id: DefId,
|
||||
) -> impl fmt::Display + 'a + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
fmt::from_fn(move |f| {
|
||||
if !cx.shared.show_type_layout {
|
||||
return Ok(());
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::clean::utils::has_doc_flag;
|
|||
use crate::docfs::PathError;
|
||||
use crate::error::Error;
|
||||
use crate::html::render::Context;
|
||||
use crate::html::{format, highlight, layout};
|
||||
use crate::html::{highlight, layout};
|
||||
use crate::visit::DocVisitor;
|
||||
|
||||
pub(crate) fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), Error> {
|
||||
|
@ -249,7 +249,7 @@ impl SourceCollector<'_, '_> {
|
|||
file_span,
|
||||
self.cx,
|
||||
&root_path,
|
||||
highlight::DecorationInfo::default(),
|
||||
&highlight::DecorationInfo::default(),
|
||||
SourceContext::Standalone { file_path },
|
||||
)
|
||||
},
|
||||
|
@ -328,13 +328,13 @@ pub(crate) fn print_src(
|
|||
file_span: rustc_span::Span,
|
||||
context: &Context<'_>,
|
||||
root_path: &str,
|
||||
decoration_info: highlight::DecorationInfo,
|
||||
decoration_info: &highlight::DecorationInfo,
|
||||
source_context: SourceContext<'_>,
|
||||
) {
|
||||
let current_href = context
|
||||
.href_from_span(clean::Span::new(file_span), false)
|
||||
.expect("only local crates should have sources emitted");
|
||||
let code = format::display_fn(move |fmt| {
|
||||
let code = fmt::from_fn(move |fmt| {
|
||||
let current_href = context
|
||||
.href_from_span(clean::Span::new(file_span), false)
|
||||
.expect("only local crates should have sources emitted");
|
||||
highlight::write_code(
|
||||
fmt,
|
||||
s,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(file_buffered)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue