diff --git a/src/config.rs b/src/config.rs index 5b6a5e05cf5..48b7a06e538 100644 --- a/src/config.rs +++ b/src/config.rs @@ -316,6 +316,7 @@ create_config! { where_layout: ListTactic, ListTactic::Vertical, "Element layout inside a where clause"; where_pred_indent: BlockIndentStyle, BlockIndentStyle::Visual, "Indentation style of a where predicate"; + where_trailing_comma: bool, false, "Put a trailing comma on where clauses"; generics_indent: BlockIndentStyle, BlockIndentStyle::Visual, "Indentation of generics"; struct_trailing_comma: SeparatorTactic, SeparatorTactic::Vertical, "If there is a trailing comma on structs"; diff --git a/src/items.rs b/src/items.rs index 1e1b6ca8076..2ff52148f6a 100644 --- a/src/items.rs +++ b/src/items.rs @@ -491,6 +491,7 @@ pub fn format_impl(context: &RewriteContext, item: &ast::Item, offset: Indent) - where_budget, context.config.where_density, "{", + true, None)); if try_opt!(is_impl_single_line(context, &items, &result, &where_clause_str, &item)) { @@ -737,6 +738,7 @@ fn format_tuple_struct(context: &RewriteContext, where_budget, Density::Compressed, ";", + false, None)) } None => "".to_owned(), @@ -818,6 +820,7 @@ pub fn rewrite_type_alias(context: &RewriteContext, where_budget, context.config.where_density, "=", + false, Some(span.hi))); result.push_str(&where_clause_str); result.push_str(" = "); @@ -1248,6 +1251,7 @@ fn rewrite_fn_base(context: &RewriteContext, where_budget, where_density, "{", + has_body, Some(span.hi))); if last_line_width(&result) + where_clause_str.len() > context.config.max_width && @@ -1487,6 +1491,7 @@ fn rewrite_where_clause(context: &RewriteContext, width: usize, density: Density, terminator: &str, + allow_trailing_comma: bool, span_end: Option) -> Option { if where_clause.predicates.is_empty() { @@ -1526,11 +1531,12 @@ fn rewrite_where_clause(context: &RewriteContext, // FIXME: we don't need to collect here if the where_layout isn't // HorizontalVertical. let tactic = definitive_tactic(&item_vec, context.config.where_layout, budget); + let use_trailing_comma = allow_trailing_comma && context.config.where_trailing_comma; let fmt = ListFormatting { tactic: tactic, separator: ",", - trailing_separator: SeparatorTactic::Never, + trailing_separator: SeparatorTactic::from_bool(use_trailing_comma), indent: offset, width: budget, ends_with_newline: true, @@ -1592,6 +1598,7 @@ fn format_generics(context: &RewriteContext, budget, Density::Tall, terminator, + true, Some(span.hi))); result.push_str(&where_clause_str); if !force_same_line_brace && diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index 1681aff77b4..cb4d5da5274 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -12,6 +12,7 @@ where_density = "Tall" where_indent = "Tabbed" where_layout = "Vertical" where_pred_indent = "Visual" +where_trailing_comma = false generics_indent = "Visual" struct_trailing_comma = "Vertical" struct_lit_trailing_comma = "Vertical" diff --git a/tests/source/where-trailing-comma.rs b/tests/source/where-trailing-comma.rs new file mode 100644 index 00000000000..8f951d199e4 --- /dev/null +++ b/tests/source/where-trailing-comma.rs @@ -0,0 +1,37 @@ +// rustfmt-where_trailing_comma: true + +fn f(x: T, y: S) -> T where T: P, S: Q +{ + x +} + +impl Trait for T where T: P +{ + fn f(x: T) -> T where T: Q + R + { + x + } +} + +struct Pair where T: P, S: P + Q { + a: T, + b: S +} + +struct TupPair (S, T) where T: P, S: P + Q; + +enum E where S: P, T: P { + A {a: T}, +} + +type Double where T: P, T: Q = Pair; + +extern "C" { + fn f(x: T, y: S) -> T where T: P, S: Q; +} + +// Note: trait declarations are not fully formatted (issue #78) +trait Q where T: P, S: R +{ + fn f(self, x: T, y: S, z: U) -> Self where U: P, V: P; +} diff --git a/tests/target/where-trailing-comma.rs b/tests/target/where-trailing-comma.rs new file mode 100644 index 00000000000..bd7108f992a --- /dev/null +++ b/tests/target/where-trailing-comma.rs @@ -0,0 +1,57 @@ +// rustfmt-where_trailing_comma: true + +fn f(x: T, y: S) -> T + where T: P, + S: Q, +{ + x +} + +impl Trait for T + where T: P, +{ + fn f(x: T) -> T + where T: Q + R, + { + x + } +} + +struct Pair + where T: P, + S: P + Q, +{ + a: T, + b: S, +} + +struct TupPair(S, T) + where T: P, + S: P + Q; + +enum E + where S: P, + T: P, +{ + A { + a: T, + }, +} + +type Double + where T: P, + T: Q = Pair; + +extern "C" { + fn f(x: T, y: S) -> T + where T: P, + S: Q; +} + +// Note: trait declarations are not fully formatted (issue #78) +trait Q where T: P, S: R +{ + fn f(self, x: T, y: S, z: U) -> Self + where U: P, + V: P; +}