diff --git a/src/config.rs b/src/config.rs index 8ba88725d01..fdfca063172 100644 --- a/src/config.rs +++ b/src/config.rs @@ -91,6 +91,7 @@ create_config! { fn_args_paren_newline: bool, fn_args_layout: Density, fn_arg_indent: BlockIndentStyle, + generics_indent: BlockIndentStyle, struct_trailing_comma: SeparatorTactic, struct_lit_trailing_comma: SeparatorTactic, struct_lit_style: StructLitStyle, @@ -117,6 +118,7 @@ impl Default for Config { fn_args_paren_newline: true, fn_args_layout: Density::Tall, fn_arg_indent: BlockIndentStyle::Visual, + generics_indent: BlockIndentStyle::Visual, struct_trailing_comma: SeparatorTactic::Vertical, struct_lit_trailing_comma: SeparatorTactic::Vertical, struct_lit_style: StructLitStyle::BlockIndent, diff --git a/src/items.rs b/src/items.rs index 694662b4eed..ae440826bdf 100644 --- a/src/items.rs +++ b/src/items.rs @@ -196,6 +196,7 @@ impl<'a> FmtVisitor<'a> { // Generics. let generics_indent = indent + result.len(); result.push_str(&self.rewrite_generics(generics, + indent, generics_indent, codemap::mk_sp(span.lo, span_for_return(&fd.output).lo))); @@ -432,6 +433,7 @@ impl<'a> FmtVisitor<'a> { let body_start = span.lo + BytePos(enum_snippet.find_uncommented("{").unwrap() as u32 + 1); let generics_str = self.format_generics(generics, " {", + self.block_indent, self.block_indent + self.config.tab_spaces, codemap::mk_sp(span.lo, body_start)); @@ -573,6 +575,7 @@ impl<'a> FmtVisitor<'a> { let generics_str = match generics { Some(g) => self.format_generics(g, opener, + offset, offset + header_str.len(), codemap::mk_sp(span.lo, struct_def.fields[0].span.lo)), @@ -670,9 +673,10 @@ impl<'a> FmtVisitor<'a> { generics: &ast::Generics, opener: &str, offset: usize, + generics_offset: usize, span: Span) -> String { - let mut result = self.rewrite_generics(generics, offset, span); + let mut result = self.rewrite_generics(generics, offset, generics_offset, span); if !generics.where_clause.predicates.is_empty() || result.contains('\n') { result.push_str(&self.rewrite_where_clause(&generics.where_clause, @@ -722,7 +726,12 @@ impl<'a> FmtVisitor<'a> { } } - fn rewrite_generics(&self, generics: &ast::Generics, offset: usize, span: Span) -> String { + fn rewrite_generics(&self, + generics: &ast::Generics, + offset: usize, + generics_offset: usize, + span: Span) + -> String { // FIXME convert bounds to where clauses where they get too big or if // there is a where clause at all. let lifetimes: &[_] = &generics.lifetimes; @@ -731,18 +740,24 @@ impl<'a> FmtVisitor<'a> { return String::new(); } - let budget = self.config.max_width - offset - 2; + let offset = match self.config.generics_indent { + BlockIndentStyle::Inherit => offset, + BlockIndentStyle::Tabbed => offset + self.config.tab_spaces, + // 1 = < + BlockIndentStyle::Visual => generics_offset + 1, + }; + + let h_budget = self.config.max_width - generics_offset - 2; // TODO might need to insert a newline if the generics are really long // Strings for the generics. - // 1 = < let context = self.get_context(); // FIXME: don't unwrap let lt_strs = lifetimes.iter().map(|lt| { - lt.rewrite(&context, budget, offset + 1).unwrap() + lt.rewrite(&context, h_budget, offset).unwrap() }); let ty_strs = tys.iter().map(|ty_param| { - ty_param.rewrite(&context, budget, offset + 1).unwrap() + ty_param.rewrite(&context, h_budget, offset).unwrap() }); // Extract comments between generics. @@ -770,7 +785,7 @@ impl<'a> FmtVisitor<'a> { item.item = ty; } - let fmt = ListFormatting::for_fn(budget, offset + 1); + let fmt = ListFormatting::for_fn(h_budget, offset); format!("<{}>", write_list(&items, &fmt)) } diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index d489f960917..e621547a010 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -8,6 +8,7 @@ fn_return_indent = "WithArgs" fn_args_paren_newline = true fn_args_layout = "Tall" fn_arg_indent = "Visual" +generics_indent = "Visual" struct_trailing_comma = "Vertical" struct_lit_trailing_comma = "Vertical" struct_lit_style = "BlockIndent" diff --git a/tests/source/fn-custom-2.rs b/tests/source/fn-custom-2.rs new file mode 100644 index 00000000000..1b7e6ad78ad --- /dev/null +++ b/tests/source/fn-custom-2.rs @@ -0,0 +1,25 @@ +// rustfmt-fn_arg_indent: Inherit +// rustfmt-generics_indent: Tabbed +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); +} + +impl Foo { + fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); + } +} + +struct Foo { + foo: Foo, +} diff --git a/tests/source/fn-custom-3.rs b/tests/source/fn-custom-3.rs new file mode 100644 index 00000000000..68939eee6b5 --- /dev/null +++ b/tests/source/fn-custom-3.rs @@ -0,0 +1,25 @@ +// rustfmt-fn_arg_indent: Tabbed +// rustfmt-generics_indent: Inherit +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); +} + +impl Foo { + fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); + } +} + +struct Foo { + foo: Foo, +} diff --git a/tests/target/fn-custom-2.rs b/tests/target/fn-custom-2.rs new file mode 100644 index 00000000000..1bb7ef401ec --- /dev/null +++ b/tests/target/fn-custom-2.rs @@ -0,0 +1,44 @@ +// rustfmt-fn_arg_indent: Inherit +// rustfmt-generics_indent: Tabbed +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, +b: Bbbbbbbbbbbbbbbb, +c: Ccccccccccccccccc, +d: Ddddddddddddddddddddddddd, +e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW> + (a: Aaaaaaaaaaaaaaa) { + bar(); +} + +impl Foo { + fn foo(self, + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW> + (a: Aaaaaaaaaaaaaaa) { + bar(); + } +} + +struct Foo +{ + foo: Foo, +} diff --git a/tests/target/fn-custom-3.rs b/tests/target/fn-custom-3.rs new file mode 100644 index 00000000000..61194dd04f3 --- /dev/null +++ b/tests/target/fn-custom-3.rs @@ -0,0 +1,44 @@ +// rustfmt-fn_arg_indent: Tabbed +// rustfmt-generics_indent: Inherit +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, +TTTTTTTTTTTTT, +UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW> + (a: Aaaaaaaaaaaaaaa) { + bar(); +} + +impl Foo { + fn foo(self, + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW> + (a: Aaaaaaaaaaaaaaa) { + bar(); + } +} + +struct Foo +{ + foo: Foo, +}