Skip to content

Commit f412c87

Browse files
afshinmnrc
authored andcommitted
Adding where_single_line option (#2030)
* feat(where): adding where_single_line option and tests * fix(where): adding more tests * feat(where): changing the shape of where clause when where_single_line is true * feat: newline_for_brace should avoid adding a new line where where_single_line is true * fix(items): where_single_line should bypass the multi-item where clauses * fix(items): refactoring and removing redundant variables * fix(items): where_single_line should not be functional when args are multilined * fix(config): fixing conflict with upstream
1 parent f1035d9 commit f412c87

File tree

4 files changed

+87
-6
lines changed

4 files changed

+87
-6
lines changed

src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ create_config! {
574574
// function decl?
575575
// 2. Currently options `Tall` and `Vertical` produce the same output.
576576
where_density: Density, Density::Vertical, false, "Density of a where clause";
577+
where_single_line: bool, false, false, "To force single line where layout";
577578
where_layout: ListTactic, ListTactic::Vertical, false, "Element layout inside a where clause";
578579
where_pred_indent: IndentStyle, IndentStyle::Visual, false,
579580
"Indentation style of a where predicate";

src/items.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ pub fn format_impl(
593593
where_span_end,
594594
self_ty.span.hi(),
595595
option,
596+
false,
596597
)?;
597598

598599
// If there is no where clause, we may have missing comments between the trait name and
@@ -960,6 +961,7 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
960961
None,
961962
pos_before_where,
962963
option,
964+
false,
963965
)?;
964966
// If the where clause cannot fit on the same line,
965967
// put the where clause on a new line
@@ -1229,6 +1231,7 @@ fn format_tuple_struct(
12291231
None,
12301232
body_hi,
12311233
option,
1234+
false,
12321235
)?
12331236
}
12341237
None => "".to_owned(),
@@ -1321,6 +1324,7 @@ pub fn rewrite_type_alias(
13211324
Some(span.hi()),
13221325
generics.span.hi(),
13231326
option,
1327+
false,
13241328
)?;
13251329
result.push_str(&where_clause_str);
13261330
if where_clause_str.is_empty() {
@@ -1954,6 +1958,8 @@ fn rewrite_fn_base(
19541958
ast::FunctionRetTy::Ty(ref ty) => ty.span.hi(),
19551959
};
19561960

1961+
let is_args_multi_lined = arg_str.contains('\n');
1962+
19571963
if where_clause.predicates.len() == 1 && should_compress_where {
19581964
let budget = context.budget(last_line_used_width(&result, indent.width()));
19591965
if let Some(where_clause_str) = rewrite_where_clause(
@@ -1966,6 +1972,7 @@ fn rewrite_fn_base(
19661972
Some(span.hi()),
19671973
pos_before_where,
19681974
WhereClauseOption::compressed(),
1975+
is_args_multi_lined,
19691976
) {
19701977
result.push_str(&where_clause_str);
19711978
force_new_line_for_brace |= last_line_contains_single_line_comment(&result);
@@ -1984,6 +1991,7 @@ fn rewrite_fn_base(
19841991
Some(span.hi()),
19851992
pos_before_where,
19861993
option,
1994+
is_args_multi_lined,
19871995
)?;
19881996
// If there are neither where clause nor return type, we may be missing comments between
19891997
// args and `{`.
@@ -2007,6 +2015,7 @@ fn rewrite_fn_base(
20072015
result.push_str(&where_clause_str);
20082016

20092017
force_new_line_for_brace |= last_line_contains_single_line_comment(&result);
2018+
force_new_line_for_brace |= is_args_multi_lined && context.config.where_single_line();
20102019
Some((result, force_new_line_for_brace))
20112020
}
20122021

@@ -2264,11 +2273,16 @@ fn compute_budgets_for_args(
22642273
}
22652274

22662275
fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause, has_body: bool) -> bool {
2276+
let predicate_count = where_clause.predicates.len();
2277+
2278+
if config.where_single_line() && predicate_count == 1 {
2279+
return false;
2280+
}
22672281
match (config.fn_brace_style(), config.where_density()) {
22682282
(BraceStyle::AlwaysNextLine, _) => true,
2269-
(_, Density::Compressed) if where_clause.predicates.len() == 1 => false,
2270-
(_, Density::CompressedIfEmpty) if where_clause.predicates.len() == 1 && !has_body => false,
2271-
(BraceStyle::SameLineWhere, _) if !where_clause.predicates.is_empty() => true,
2283+
(_, Density::Compressed) if predicate_count == 1 => false,
2284+
(_, Density::CompressedIfEmpty) if predicate_count == 1 && !has_body => false,
2285+
(BraceStyle::SameLineWhere, _) if predicate_count > 0 => true,
22722286
_ => false,
22732287
}
22742288
}
@@ -2444,6 +2458,7 @@ fn rewrite_where_clause_rfc_style(
24442458
span_end: Option<BytePos>,
24452459
span_end_before_where: BytePos,
24462460
where_clause_option: WhereClauseOption,
2461+
is_args_multi_line: bool,
24472462
) -> Option<String> {
24482463
let block_shape = shape.block().with_max_width(context.config);
24492464

@@ -2479,14 +2494,23 @@ fn rewrite_where_clause_rfc_style(
24792494
span_end,
24802495
false,
24812496
);
2482-
let comma_tactic = if where_clause_option.suppress_comma {
2497+
let where_single_line = context.config.where_single_line() && len == 1 && !is_args_multi_line;
2498+
let comma_tactic = if where_clause_option.suppress_comma || where_single_line {
24832499
SeparatorTactic::Never
24842500
} else {
24852501
context.config.trailing_comma()
24862502
};
24872503

2504+
// shape should be vertical only and only if we have `where_single_line` option enabled
2505+
// and the number of items of the where clause is equal to 1
2506+
let shape_tactic = if where_single_line {
2507+
DefinitiveListTactic::Horizontal
2508+
} else {
2509+
DefinitiveListTactic::Vertical
2510+
};
2511+
24882512
let fmt = ListFormatting {
2489-
tactic: DefinitiveListTactic::Vertical,
2513+
tactic: shape_tactic,
24902514
separator: ",",
24912515
trailing_separator: comma_tactic,
24922516
separator_place: SeparatorPlace::Back,
@@ -2508,7 +2532,7 @@ fn rewrite_where_clause_rfc_style(
25082532
// 6 = `where `
25092533
let clause_sep = if where_clause_option.compress_where && comment_before.is_empty()
25102534
&& comment_after.is_empty() && !preds_str.contains('\n')
2511-
&& 6 + preds_str.len() <= shape.width
2535+
&& 6 + preds_str.len() <= shape.width || where_single_line
25122536
{
25132537
String::from(" ")
25142538
} else {
@@ -2536,6 +2560,7 @@ fn rewrite_where_clause(
25362560
span_end: Option<BytePos>,
25372561
span_end_before_where: BytePos,
25382562
where_clause_option: WhereClauseOption,
2563+
is_args_multi_line: bool,
25392564
) -> Option<String> {
25402565
if where_clause.predicates.is_empty() {
25412566
return Some(String::new());
@@ -2550,6 +2575,7 @@ fn rewrite_where_clause(
25502575
span_end,
25512576
span_end_before_where,
25522577
where_clause_option,
2578+
is_args_multi_line,
25532579
);
25542580
}
25552581

@@ -2698,6 +2724,7 @@ fn format_generics(
26982724
Some(span.hi()),
26992725
span_end_before_where,
27002726
option,
2727+
false,
27012728
)?;
27022729
result.push_str(&where_clause_str);
27032730
force_same_line_brace || brace_style == BraceStyle::PreferSameLine
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// rustfmt-where_single_line: true
2+
// Where style
3+
4+
5+
fn lorem_two_items<Ipsum, Dolor, Sit, Amet>() -> T where Ipsum: Eq, Lorem: Eq {
6+
// body
7+
}
8+
9+
fn lorem_multi_line<Ipsum, Dolor, Sit, Amet>(
10+
a: Aaaaaaaaaaaaaaa,
11+
b: Bbbbbbbbbbbbbbbb,
12+
c: Ccccccccccccccccc,
13+
d: Ddddddddddddddddddddddddd,
14+
e: Eeeeeeeeeeeeeeeeeee,
15+
) -> T
16+
where
17+
Ipsum: Eq,
18+
{
19+
// body
20+
}
21+
22+
fn lorem<Ipsum, Dolor, Sit, Amet>() -> T where Ipsum: Eq {
23+
// body
24+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// rustfmt-where_single_line: true
2+
// Where style
3+
4+
5+
fn lorem_two_items<Ipsum, Dolor, Sit, Amet>() -> T
6+
where
7+
Ipsum: Eq,
8+
Lorem: Eq,
9+
{
10+
// body
11+
}
12+
13+
fn lorem_multi_line<Ipsum, Dolor, Sit, Amet>(
14+
a: Aaaaaaaaaaaaaaa,
15+
b: Bbbbbbbbbbbbbbbb,
16+
c: Ccccccccccccccccc,
17+
d: Ddddddddddddddddddddddddd,
18+
e: Eeeeeeeeeeeeeeeeeee,
19+
) -> T
20+
where
21+
Ipsum: Eq,
22+
{
23+
// body
24+
}
25+
26+
fn lorem<Ipsum, Dolor, Sit, Amet>() -> T
27+
where Ipsum: Eq {
28+
// body
29+
}

0 commit comments

Comments
 (0)