Skip to content

Commit 94a1c9d

Browse files
fix: PreferSameLine and WhereSingleLine had conflicting brace rules for fn declarations + tests
When I added these tests I noticed that in target/prefer_same_line_where_single_line.rs line 98 that the brace was on the same line as the second where predicate `U`, while in the same file at line 114, a very similar function declaration was incorrectly formatting the brace onto the next line. Now if the brace style is PreferSameLine, then the opening brace on function declarations with multi-lined parameters remains on the same line as the last where clause predicate.
1 parent 14b815d commit 94a1c9d

16 files changed

+1824
-89
lines changed

src/items.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,8 +2758,13 @@ fn rewrite_fn_base(
27582758

27592759
let ends_with_comment = last_line_contains_single_line_comment(&result);
27602760
force_new_line_for_brace |= ends_with_comment;
2761-
force_new_line_for_brace |=
2762-
is_params_multi_lined && context.config.where_single_line() && !where_clause_str.is_empty();
2761+
2762+
// PreferSameLine should keep the brace on the same line as the last where predicate.
2763+
force_new_line_for_brace |= !where_clause_str.is_empty()
2764+
&& context.config.where_single_line()
2765+
&& is_params_multi_lined
2766+
&& context.config.brace_style() != BraceStyle::PreferSameLine;
2767+
27632768
Ok((result, ends_with_comment, force_new_line_for_brace))
27642769
}
27652770

tests/source/issue-6539/brace_next_line.rs

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,72 @@
22
// rustfmt-brace_style: AlwaysNextLine
33
// rustfmt-where_single_line: false
44

