diff --git a/Configurations.md b/Configurations.md index ac5747800b2..fd93ac65694 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2528,6 +2528,61 @@ fn lorem(t : T) { See also: [`space_after_colon`](#space_after_colon). +## `spaces_within_parenthesized_items` + +Put one space after '(' and before ')' on parenthesized items. +Note that spaces are not added within grouping parentheses. + +- **Default value**: `false` +- **Possible values**: `true`, `false` +- **Stable**: No + +#### `false` (default): + +```rust +#[cfg(test)] +fn lorem() {} + +fn lorem(ipsum: usize, dolor: usize) -> i32 { + println!("ipsum!"); + bar(); + foo(1, 2, 3); + let (x, y) = (1, 2); + (1 * ((2 + 3) * 4)) // grouping parentheses +} + +pub(crate) type Bar = fn(i32, i32) -> (); + +struct Dummy; + +impl Foo for Dummy { + fn lorem(self, ipsum: usize, dolor: usize) {} +} +``` + +#### `true`: + +```rust +#[cfg( test )] +fn lorem() {} + +fn lorem( ipsum: usize, dolor: usize ) -> i32 { + println!( "ipsum!" ); + bar(); + foo( 1, 2, 3 ); + let ( x, y ) = ( 1, 2 ); + (1 * ((2 + 3) * 4)) // grouping parentheses +} + +pub(crate) type Bar = fn( i32, i32 ) -> (); + +struct Dummy; + +impl Foo for Dummy { + fn lorem( self, ipsum: usize, dolor: usize ) {} +} +``` + ## `spaces_around_ranges` Put spaces around the .., ..=, and ... range operators @@ -3132,4 +3187,4 @@ Internal option, use `--backup` ## `print_misformatted_file_names` -Internal option, use `-l` or `--files-with-diff` +Internal option, use `-l` or `--files-with-diff` \ No newline at end of file diff --git a/src/config/mod.rs b/src/config/mod.rs index 6f41b299e87..69b26f481fa 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -110,6 +110,8 @@ create_config! { spaces_around_ranges: bool, false, false, "Put spaces around the .. and ..= range operators"; binop_separator: SeparatorPlace, SeparatorPlace::Front, false, "Where to put a binary operator when a binary expression goes multiline"; + spaces_within_parenthesized_items: bool, false, false, + "Put one space after '(' and before ')' on parenthesized items"; // Misc. remove_nested_parens: bool, true, true, "Remove nested parens"; @@ -653,6 +655,7 @@ space_before_colon = false space_after_colon = true spaces_around_ranges = false binop_separator = "Front" +spaces_within_parenthesized_items = false remove_nested_parens = true combine_control_expr = true short_array_element_width_threshold = 10 diff --git a/src/items.rs b/src/items.rs index fd4e08ed403..4e790e80309 100644 --- a/src/items.rs +++ b/src/items.rs @@ -2324,13 +2324,22 @@ fn rewrite_fn_base( result.push_str("fn "); // Generics. - let overhead = if let FnBraceStyle::SameLine = fn_brace_style { + let mut overhead = if let FnBraceStyle::SameLine = fn_brace_style { // 4 = `() {` 4 } else { // 2 = `()` 2 }; + + let can_have_spaces_within_parentheses = + context.config.spaces_within_parenthesized_items() && !fn_sig.decl.inputs.is_empty(); + + overhead += if can_have_spaces_within_parentheses { + 2 + } else { + 0 + }; let used_width = last_line_used_width(&result, indent.width()); let one_line_budget = context.budget(used_width + overhead); let shape = Shape { @@ -2425,6 +2434,9 @@ fn rewrite_fn_base( result.push_str(&indent.to_string_with_newline(context.config)); result.push(')'); } else { + if can_have_spaces_within_parentheses { + result.push(' '); + } result.push_str(¶m_str); let used_width = last_line_used_width(&result, indent.width()) + first_line_width(&ret_str); // Put the closing brace on the next line if it overflows the max width. @@ -2448,11 +2460,16 @@ fn rewrite_fn_base( result.push(')'); no_params_and_over_max_width = true; } else { + if can_have_spaces_within_parentheses { + result.push(' '); + } result.push(')'); } } else { if closing_paren_overflow_max_width || params_last_line_contains_comment { result.push_str(&indent.to_string_with_newline(context.config)); + } else if can_have_spaces_within_parentheses { + result.push(' '); } result.push(')'); } diff --git a/src/overflow.rs b/src/overflow.rs index d81bf24dbd1..195be023187 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -658,21 +658,48 @@ impl<'a> Context<'a> { .block() .indent .to_string_with_newline(self.context.config); + + let can_have_spaces_within_parenthesis = !items_str.is_empty() + && self.context.config.spaces_within_parenthesized_items() + && prefix == "(" + && suffix == ")"; + + let num_spaces_within_parenthesis = if can_have_spaces_within_parenthesis { + 2 + } else { + 0 + }; + let mut result = String::with_capacity( - self.ident.len() + items_str.len() + 2 + indent_str.len() + nested_indent_str.len(), + self.ident.len() + + items_str.len() + + 2 + + indent_str.len() + + nested_indent_str.len() + + num_spaces_within_parenthesis, ); + result.push_str(self.ident); result.push_str(prefix); let force_single_line = if self.context.config.version() == Version::Two { !self.context.use_block_indent() || (is_extendable && extend_width <= shape.width) } else { + let fits_one_line = if can_have_spaces_within_parenthesis { + items_str.len() + 4 <= shape.width // 2 = `()` - let fits_one_line = items_str.len() + 2 <= shape.width; + } else { + items_str.len() + 2 <= shape.width + }; + !self.context.use_block_indent() || (self.context.inside_macro() && !items_str.contains('\n') && fits_one_line) || (is_extendable && extend_width <= shape.width) }; - if force_single_line { + if force_single_line && can_have_spaces_within_parenthesis { + result.push(' '); + result.push_str(items_str); + result.push(' '); + } else if force_single_line { result.push_str(items_str); } else { if !items_str.is_empty() { diff --git a/src/types.rs b/src/types.rs index aef85598f06..0607576f0ab 100644 --- a/src/types.rs +++ b/src/types.rs @@ -369,11 +369,14 @@ where (write_list(&item_vec, &fmt)?, tactic) }; - let args = if tactic == DefinitiveListTactic::Horizontal - || !context.use_block_indent() - || is_inputs_empty - { + let args = if is_inputs_empty { format!("({})", list_str) + } else if tactic == DefinitiveListTactic::Horizontal || !context.use_block_indent() { + if context.config.spaces_within_parenthesized_items() { + format!("( {} )", list_str) + } else { + format!("({})", list_str) + } } else { format!( "({}{}{})", diff --git a/tests/source/configs/spaces_within_parenthesized_items/false.rs b/tests/source/configs/spaces_within_parenthesized_items/false.rs new file mode 100644 index 00000000000..a5e40d43237 --- /dev/null +++ b/tests/source/configs/spaces_within_parenthesized_items/false.rs @@ -0,0 +1,77 @@ +// rustfmt-spaces_within_parenthesized_items: false +#[cfg( test )] +fn foo1() {} + +fn foo1_a(/* comment */) {} + +fn foo1_b(/* comment */ /* comment */) {} + +fn foo2( arg1: i32 ) -> i32 { + 0 +} + +fn foo2_a( /* comment */ arg1: i32 ) -> i32 { + 0 +} + +fn foo2_b( arg1: i32 /*comment */ ) -> i32 { + 0 +} + +fn foo3( arg1: T, arg2: U ) -> T { + Dummy( 1 ); + let ( x, y ) = ( 1, 2 ); + ( /* comment */ 1, 2 ); + ( 1, /* comment */ 2 ); + ( 1, 2 /* comment */ ); + 0 +} + +fn foo3_a( arg1: T, /* comment */ arg2: U ) -> T { + 0 +} + +fn foo4( + arggggggggggggggggggggggggggggggggggggggg1: i32, + arggggggggggggggggggggggggggggggggggggggg2: i32, +) { +} + +fn foo4_a( + /* comment */ + arggggggggggggggggggggggggggggggggggggggg1: i32, + arggggggggggggggggggggggggggggggggggggggg2: i32, +) { +} + +fn foo5() -> i32 { + foo1(); + foo1(/* comment */); + foo2( 1 ); + foo2( /* comment */ 1 ); + foo2( 1 /* comment */ ); + foo3( 1, 2 ); + foo3( 1, /* comment */ 2 ); + foo4( + 000000000000000000000001111111111, + 000000000000000000000002222222222, + ); + foo2( 000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 ); + foo2( + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + ); + foo2( + 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + ); + println!( "{}", "hello" ); + vec![1, 2, 3, 4].iter().contains( |x| x == 1 ); + (1 * ((2 + 1) * 3)) +} + +type Bar = fn( i32, i32 ) -> (); + +macro_rules! add { + ($a:expr,$b:expr) => {{ + $a + $b + }}; +} diff --git a/tests/source/configs/spaces_within_parenthesized_items/true.rs b/tests/source/configs/spaces_within_parenthesized_items/true.rs new file mode 100644 index 00000000000..25844182f00 --- /dev/null +++ b/tests/source/configs/spaces_within_parenthesized_items/true.rs @@ -0,0 +1,73 @@ +// rustfmt-spaces_within_parenthesized_items: true +#[cfg(test)] +fn foo1() {} + +fn foo1_a(/* comment */) {} + +fn foo1_b(/* comment */ /* comment */) {} + +fn foo2(arg1: i32) -> i32 { + 0 +} + +fn foo2_a( /* comment */ arg1: i32 ) -> i32 { + 0 +} + +fn foo2_b( arg1: i32 /*comment */ ) -> i32 { + 0 +} + +fn foo3(arg1: T, arg2: U) -> T { + Dummy(1); + let (x, y) = (1, 2); + (/* comment */1, 2); + (1, /* comment */ 2); + (1, 2 /* comment */); + 0 +} + +fn foo3_a(arg1: T, /* comment */ arg2: U) -> T { + 0 +} + +fn foo4( + arggggggggggggggggggggggggggggggggggggggg1: i32, + arggggggggggggggggggggggggggggggggggggggg2: i32, +) { +} + +fn foo4_a( /* comment */ + arggggggggggggggggggggggggggggggggggggggg1: i32, + arggggggggggggggggggggggggggggggggggggggg2: i32, +) { +} + +fn foo5() -> i32 { + foo1(); + foo1(/* comment */); + foo2(1); + foo2(/* comment */ 1); + foo2(1, /* comment */); + foo3(1, 2); + foo3(1, /* comment */ 2); + foo4( + 000000000000000000000001111111111, + 000000000000000000000002222222222, + ); + foo2(000000000000000000000000000000000000000000000000000000000000000000000000000000000000001); + foo2(000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001); + foo2(0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001); + println!("{}","hello"); + vec![1, 2, 3, 4].iter().contains( |x| x == 1 ); + (1 * ((2 + 1) * 3)) +} + + +type Bar = fn(i32, i32) -> (); + +macro_rules! add { + ($a:expr,$b:expr) => {{ + $a + $b + }}; +} diff --git a/tests/target/configs/spaces_within_parenthesized_items/false.rs b/tests/target/configs/spaces_within_parenthesized_items/false.rs new file mode 100644 index 00000000000..46de0686e02 --- /dev/null +++ b/tests/target/configs/spaces_within_parenthesized_items/false.rs @@ -0,0 +1,77 @@ +// rustfmt-spaces_within_parenthesized_items: false +#[cfg(test)] +fn foo1() {} + +fn foo1_a(/* comment */) {} + +fn foo1_b(/* comment */ /* comment */) {} + +fn foo2(arg1: i32) -> i32 { + 0 +} + +fn foo2_a(/* comment */ arg1: i32) -> i32 { + 0 +} + +fn foo2_b(arg1: i32 /*comment */) -> i32 { + 0 +} + +fn foo3(arg1: T, arg2: U) -> T { + Dummy(1); + let (x, y) = (1, 2); + (/* comment */ 1, 2); + (1, /* comment */ 2); + (1, 2 /* comment */); + 0 +} + +fn foo3_a(arg1: T, /* comment */ arg2: U) -> T { + 0 +} + +fn foo4( + arggggggggggggggggggggggggggggggggggggggg1: i32, + arggggggggggggggggggggggggggggggggggggggg2: i32, +) { +} + +fn foo4_a( + /* comment */ + arggggggggggggggggggggggggggggggggggggggg1: i32, + arggggggggggggggggggggggggggggggggggggggg2: i32, +) { +} + +fn foo5() -> i32 { + foo1(); + foo1(/* comment */); + foo2(1); + foo2(/* comment */ 1); + foo2(1 /* comment */); + foo3(1, 2); + foo3(1, /* comment */ 2); + foo4( + 000000000000000000000001111111111, + 000000000000000000000002222222222, + ); + foo2(000000000000000000000000000000000000000000000000000000000000000000000000000000000000001); + foo2( + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + ); + foo2( + 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + ); + println!("{}", "hello"); + vec![1, 2, 3, 4].iter().contains(|x| x == 1); + (1 * ((2 + 1) * 3)) +} + +type Bar = fn(i32, i32) -> (); + +macro_rules! add { + ($a:expr,$b:expr) => {{ + $a + $b + }}; +} diff --git a/tests/target/configs/spaces_within_parenthesized_items/true.rs b/tests/target/configs/spaces_within_parenthesized_items/true.rs new file mode 100644 index 00000000000..8c0d7289ebc --- /dev/null +++ b/tests/target/configs/spaces_within_parenthesized_items/true.rs @@ -0,0 +1,77 @@ +// rustfmt-spaces_within_parenthesized_items: true +#[cfg( test )] +fn foo1() {} + +fn foo1_a(/* comment */) {} + +fn foo1_b(/* comment */ /* comment */) {} + +fn foo2( arg1: i32 ) -> i32 { + 0 +} + +fn foo2_a( /* comment */ arg1: i32 ) -> i32 { + 0 +} + +fn foo2_b( arg1: i32 /*comment */ ) -> i32 { + 0 +} + +fn foo3( arg1: T, arg2: U ) -> T { + Dummy( 1 ); + let ( x, y ) = ( 1, 2 ); + ( /* comment */ 1, 2 ); + ( 1, /* comment */ 2 ); + ( 1, 2 /* comment */ ); + 0 +} + +fn foo3_a( arg1: T, /* comment */ arg2: U ) -> T { + 0 +} + +fn foo4( + arggggggggggggggggggggggggggggggggggggggg1: i32, + arggggggggggggggggggggggggggggggggggggggg2: i32, +) { +} + +fn foo4_a( + /* comment */ + arggggggggggggggggggggggggggggggggggggggg1: i32, + arggggggggggggggggggggggggggggggggggggggg2: i32, +) { +} + +fn foo5() -> i32 { + foo1(); + foo1(/* comment */); + foo2( 1 ); + foo2( /* comment */ 1 ); + foo2( 1 /* comment */ ); + foo3( 1, 2 ); + foo3( 1, /* comment */ 2 ); + foo4( + 000000000000000000000001111111111, + 000000000000000000000002222222222, + ); + foo2( 000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 ); + foo2( + 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + ); + foo2( + 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + ); + println!( "{}", "hello" ); + vec![1, 2, 3, 4].iter().contains( |x| x == 1 ); + (1 * ((2 + 1) * 3)) +} + +type Bar = fn( i32, i32 ) -> (); + +macro_rules! add { + ($a:expr,$b:expr) => {{ + $a + $b + }}; +}