Skip to content

Commit 85dcf16

Browse files
committed
Allow generic arguments in chain method calls to overflow
Fixes 5249 Previously, we always formatted generic arguments horizontally. Now, we attempt to format generic items horizontally, but when doing so would lead to issue like exceeding the `max_width` we format the generic arguments vertically.
1 parent 272fb42 commit 85dcf16

12 files changed

+407
-8
lines changed

src/chains.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ use crate::config::{IndentStyle, Version};
6666
use crate::expr::rewrite_call;
6767
use crate::lists::extract_pre_comment;
6868
use crate::macros::convert_try_mac;
69+
use crate::overflow::rewrite_with_angle_brackets;
6970
use crate::rewrite::{Rewrite, RewriteContext};
7071
use crate::shape::Shape;
7172
use crate::source_map::SpanUtils;
@@ -242,21 +243,29 @@ impl ChainItem {
242243
context: &RewriteContext<'_>,
243244
shape: Shape,
244245
) -> Option<String> {
246+
let callee_str = rewrite_ident(context, method_name);
245247
let type_str = if types.is_empty() {
246248
String::new()
247249
} else {
248-
let type_list = types
249-
.iter()
250-
.map(|ty| ty.rewrite(context, shape))
251-
.collect::<Option<Vec<_>>>()?;
252-
253-
format!("::<{}>", type_list.join(", "))
250+
// subtract `{callee_str}::<>()` from the shape. We can only place everything on a
251+
// single line if there's enough room for the callee, turbofish, generic args, and ()
252+
let shape = shape.sub_width(callee_str.len() + 6)?;
253+
rewrite_generic_args(types, span, context, shape)?
254254
};
255-
let callee_str = format!(".{}{}", rewrite_ident(context, method_name), type_str);
255+
let callee_str = format!(".{}{}", callee_str, type_str);
256256
rewrite_call(context, &callee_str, &args[1..], span, shape)
257257
}
258258
}
259259

