diff --git a/src/config.rs b/src/config.rs index 448ab3b8d514..32eb9af4b118 100644 --- a/src/config.rs +++ b/src/config.rs @@ -71,6 +71,8 @@ configuration_option_enum! { Density: Tall, // Try to compress if the body is empty. CompressedIfEmpty, + // Place every item on a separate line. + Vertical, } configuration_option_enum! { TypeDensity: @@ -85,6 +87,7 @@ impl Density { match self { Density::Compressed => ListTactic::Mixed, Density::Tall | Density::CompressedIfEmpty => ListTactic::HorizontalVertical, + Density::Vertical => ListTactic::Vertical, } } } diff --git a/src/items.rs b/src/items.rs index b879080d92f4..04382489b280 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1544,13 +1544,18 @@ fn rewrite_args(context: &RewriteContext, _ => multi_line_budget, }; + let end_with_newline = match context.config.fn_args_layout { + StructLitStyle::Block => true, + _ => false, + }; + let fmt = ListFormatting { tactic: tactic, separator: ",", trailing_separator: SeparatorTactic::Never, indent: indent, width: budget, - ends_with_newline: false, + ends_with_newline: end_with_newline, config: context.config, }; diff --git a/tests/source/fn-custom-7.rs b/tests/source/fn-custom-7.rs new file mode 100644 index 000000000000..6a56c440d331 --- /dev/null +++ b/tests/source/fn-custom-7.rs @@ -0,0 +1,19 @@ +// rustfmt-fn_args_layout: Block +// rustfmt-fn_args_density: Vertical +// rustfmt-fn_arg_indent: Tabbed +// rustfmt-fn_brace_style: AlwaysNextLine + +// Case with only one variable. +fn foo(a: u8) -> u8 { + bar() +} + +// Case with 2 variables and some pre-comments. +fn foo(a: u8 /* Comment 1 */, b: u8 /* Comment 2 */) -> u8 { + bar() +} + +// Case with 2 variables and some post-comments. +fn foo(/* Comment 1 */ a: u8, /* Comment 2 */ b: u8) -> u8 { + bar() +} diff --git a/tests/source/fn_args_density-vertical.rs b/tests/source/fn_args_density-vertical.rs new file mode 100644 index 000000000000..7dd4dcbfc4dd --- /dev/null +++ b/tests/source/fn_args_density-vertical.rs @@ -0,0 +1,33 @@ +// rustfmt-fn_args_density: Vertical + +// Empty list shoul stay on one line. +fn do_bar( + +) -> u8 { + bar() +} + +// A single argument should stay on the same line. +fn do_bar( + a: u8) -> u8 { + bar() +} + +// Multiple arguments should each get their own line. +fn do_bar(a: u8, mut b: u8, c: &u8, d: &mut u8, closure: &Fn(i32) -> i32) -> i32 { + // This feature should not affect closures. + let bar = |x: i32, y: i32| -> i32 { x + y }; + bar(a, b) +} + +// If the first argument doesn't fit on the same line with the function name, +// the whole list should probably be pushed to the next line with hanging +// indent. That's not what happens though, so check current behaviour instead. +// In any case, it should maintain single argument per line. +fn do_this_that_and_the_other_thing( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: u8, + b: u8, c: u8, d: u8) { + this(); + that(); + the_other_thing(); +} diff --git a/tests/target/fn-custom-7.rs b/tests/target/fn-custom-7.rs new file mode 100644 index 000000000000..1c4cbde24b85 --- /dev/null +++ b/tests/target/fn-custom-7.rs @@ -0,0 +1,32 @@ +// rustfmt-fn_args_layout: Block +// rustfmt-fn_args_density: Vertical +// rustfmt-fn_arg_indent: Tabbed +// rustfmt-fn_brace_style: AlwaysNextLine + +// Case with only one variable. +fn foo( + a: u8 +) -> u8 +{ + bar() +} + +// Case with 2 variables and some pre-comments. +fn foo( + a: u8, // Comment 1 + b: u8 // Comment 2 +) -> u8 +{ + bar() +} + +// Case with 2 variables and some post-comments. +fn foo( + // Comment 1 + a: u8, + // Comment 2 + b: u8 +) -> u8 +{ + bar() +} diff --git a/tests/target/fn_args_density-vertical.rs b/tests/target/fn_args_density-vertical.rs new file mode 100644 index 000000000000..250d32654e56 --- /dev/null +++ b/tests/target/fn_args_density-vertical.rs @@ -0,0 +1,36 @@ +// rustfmt-fn_args_density: Vertical + +// Empty list shoul stay on one line. +fn do_bar() -> u8 { + bar() +} + +// A single argument should stay on the same line. +fn do_bar(a: u8) -> u8 { + bar() +} + +// Multiple arguments should each get their own line. +fn do_bar(a: u8, + mut b: u8, + c: &u8, + d: &mut u8, + closure: &Fn(i32) -> i32) + -> i32 { + // This feature should not affect closures. + let bar = |x: i32, y: i32| -> i32 { x + y }; + bar(a, b) +} + +// If the first argument doesn't fit on the same line with the function name, +// the whole list should probably be pushed to the next line with hanging +// indent. That's not what happens though, so check current behaviour instead. +// In any case, it should maintain single argument per line. +fn do_this_that_and_the_other_thing(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: u8, + b: u8, + c: u8, + d: u8) { + this(); + that(); + the_other_thing(); +}