fmt-rfcs
fmt-rfcs copied to clipboard
Closures with complex arguments
In #35 the discussion was mainly about how we format the body of closures. Currently rustfmt uses visual indent when we need to use multiple lines for closure's arguments:
fn examples() {
let commented = |// first
a, // argument
// second
b: WithType, // argument
// ignored
_| {
(a, b)
};
let block_body = move |xxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
ref yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy| {
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
};
let y = x.into_iter().map(
|AaaaaaAaaaaaaaaaa {
bbbbbb_bbbb,
ccc_ccccccc,
}| (),
);
}
Since the default indent style in other places is block indent, I was wondering where rustfmt should use it in closure's arguments as well:
fn examples() {
let y = x.into_iter().map(
|
AaaaaaAaaaaaaaaaa {
bbbbbb_bbbb,
ccc_ccccccc,
},
| (),
);
let commented = |
// first
a, // argument
// second
b: WithType, // argument
// ignored
_,
| {
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
)
};
let block_body = move |
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
ref yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,
| {
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
};
}
Any thoughts?
Figuring out how to format closures has been driving me slightly bonkers. And vim doesn't have any appreciation for visually indenting the arguments. Treating them as a fn item declaration may be the sanest approach, and would be consistent with the rest of Rust. It'd be nice if they just had a more compliant syntax, but that ship has already sailed, sunken off the coast of Costa Rica, and been salvaged as a source for metal free from the radioactive contamination of nuclear testing.
With my format team hat on: I do think we should use block style for closures. I also think we should treat the leading | and trailing | -> Type the same way we treat other grouping, so that we can put the | on the same line as the start of a function accepting the closure as an argument.
Would someone be up for writing a PR for the style guide?
The current style can have a disgusting result:
let read = move |mut conn: DbConn<'a>,
(post_id, my_person_id, is_mod_or_admin): (
PostId,
Option<PersonId>,
Option<bool>,
)| async move {
I don't think that's consistent with the style guide, or at least I don't know what rule would produce that result.
cc @rust-lang/rustfmt
The current style can have a disgusting result:
let read = move |mut conn: DbConn<'a>, (post_id, my_person_id, is_mod_or_admin): ( PostId, Option<PersonId>, Option<bool>, )| async move {
This is due to a very long standing bug in rustfmt and as Josh noted, does not adhere to the style guide prescriptions for closures
https://github.com/rust-lang/rustfmt/issues/3865
This issue has been bugging me too. Anyone working on it?
I wonder if a separate option should be added (like imports_indent) or should indent_style be extended for closures too? The former might be preferable for backwards-compatibility.