5-
pub trait Trait
6-
{
7-
fn a_one_hundred_column_fn_decl_no_body(&self, aaa: f64, b: f64, c: f64, d: f64, e: f64) -> f64;
5+
// Top-level functions
86

9-
fn an_over_one_hundred_column_fn_decl_no_body_and_where_clause<T>(&self, a: T, bb: f64) -> f64 where T: Debug;
7+
// Short function
8+
fn short_fn(a: f64, b: f64) -> f64;
109

11-
fn an_over_one_hundred_column_fn_decl_no_body_and_where_clause2<T>(&self, aaa: T, bbb: f64) -> f64 where T: Debug;
10+
// Function with wrapping return type and no where clause
11+
fn fn_with_long_return_type(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>>;
1212

13-
fn an_over_one_hundred_column_fn_decl_with_body(&self, aaaaa: f64, bbbbb: f64, ccc: f64) -> f64 {}
13+
// Function with non-wrapping return type and where clause
14+
fn fn_with_short_where<T>(a: f64, b: T) -> f64 where T: Debug;
1415

15-
fn an_over_one_hundred_column_fn_decl_with_body_and_where_clause<T>(&self, aaaaa: f64) -> f64 where T: Debug {}
16+
// Function that wraps at a simple return type
17+
fn fn_with_wrapping_return_type<T>(aaaaaa: f64, bbbbbb: T, cccccc: f64, dddddd: f64, eeee: f64) -> f64;
18+
19+
// Function that wraps at the where clause
20+
fn fn_with_wrapping_where_clause<T>(aaaaaa: f64, bbbbbb: T, cccccc: f64, dddddd: f64) -> f64 where T: Debug;
21+
22+
// Function with both wrapping return type and wrapping where clause
23+
fn fn_with_long_return_and_where<T, U, 'a>(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
24+
25+
// Function with wrapping arguments, return type, and where clause
26+
fn fn_with_everything_long<T, U, 'a>(aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64, ffff: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
27+
28+
// Same variations with bodies
29+
fn short_fn_with_body(a: f64, b: f64) -> f64 {}
30+
31+
fn fn_with_long_return_type_and_body(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> {}
32+
33+
fn fn_with_short_where_and_body<T>(a: f64, b: T) -> f64 where T: Debug {}
34+
35+
fn fn_with_wrapping_return_type_and_body<T>(aaaaaa: f64, bbbbbb: T, ccc: f64, ddd: f64, ee: f64) -> f64 {}
36+
37+
fn fn_with_wrapping_where_clause_and_body<T>(aaaaaa: f64, bbbbbb: T, ccc: f64, ddd: f64) -> f64 where T: Debug {}
38+
39+
fn fn_with_long_return_and_where_and_body<T, U, 'a>(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
40+
41+
fn fn_with_everything_long_and_body<T, U, 'a>(aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64, ffff: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
42+
43+
// Trait methods
44+
pub trait Trait {
45+
fn short_method(a: f64, b: f64) -> f64;
46+
47+
fn method_with_long_return(&self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>>;
48+
49+
fn method_with_short_where<T>(&self, a: f64, b: T) -> f64 where T: Debug;
50+
51+
fn method_with_wrapping_return_type<T>(self, aaa: f64, bbb: T, ccc: f64, ddd: f64, ee: f64) -> f64;
52+
53+
fn method_with_wrapping_where_clause<T>(aaaaaa: f64, bbbbbb: T, ccc: f64, ddd: f64) -> f64 where T: Debug;
54+
55+
fn method_with_long_return_and_where<T, U, 'a>(self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
56+
57+
fn method_with_everything_long<T, U, 'a>(&self, aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
58+
59+
// Same variations with bodies
60+
fn short_method_with_body(a: f64, b: f64) -> f64 {}
61+
62+
fn method_with_long_return_and_body(&self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> {}
63+
64+
fn method_with_short_where_and_body<T>(&self, a: f64, b: T) -> f64 where T: Debug {}
65+
66+
fn method_with_wrapping_return_type_and_body<T>(aaaa: f64, bb: T, cc: f64, d: f64, e: f64) -> f64 {}
67+
68+
fn method_with_wrapping_where_clause_and_body<T>(aaa: f64, bb: T, cc: f64, d: f64) -> f64 where T: Debug {}
69+
70+
fn method_with_long_return_and_where_and_body<T, U, 'a>(self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
71+
72+
fn method_with_everything_long_and_body<T, U, 'a>(aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
1673
}

tests/source/issue-6539/brace_next_line_where_single_line.rs

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,72 @@
22
// rustfmt-brace_style: AlwaysNextLine
33
// rustfmt-where_single_line: true
44

5-
pub trait Trait
6-
{
7-
fn a_one_hundred_column_fn_decl_no_body(&self, aaa: f64, b: f64, c: f64, d: f64, e: f64) -> f64;
5+
// Top-level functions
86

9-
fn an_over_one_hundred_column_fn_decl_no_body_and_where_clause<T>(&self, a: T, bb: f64) -> f64 where T: Debug;
7+
// Short function
8+
fn short_fn(a: f64, b: f64) -> f64;
109

11-
fn an_over_one_hundred_column_fn_decl_no_body_and_where_clause2<T>(&self, aaa: T, bbb: f64) -> f64 where T: Debug;
10+
// Function with wrapping return type and no where clause
11+
fn fn_with_long_return_type(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>>;
1212

13-
fn an_over_one_hundred_column_fn_decl_with_body(&self, aaaaa: f64, bbbbb: f64, ccc: f64) -> f64 {}
13+
// Function with non-wrapping return type and where clause
14+
fn fn_with_short_where<T>(a: f64, b: T) -> f64 where T: Debug;
1415

15-
fn an_over_one_hundred_column_fn_decl_with_body_and_where_clause<T>(&self, aaaaa: f64) -> f64 where T: Debug {}
16+
// Function that wraps at a simple return type
17+
fn fn_with_wrapping_return_type<T>(aaaaaa: f64, bbbbbb: T, cccccc: f64, dddddd: f64, eeee: f64) -> f64;
18+
19+
// Function that wraps at the where clause
20+
fn fn_with_wrapping_where_clause<T>(aaaaaa: f64, bbbbbb: T, cccccc: f64, dddddd: f64) -> f64 where T: Debug;
21+
22+
// Function with both wrapping return type and wrapping where clause
23+
fn fn_with_long_return_and_where<T, U, 'a>(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
24+
25+
// Function with wrapping arguments, return type, and where clause
26+
fn fn_with_everything_long<T, U, 'a>(aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64, ffff: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
27+
28+
// Same variations with bodies
29+
fn short_fn_with_body(a: f64, b: f64) -> f64 {}
30+
31+
fn fn_with_long_return_type_and_body(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> {}
32+
33+
fn fn_with_short_where_and_body<T>(a: f64, b: T) -> f64 where T: Debug {}
34+
35+
fn fn_with_wrapping_return_type_and_body<T>(aaaaaa: f64, bbbbbb: T, ccc: f64, ddd: f64, ee: f64) -> f64 {}
36+
37+
fn fn_with_wrapping_where_clause_and_body<T>(aaaaaa: f64, bbbbbb: T, ccc: f64, ddd: f64) -> f64 where T: Debug {}
38+
39+
fn fn_with_long_return_and_where_and_body<T, U, 'a>(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
40+
41+
fn fn_with_everything_long_and_body<T, U, 'a>(aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64, ffff: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
42+
43+
// Trait methods
44+
pub trait Trait {
45+
fn short_method(a: f64, b: f64) -> f64;
46+
47+
fn method_with_long_return(&self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>>;
48+
49+
fn method_with_short_where<T>(&self, a: f64, b: T) -> f64 where T: Debug;
50+
51+
fn method_with_wrapping_return_type<T>(self, aaa: f64, bbb: T, ccc: f64, ddd: f64, ee: f64) -> f64;
52+
53+
fn method_with_wrapping_where_clause<T>(aaaaaa: f64, bbbbbb: T, ccc: f64, ddd: f64) -> f64 where T: Debug;
54+
55+
fn method_with_long_return_and_where<T, U, 'a>(self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
56+
57+
fn method_with_everything_long<T, U, 'a>(&self, aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
58+
59+
// Same variations with bodies
60+
fn short_method_with_body(a: f64, b: f64) -> f64 {}
61+
62+
fn method_with_long_return_and_body(&self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> {}
63+
64+
fn method_with_short_where_and_body<T>(&self, a: f64, b: T) -> f64 where T: Debug {}
65+
66+
fn method_with_wrapping_return_type_and_body<T>(aaaa: f64, bb: T, cc: f64, d: f64, e: f64) -> f64 {}
67+
68+
fn method_with_wrapping_where_clause_and_body<T>(aaa: f64, bb: T, cc: f64, d: f64) -> f64 where T: Debug {}
69+
70+
fn method_with_long_return_and_where_and_body<T, U, 'a>(self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
71+
72+
fn method_with_everything_long_and_body<T, U, 'a>(aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
1673
}

tests/source/issue-6539/default.rs

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// rustfmt-style_edition: 2027
2+
// rustfmt-brace_style: PreferSameLine
3+
// rustfmt-where_single_line: false
4+
5+
// Top-level functions
6+
7+
// Short function
8+
fn short_fn(a: f64, b: f64) -> f64;
9+
10+
// Function with wrapping return type and no where clause
11+
fn fn_with_long_return_type(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>>;
12+
13+
// Function with non-wrapping return type and where clause
14+
fn fn_with_short_where<T>(a: f64, b: T) -> f64 where T: Debug;
15+
16+
// Function that wraps at a simple return type
17+
fn fn_with_wrapping_return_type<T>(aaaaaa: f64, bbbbbb: T, cccccc: f64, dddddd: f64, eeee: f64) -> f64;
18+
19+
// Function that wraps at the where clause
20+
fn fn_with_wrapping_where_clause<T>(aaaaaa: f64, bbbbbb: T, cccccc: f64, dddddd: f64) -> f64 where T: Debug;
21+
22+
// Function with both wrapping return type and wrapping where clause
23+
fn fn_with_long_return_and_where<T, U, 'a>(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
24+
25+
// Function with wrapping arguments, return type, and where clause
26+
fn fn_with_everything_long<T, U, 'a>(aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64, ffff: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
27+
28+
// Same variations with bodies
29+
fn short_fn_with_body(a: f64, b: f64) -> f64 {}
30+
31+
fn fn_with_long_return_type_and_body(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> {}
32+
33+
fn fn_with_short_where_and_body<T>(a: f64, b: T) -> f64 where T: Debug {}
34+
35+
fn fn_with_wrapping_return_type_and_body<T>(aaaaaa: f64, bbbbbb: T, ccc: f64, ddd: f64, ee: f64) -> f64 {}
36+
37+
fn fn_with_wrapping_where_clause_and_body<T>(aaaaaa: f64, bbbbbb: T, ccc: f64, ddd: f64) -> f64 where T: Debug {}
38+
39+
fn fn_with_long_return_and_where_and_body<T, U, 'a>(a: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
40+
41+
fn fn_with_everything_long_and_body<T, U, 'a>(aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64, ffff: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
42+
43+
// Trait methods
44+
pub trait Trait {
45+
fn short_method(a: f64, b: f64) -> f64;
46+
47+
fn method_with_long_return(&self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>>;
48+
49+
fn method_with_short_where<T>(&self, a: f64, b: T) -> f64 where T: Debug;
50+
51+
fn method_with_wrapping_return_type<T>(self, aaa: f64, bbb: T, ccc: f64, ddd: f64, ee: f64) -> f64;
52+
53+
fn method_with_wrapping_where_clause<T>(aaaaaa: f64, bbbbbb: T, ccc: f64, ddd: f64) -> f64 where T: Debug;
54+
55+
fn method_with_long_return_and_where<T, U, 'a>(self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
56+
57+
fn method_with_everything_long<T, U, 'a>(&self, aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator;
58+
59+
// Same variations with bodies
60+
fn short_method_with_body(a: f64, b: f64) -> f64 {}
61+
62+
fn method_with_long_return_and_body(&self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> {}
63+
64+
fn method_with_short_where_and_body<T>(&self, a: f64, b: T) -> f64 where T: Debug {}
65+
66+
fn method_with_wrapping_return_type_and_body<T>(aaaa: f64, bb: T, cc: f64, d: f64, e: f64) -> f64 {}
67+
68+
fn method_with_wrapping_where_clause_and_body<T>(aaa: f64, bb: T, cc: f64, d: f64) -> f64 where T: Debug {}
69+
70+
fn method_with_long_return_and_where_and_body<T, U, 'a>(self) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
71+
72+
fn method_with_everything_long_and_body<T, U, 'a>(aaaa: f64, bbbb: f64, cccc: f64, dddd: f64, eeee: f64) -> Result<HashMap<String, Vec<(SomeLongTypeName, AnotherLongTypeName, YetAnotherType)>>, Box<dyn Error + Send + Sync + 'static>> where T: Debug + Display + Clone + Send + Sync + 'static, U: Iterator<Item = &'a T> + ExactSizeIterator {}
73+
}

0 commit comments

Comments
 (0)