From fae93abbdaa9d2bcf7a3c2cff0c5c7beadc62cc7 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 2 Sep 2015 09:41:08 +1200 Subject: [PATCH] Support struct-like layouts for fn args --- src/config.rs | 4 +- src/expr.rs | 8 ++-- src/items.rs | 23 +++++++--- src/lib.rs | 6 +-- tests/config/small_tabs.toml | 3 +- tests/source/fn-custom-6.rs | 36 +++++++++++++++ tests/source/struct_lits_visual.rs | 2 +- tests/target/fn-custom-6.rs | 70 ++++++++++++++++++++++++++++++ tests/target/struct_lits_visual.rs | 2 +- 9 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 tests/source/fn-custom-6.rs create mode 100644 tests/target/fn-custom-6.rs diff --git a/src/config.rs b/src/config.rs index 329c67d2b0d..1b4d79ab6ee 100644 --- a/src/config.rs +++ b/src/config.rs @@ -90,6 +90,7 @@ create_config! { fn_return_indent: ReturnIndent, fn_args_paren_newline: bool, fn_args_density: Density, + fn_args_layout: StructLitStyle, fn_arg_indent: BlockIndentStyle, where_density: Density, // Should we at least try to put the where clause on the same line as // the rest of the function decl? @@ -123,6 +124,7 @@ impl Default for Config { fn_return_indent: ReturnIndent::WithArgs, fn_args_paren_newline: true, fn_args_density: Density::Tall, + fn_args_layout: StructLitStyle::Visual, fn_arg_indent: BlockIndentStyle::Visual, where_density: Density::Tall, where_indent: BlockIndentStyle::Tabbed, @@ -131,7 +133,7 @@ impl Default for Config { generics_indent: BlockIndentStyle::Visual, struct_trailing_comma: SeparatorTactic::Vertical, struct_lit_trailing_comma: SeparatorTactic::Vertical, - struct_lit_style: StructLitStyle::BlockIndent, + struct_lit_style: StructLitStyle::Block, enum_trailing_comma: true, report_todo: ReportTactic::Always, report_fixme: ReportTactic::Never, diff --git a/src/expr.rs b/src/expr.rs index 20c56ccd34f..19b3693d94b 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -940,10 +940,10 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext, // Foo { a: Foo } - indent is +3, width is -5. let h_budget = try_opt!(width.checked_sub(path_str.len() + 5)); let (indent, v_budget) = match context.config.struct_lit_style { - StructLitStyle::VisualIndent => { + StructLitStyle::Visual => { (offset + path_str.len() + 3, h_budget) } - StructLitStyle::BlockIndent => { + StructLitStyle::Block => { // If we are all on one line, then we'll ignore the indent, and we // have a smaller budget. let indent = context.block_indent + context.config.tab_spaces; @@ -1012,7 +1012,7 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext, let fields_str = write_list(&items.collect::>(), &fmt); match context.config.struct_lit_style { - StructLitStyle::BlockIndent if fields_str.contains('\n') => { + StructLitStyle::Block if fields_str.contains('\n') => { let inner_indent = make_indent(context.block_indent + context.config.tab_spaces); let outer_indent = make_indent(context.block_indent); Some(format!("{} {{\n{}{}\n{}}}", path_str, inner_indent, fields_str, outer_indent)) @@ -1020,7 +1020,7 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext, _ => Some(format!("{} {{ {} }}", path_str, fields_str)), } - // FIXME if context.config.struct_lit_style == VisualIndent, but we run out + // FIXME if context.config.struct_lit_style == Visual, but we run out // of space, we should fall back to BlockIndent. } diff --git a/src/items.rs b/src/items.rs index fd163cec680..4d84a142045 100644 --- a/src/items.rs +++ b/src/items.rs @@ -10,7 +10,7 @@ // Formatting top-level items - functions, structs, enums, traits, impls. -use {ReturnIndent, BraceStyle}; +use {ReturnIndent, BraceStyle, StructLitStyle}; use utils::{format_mutability, format_visibility, make_indent, contains_skip, span_after, end_typaram}; use lists::{write_list, itemize_list, ListItem, ListFormatting, SeparatorTactic, ListTactic}; @@ -225,6 +225,10 @@ impl<'a> FmtVisitor<'a> { result.push_str("(\n"); result.push_str(&make_indent(arg_indent)); } + } else if self.config.fn_args_layout == StructLitStyle::Block { + arg_indent = indent + self.config.tab_spaces; + result.push_str("(\n"); + result.push_str(&make_indent(arg_indent)); } else { result.push('('); } @@ -245,14 +249,20 @@ impl<'a> FmtVisitor<'a> { indent, arg_indent, args_span)); + if self.config.fn_args_layout == StructLitStyle::Block { + result.push('\n'); + } result.push(')'); // Return type. if !ret_str.is_empty() { // If we've already gone multi-line, or the return type would push // over the max width, then put the return type on a new line. - if result.contains("\n") || - result.len() + indent + ret_str.len() > self.config.max_width { + // Unless we are formatting args like a block, in which case there + // should always be room for the return type. + if (result.contains("\n") || + result.len() + indent + ret_str.len() > self.config.max_width) && + self.config.fn_args_layout != StructLitStyle::Block { let indent = match self.config.fn_return_indent { ReturnIndent::WithWhereClause => indent + 4, // TODO we might want to check that using the arg indent doesn't @@ -285,8 +295,11 @@ impl<'a> FmtVisitor<'a> { } } - let where_density = if self.config.where_density == Density::Compressed && - !result.contains('\n') { + let where_density = if (self.config.where_density == Density::Compressed && + (!result.contains('\n') || + self.config.fn_args_layout == StructLitStyle::Block)) || + (self.config.fn_args_layout == StructLitStyle::Block && + ret_str.is_empty()) { Density::Compressed } else { Density::Tall diff --git a/src/lib.rs b/src/lib.rs index f410f7e5468..83c0c5ae1b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -133,13 +133,13 @@ impl_enum_decodable!(ReturnIndent, WithArgs, WithWhereClause); pub enum StructLitStyle { // First line on the same line as the opening brace, all lines aligned with // the first line. - VisualIndent, + Visual, // First line is on a new line and all lines align with block indent. - BlockIndent, + Block, // FIXME Maybe we should also have an option to align types. } -impl_enum_decodable!(StructLitStyle, VisualIndent, BlockIndent); +impl_enum_decodable!(StructLitStyle, Visual, Block); enum ErrorKind { // Line has exceeded character limit diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index 08a0c22cc10..c5122b760a0 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -7,6 +7,7 @@ fn_brace_style = "SameLineWhere" fn_return_indent = "WithArgs" fn_args_paren_newline = true fn_args_density = "Tall" +fn_args_layout = "Visual" fn_arg_indent = "Visual" where_density = "Tall" where_indent = "Tabbed" @@ -15,7 +16,7 @@ where_pred_indent = "Visual" generics_indent = "Visual" struct_trailing_comma = "Vertical" struct_lit_trailing_comma = "Vertical" -struct_lit_style = "BlockIndent" +struct_lit_style = "Block" enum_trailing_comma = true report_todo = "Always" report_fixme = "Never" diff --git a/tests/source/fn-custom-6.rs b/tests/source/fn-custom-6.rs new file mode 100644 index 00000000000..1042fa5bd88 --- /dev/null +++ b/tests/source/fn-custom-6.rs @@ -0,0 +1,36 @@ +// rustfmt-fn_args_layout: Block +// rustfmt-where_indent: Inherit +// rustfmt-fn_brace_style: PreferSameLine +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) -> String { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) where T: UUUUUUUUUUU { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) where T: UUUUUUUUUUU { + bar(); +} + +fn foo(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb) -> String where T: UUUUUUUUUUU { + foo(); +} + +fn bar(a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb, c: Cccccccccccccccccc, d: Dddddddddddddddd, e: Eeeeeeeeeeeeeee) -> String where T: UUUUUUUUUUU { + bar(); +} diff --git a/tests/source/struct_lits_visual.rs b/tests/source/struct_lits_visual.rs index ea76a088a32..180a1229faa 100644 --- a/tests/source/struct_lits_visual.rs +++ b/tests/source/struct_lits_visual.rs @@ -1,4 +1,4 @@ -// rustfmt-struct_lit_style: VisualIndent +// rustfmt-struct_lit_style: Visual // Struct literal expressions. diff --git a/tests/target/fn-custom-6.rs b/tests/target/fn-custom-6.rs new file mode 100644 index 00000000000..bea50c6a3ce --- /dev/null +++ b/tests/target/fn-custom-6.rs @@ -0,0 +1,70 @@ +// rustfmt-fn_args_layout: Block +// rustfmt-where_indent: Inherit +// rustfmt-fn_brace_style: PreferSameLine +// Test different indents. + +fn foo( + a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb +) { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee +) { + bar(); +} + +fn foo( + a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb +) -> String { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee +) -> String { + bar(); +} + +fn foo( + a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb +) where T: UUUUUUUUUUU { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee +) where T: UUUUUUUUUUU { + bar(); +} + +fn foo( + a: Aaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbb +) -> String +where T: UUUUUUUUUUU { + foo(); +} + +fn bar( + a: Aaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbb, + c: Cccccccccccccccccc, + d: Dddddddddddddddd, + e: Eeeeeeeeeeeeeee +) -> String +where T: UUUUUUUUUUU { + bar(); +} diff --git a/tests/target/struct_lits_visual.rs b/tests/target/struct_lits_visual.rs index 77467a40ce7..4274c916777 100644 --- a/tests/target/struct_lits_visual.rs +++ b/tests/target/struct_lits_visual.rs @@ -1,4 +1,4 @@ -// rustfmt-struct_lit_style: VisualIndent +// rustfmt-struct_lit_style: Visual // Struct literal expressions.