Skip to content

Changes for #4394 - Support preserving block wrapping of closure bodies #4519

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -1836,6 +1836,33 @@ fn say_hi() {
}
```

## `preserve_closure_block_wrapping`

Preserves block wraping arround closures. For example, useful when the closure `||` can be
confused with OR.

- **Default value**: `false`
- **Possible values**: `true`, `false`
- **Stable**: No

#### `true`:
Original block wrapping is preserved:
```rust
fn main() {
let explicit_conversion_preserves_semantics =
|| { !is_mod || (is_mod && attrs.map_or(true, |a| a.is_empty())) };
}
```

#### `false` (default):
Block is not preserved:
```rust
fn main() {
let explicit_conversion_preserves_semantics =
|| !is_mod || (is_mod && attrs.map_or(true, |a| a.is_empty()));
}
```

## `overflow_delimited_expr`

When structs, slices, arrays, and block/array-like macros are used as the last
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ create_config! {
format_generated_files: bool, false, false, "Format generated files";
preserve_block_start_blank_lines: bool, false, false, "Preserve blank lines at the start of \
blocks.";
preserve_closure_block_wrapping: bool, false , false, "Preserve block wrapping around closures";

// Options that can change the source code beyond whitespace/blocks (somewhat linty things)
merge_derives: bool, true, true, "Merge multiple `#[derive(...)]` into a single one";
Expand Down Expand Up @@ -623,6 +624,7 @@ edition = "2018"
inline_attribute_width = 0
format_generated_files = false
preserve_block_start_blank_lines = false
preserve_closure_block_wrapping = false
merge_derives = true
use_try_shorthand = false
use_field_init_shorthand = false
Expand Down
13 changes: 12 additions & 1 deletion src/formatting/closures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,19 @@ pub(crate) fn rewrite_closure(
.map(|s| format!("{} {}", prefix, s));
}

// Whether a closure block wrapping may not be preserved (#4394).
let can_try_rewrite_without_block = if context.inside_macro() {
false
} else if context.config.preserve_closure_block_wrapping()
&& context.snippet(body.span).trim_start().starts_with('{')
{
false
} else {
true
};

let result = match fn_decl.output {
ast::FnRetTy::Default(_) if !context.inside_macro() => {
ast::FnRetTy::Default(_) if can_try_rewrite_without_block => {
try_rewrite_without_block(body, &prefix, capture, context, shape, body_shape)
}
_ => None,
Expand Down
32 changes: 32 additions & 0 deletions tests/source/preserve_closure_block_wrapping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// rustfmt-preserve_closure_block_wrapping: true

fn main() {
let explicit_conversion_preserves_semantics =
|| { !is_mod || (is_mod && attrs.map_or(true, |a| a.is_empty())) };
}

fn main() {
|| {{}};
}

fn issue1524() {
let f = |x| {{{{x}}}};
let f = |x| {{{x}}};
let f = |x| {{x}};
let f = |x| {x};
let f = |x| x;
}

fn main() {
let arg_test2 = |big_argument_name, test123| {looooooooooooooooooong_function_naaaaaaaaaaaaaaaaame()};
}

impl Foo {
pub fn bar(&self) {
Some(SomeType {
push_closure_out_to_100_chars: iter(otherwise_it_works_ok.into_iter().map(|f| {
Ok(f)
})),
})
}
}
45 changes: 45 additions & 0 deletions tests/target/preserve_closure_block_wrapping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// rustfmt-preserve_closure_block_wrapping: true

fn main() {
let explicit_conversion_preserves_semantics =
|| { !is_mod || (is_mod && attrs.map_or(true, |a| a.is_empty())) };
}

fn main() {
|| { {} };
}

fn issue1524() {
let f = |x| {
{
{
{ x }
}
}
};
let f = |x| {
{
{ x }
}
};
let f = |x| {
{ x }
};
let f = |x| { x };
let f = |x| x;
}

fn main() {
let arg_test2 =
|big_argument_name, test123| { looooooooooooooooooong_function_naaaaaaaaaaaaaaaaame() };
}

impl Foo {
pub fn bar(&self) {
Some(SomeType {
push_closure_out_to_100_chars: iter(
otherwise_it_works_ok.into_iter().map(|f| { Ok(f) }),
),
})
}
}