260+
fn rewrite_generic_args(
261+
types: &[ast::GenericArg],
262+
span: Span,
263+
context: &RewriteContext<'_>,
264+
shape: Shape,
265+
) -> Option<String> {
266+
rewrite_with_angle_brackets(context, "::", types.iter(), shape, span)
267+
}
268+
260269
#[derive(Debug)]
261270
struct Chain {
262271
parent: ChainItem,

src/overflow.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const SPECIAL_ATTR_WHITELIST: &[(&str, usize)] = &[
7171
pub(crate) enum OverflowableItem<'a> {
7272
Expr(&'a ast::Expr),
7373
GenericParam(&'a ast::GenericParam),
74+
GenericArg(&'a ast::GenericArg),
7475
MacroArg(&'a MacroArg),
7576
NestedMetaItem(&'a ast::NestedMetaItem),
7677
SegmentParam(&'a SegmentParam<'a>),
@@ -110,6 +111,7 @@ impl<'a> OverflowableItem<'a> {
110111
{
111112
match self {
112113
OverflowableItem::Expr(expr) => f(*expr),
114+
OverflowableItem::GenericArg(ga) => f(*ga),
113115
OverflowableItem::GenericParam(gp) => f(*gp),
114116
OverflowableItem::MacroArg(macro_arg) => f(*macro_arg),
115117
OverflowableItem::NestedMetaItem(nmi) => f(*nmi),
@@ -234,7 +236,15 @@ macro_rules! impl_into_overflowable_item_for_rustfmt_types {
234236
}
235237
}
236238

237-
impl_into_overflowable_item_for_ast_node!(Expr, GenericParam, NestedMetaItem, FieldDef, Ty, Pat);
239+
impl_into_overflowable_item_for_ast_node!(
240+
Expr,
241+
GenericArg,
242+
GenericParam,
243+
NestedMetaItem,
244+
FieldDef,
245+
Ty,
246+
Pat
247+
);
238248
impl_into_overflowable_item_for_rustfmt_types!([MacroArg], [SegmentParam, TuplePatField]);
239249

240250
pub(crate) fn into_overflowable_list<'a, T>(

tests/source/issue-5249/issue_5249.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
fn long_generic_args_list() {
2+
x.f::<
3+
A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
4+
A, A, A, A, A, A, A, A, A, A, A, A,
5+
>();
6+
}
7+
8+
fn long_items_in_generic_args_list() {
9+
x.f::<
10+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
11+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
12+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>
13+
>();
14+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
fn chained_method_calls_short_generic_args_list_long_method_args_list() {
2+
x.f::<A, B, C>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE).g::<A, B, C>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE);
3+
}
4+
5+
fn chained_method_calls_short_generic_args_list_long_method_args_list_with_inline_comments() {
6+
x.f::<
7+
A, // Something about arg A
8+
B,
9+
C,
10+
>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE).g::<
11+
A, // Something about arg A
12+
B,
13+
C,
14+
>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE);
15+
}
16+
17+
fn chained_method_calls_short_generic_args_list_long_method_args_list_with_inline_comments_in_both_lists(
18+
) {
19+
x.f::<
20+
A, // Something about arg A
21+
B,
22+
C,
23+
>(
24+
AAAAAAAA, BBBBBBBBB, // Something about arg BBBBBBBBB
25+
CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE,
26+
).g::<
27+
A, // Something about arg A
28+
B,
29+
C,
30+
>(
31+
AAAAAAAA, BBBBBBBBB, // Something about arg BBBBBBBBB
32+
CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE,
33+
);
34+
}
35+
36+
fn chained_method_calls_short_generic_args_list_long_method_args_list_with_block_comments() {
37+
x.f::<A /* Something about arg A */, B, C>(
38+
AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE,
39+
).g::<A /* Something about arg A */, B, C>(
40+
AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE,
41+
);
42+
}
43+
44+
fn chained_method_calls_short_generic_args_list_long_method_args_list_with_block_comments_in_both_lists(
45+
) {
46+
x.f::<A /* Something about arg A */, B, C>(
47+
AAAAAAAA, BBBBBBBBB, /* Something about arg BBBBBBBBB */ CCCCCCCCC, DDDDDDDDDD,
48+
EEEEEEEEEE,
49+
).g::<A /* Something about arg A */, B, C>(
50+
AAAAAAAA, BBBBBBBBB, /* Something about arg BBBBBBBBB */ CCCCCCCCC, DDDDDDDDDD,
51+
EEEEEEEEEE,
52+
);
53+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
fn short_generic_args_list() {
2+
x.f::<
3+
A,
4+
B, C
5+
>();
6+
}
7+
8+
fn short_generic_args_list_with_inline_comments() {
9+
x.f::<
10+
A, // Something about arg A
11+
B, C
12+
>();
13+
}
14+
15+
fn short_generic_args_list_with_block_comments() {
16+
x.f::<
17+
A, /* Something about arg A */
18+
B, C
19+
>();
20+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
fn long_items_in_generic_args_list_inline_comment() {
2+
x.f::<
3+
// Pre comment
4+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>, // Inline
5+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
6+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
7+
// Post Comment
8+
>();
9+
}
10+
11+
fn long_items_in_generic_args_list_multi_line_inline_comment() {
12+
x.f::<
13+
// Pre comment
14+
// Pre comment
15+
// Pre comment
16+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>, // Inline
17+
// Inline
18+
// Inline
19+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
20+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
21+
// Post Comment
22+
// Post Comment
23+
// Post Comment
24+
>();
25+
}
26+
27+
fn long_items_in_generic_args_list_block_comment() {
28+
x.f::<
29+
/* Pre comment */
30+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>, /* Inline */
31+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
32+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
33+
/* Post Comment */
34+
>();
35+
}
36+
37+
fn long_items_in_generic_args_list_multi_line_block_comment() {
38+
x.f::<
39+
/* Pre comment
40+
* Pre comment
41+
* Pre comment
42+
*/
43+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>, /* Inline
44+
* Inline
45+
* Inline
46+
*/
47+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
48+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
49+
/* Post Comment
50+
* Post Comment
51+
* Post Comment
52+
*/
53+
>();
54+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
fn short_generic_args_list_long_method_args_list() {
2+
x.f::<
3+
A,
4+
B, C
5+
>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE);
6+
}
7+
8+
fn short_generic_args_list_long_method_args_list_with_inline_comments() {
9+
x.f::<
10+
A, // Something about arg A
11+
B, C
12+
>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE);
13+
}
14+
15+
fn short_generic_args_list_long_method_args_list_with_inline_comments_in_both_lists() {
16+
x.f::<
17+
A, // Something about arg A
18+
B, C
19+
>(AAAAAAAA, BBBBBBBBB, // Something about arg BBBBBBBBB
20+
CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE);
21+
}
22+
23+
fn short_generic_args_list_long_method_args_list_with_block_comments() {
24+
x.f::<
25+
A, /* Something about arg A */
26+
B, C
27+
>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE);
28+
}
29+
30+
fn short_generic_args_list_long_method_args_list_with_block_comments_in_both_lists() {
31+
x.f::<
32+
A, /* Something about arg A */
33+
B, C
34+
>(AAAAAAAA, BBBBBBBBB, /* Something about arg BBBBBBBBB */ CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE);
35+
}

tests/target/issue-5249/issue_5249.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
fn long_generic_args_list() {
2+
x.f::<
3+
A,
4+
A,
5+
A,
6+
A,
7+
A,
8+
A,
9+
A,
10+
A,
11+
A,
12+
A,
13+
A,
14+
A,
15+
A,
16+
A,
17+
A,
18+
A,
19+
A,
20+
A,
21+
A,
22+
A,
23+
A,
24+
A,
25+
A,
26+
A,
27+
A,
28+
A,
29+
A,
30+
A,
31+
A,
32+
A,
33+
>();
34+
}
35+
36+
fn long_items_in_generic_args_list() {
37+
x.f::<
38+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
39+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
40+
AAAA<BBBB::CCCC, (DDDD, EEEE), FFFF>,
41+
>();
42+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
fn chained_method_calls_short_generic_args_list_long_method_args_list() {
2+
x.f::<A, B, C>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE)
3+
.g::<A, B, C>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE);
4+
}
5+
6+
fn chained_method_calls_short_generic_args_list_long_method_args_list_with_inline_comments() {
7+
x.f::<
8+
A, // Something about arg A
9+
B,
10+
C,
11+
>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE)
12+
.g::<
13+
A, // Something about arg A
14+
B,
15+
C,
16+
>(AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE);
17+
}
18+
19+
fn chained_method_calls_short_generic_args_list_long_method_args_list_with_inline_comments_in_both_lists(
20+
) {
21+
x.f::<
22+
A, // Something about arg A
23+
B,
24+
C,
25+
>(
26+
AAAAAAAA, BBBBBBBBB, // Something about arg BBBBBBBBB
27+
CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE,
28+
)
29+
.g::<
30+
A, // Something about arg A
31+
B,
32+
C,
33+
>(
34+
AAAAAAAA, BBBBBBBBB, // Something about arg BBBBBBBBB
35+
CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE,
36+
);
37+
}
38+
39+
fn chained_method_calls_short_generic_args_list_long_method_args_list_with_block_comments() {
40+
x.f::<A /* Something about arg A */, B, C>(
41+
AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE,
42+
)
43+
.g::<A /* Something about arg A */, B, C>(
44+
AAAAAAAA, BBBBBBBBB, CCCCCCCCC, DDDDDDDDDD, EEEEEEEEEE,
45+
);
46+
}
47+
48+
fn chained_method_calls_short_generic_args_list_long_method_args_list_with_block_comments_in_both_lists(
49+
) {
50+
x.f::<A /* Something about arg A */, B, C>(
51+
AAAAAAAA, BBBBBBBBB, /* Something about arg BBBBBBBBB */ CCCCCCCCC, DDDDDDDDDD,
52+
EEEEEEEEEE,
53+
)
54+
.g::<A /* Something about arg A */, B, C>(
55+
AAAAAAAA, BBBBBBBBB, /* Something about arg BBBBBBBBB */ CCCCCCCCC, DDDDDDDDDD,
56+
EEEEEEEEEE,
57+
);
58+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
fn short_generic_args_list() {
2+
x.f::<A, B, C>();
3+
}
4+
5+
fn short_generic_args_list_with_inline_comments() {
6+
x.f::<
7+
A, // Something about arg A
8+
B,
9+
C,
10+
>();
11+
}
12+
13+
fn short_generic_args_list_with_block_comments() {
14+
x.f::<A /* Something about arg A */, B, C>();
15+
}

0 commit comments

Comments
 (0)