Rollup merge of #146645 - yotamofek:pr/rustdoc/fndecl_inner_full_print, r=fmease

Cleanup `FnDecl::inner_full_print`

`inner_full_print` was pretty hard to follow IMHO.
Hopefully this cleans it up a little bit.

Also, it was checking whether `self.inputs` is empty twice, and then handling an unreachable match arm:
f836ae4e66/src/librustdoc/html/format.rs (L1368C1-L1368C33)
`last_input_index` could only be `None` if the fn has no parameters, in which case the loop body would never run.

r? ``@GuillaumeGomez`` if you have the capacity :)

BTW, can we rename `FnDecl::inputs` to `parameters` or something? And `output` to `return_ty`?
This commit is contained in:
Stuart Cook 2025-09-18 11:48:50 +10:00 committed by GitHub
commit 34a805b0f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 63 additions and 52 deletions

View file

@ -10,7 +10,7 @@ pub(crate) trait Joined: IntoIterator {
///
/// The performance of `joined` is slightly better than `format`, since it doesn't need to use a `Cell` to keep track of whether [`fmt`](Display::fmt)
/// was already called (`joined`'s API doesn't allow it be called more than once).
fn joined(self, sep: &str, f: &mut Formatter<'_>) -> fmt::Result;
fn joined(self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result;
}
impl<I, T> Joined for I
@ -18,12 +18,12 @@ where
I: IntoIterator<Item = T>,
T: Display,
{
fn joined(self, sep: &str, f: &mut Formatter<'_>) -> fmt::Result {
fn joined(self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result {
let mut iter = self.into_iter();
let Some(first) = iter.next() else { return Ok(()) };
first.fmt(f)?;
for item in iter {
f.write_str(sep)?;
sep.fmt(f)?;
item.fmt(f)?;
}
Ok(())

View file

@ -1264,6 +1264,7 @@ impl std::fmt::Write for WriteCounter {
}
// Implements Display by emitting the given number of spaces.
#[derive(Clone, Copy)]
struct Indent(usize);
impl Display for Indent {
@ -1275,6 +1276,37 @@ impl Display for Indent {
}
}
impl clean::Parameter {
fn print(&self, cx: &Context<'_>) -> impl fmt::Display {
fmt::from_fn(move |f| {
if let Some(self_ty) = self.to_receiver() {
match self_ty {
clean::SelfTy => f.write_str("self"),
clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
f.write_str(if f.alternate() { "&" } else { "&amp;" })?;
if let Some(lt) = lifetime {
write!(f, "{lt} ", lt = lt.print())?;
}
write!(f, "{mutability}self", mutability = mutability.print_with_space())
}
_ => {
f.write_str("self: ")?;
self_ty.print(cx).fmt(f)
}
}
} else {
if self.is_const {
write!(f, "const ")?;
}
if let Some(name) = self.name {
write!(f, "{name}: ")?;
}
self.type_.print(cx).fmt(f)
}
})
}
}
impl clean::FnDecl {
pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
@ -1333,63 +1365,42 @@ impl clean::FnDecl {
f: &mut fmt::Formatter<'_>,
cx: &Context<'_>,
) -> fmt::Result {
let amp = if f.alternate() { "&" } else { "&amp;" };
f.write_char('(')?;
write!(f, "(")?;
if let Some(n) = line_wrapping_indent
&& !self.inputs.is_empty()
{
write!(f, "\n{}", Indent(n + 4))?;
}
if !self.inputs.is_empty() {
let line_wrapping_indent = line_wrapping_indent.map(|n| Indent(n + 4));
let last_input_index = self.inputs.len().checked_sub(1);
for (i, param) in self.inputs.iter().enumerate() {
if let Some(selfty) = param.to_receiver() {
match selfty {
clean::SelfTy => {
write!(f, "self")?;
}
clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
write!(f, "{amp}")?;
if let Some(lt) = lifetime {
write!(f, "{lt} ", lt = lt.print())?;
}
write!(f, "{mutability}self", mutability = mutability.print_with_space())?;
}
_ => {
write!(f, "self: ")?;
selfty.print(cx).fmt(f)?;
}
}
} else {
if param.is_const {
write!(f, "const ")?;
}
if let Some(name) = param.name {
write!(f, "{name}: ")?;
}
param.type_.print(cx).fmt(f)?;
if let Some(indent) = line_wrapping_indent {
write!(f, "\n{indent}")?;
}
match (line_wrapping_indent, last_input_index) {
(_, None) => (),
(None, Some(last_i)) if i != last_i => write!(f, ", ")?,
(None, Some(_)) => (),
(Some(n), Some(last_i)) if i != last_i => write!(f, ",\n{}", Indent(n + 4))?,
(Some(_), Some(_)) => writeln!(f, ",")?,
let sep = fmt::from_fn(|f| {
if let Some(indent) = line_wrapping_indent {
write!(f, ",\n{indent}")
} else {
f.write_str(", ")
}
});
self.inputs.iter().map(|param| param.print(cx)).joined(sep, f)?;
if line_wrapping_indent.is_some() {
writeln!(f, ",")?
}
if self.c_variadic {
match line_wrapping_indent {
None => write!(f, ", ...")?,
Some(indent) => writeln!(f, "{indent}...")?,
};
}
}
if self.c_variadic {
match line_wrapping_indent {
None => write!(f, ", ...")?,
Some(n) => writeln!(f, "{}...", Indent(n + 4))?,
};
if let Some(n) = line_wrapping_indent {
write!(f, "{}", Indent(n))?
}
match line_wrapping_indent {
None => write!(f, ")")?,
Some(n) => write!(f, "{})", Indent(n))?,
};
f.write_char(')')?;
self.print_output(cx).fmt(f)
}