Skip to content

Commit d0b3bd1

Browse files
committed
Add fn_call_layout configuration option
Closes 5218 The `fn_call_layout` was added to give users more control over how function calls are formatted. This change will only impact function calls, and will not have any affect on method calls. The values are identical to those for `fn_args_layout`, which is a stable option that controls how function declarations are laid out.
1 parent 0cb294f commit d0b3bd1

File tree

16 files changed

+584
-4
lines changed

16 files changed

+584
-4
lines changed

Configurations.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,75 @@ trait Lorem {
756756

757757
See also [`fn_params_layout`](#fn_params_layout)
758758

759+
## `fn_call_layout`
760+
761+
Control the layout of arguments in function calls
762+
763+
- **Default value**: `"Tall"`
764+
- **Possible values**: `"Compressed"`, `"Tall"`, `"Vertical"`
765+
- **Stable**: No (tracking issue: N/A)
766+
767+
#### `"Tall"` (default):
768+
769+
```rust
770+
fn main() {
771+
lorem(ipsum, dolor, sit, amet);
772+
ipsum(
773+
dolor,
774+
sit,
775+
amet,
776+
consectetur,
777+
adipiscing,
778+
elit,
779+
vivamus,
780+
ipsum,
781+
orci,
782+
rhoncus,
783+
vel,
784+
imperdiet,
785+
);
786+
}
787+
```
788+
789+
#### `"Compressed"`:
790+
791+
```rust
792+
fn main() {
793+
lorem(ipsum, dolor, sit, amet);
794+
ipsum(
795+
dolor, sit, amet, consectetur, adipiscing, elit, vivamus, ipsum, orci, rhoncus, vel,
796+
imperdiet,
797+
);
798+
}
799+
```
800+
801+
#### `"Vertical"`:
802+
803+
```rust
804+
fn main() {
805+
lorem(
806+
ipsum,
807+
dolor,
808+
sit,
809+
amet,
810+
);
811+
ipsum(
812+
dolor,
813+
sit,
814+
amet,
815+
consectetur,
816+
adipiscing,
817+
elit,
818+
vivamus,
819+
ipsum,
820+
orci,
821+
rhoncus,
822+
vel,
823+
imperdiet,
824+
);
825+
}
826+
```
827+
759828
## `fn_call_width`
760829

761830
Maximum width of the args of a function call before falling back to vertical formatting.

src/attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ impl Rewrite for ast::MetaItem {
309309
} else {
310310
SeparatorTactic::Never
311311
}),
312+
None,
312313
)?
313314
}
314315
ast::MetaItemKind::NameValue(ref literal) => {

src/chains.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ impl ChainItem {
253253
format!("::<{}>", type_list.join(", "))
254254
};
255255
let callee_str = format!(".{}{}", rewrite_ident(context, method_name), type_str);
256-
rewrite_call(context, &callee_str, &args[1..], span, shape)
256+
rewrite_call(context, &callee_str, &args[1..], None, span, shape)
257257
}
258258
}
259259

src/config/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ create_config! {
127127
"(deprecated: use fn_params_layout instead)";
128128
fn_params_layout: Density, Density::Tall, true,
129129
"Control the layout of parameters in function signatures.";
130+
fn_call_layout: Density, Density::Tall, false,
131+
"Control the layout of arguments in a function call";
130132
brace_style: BraceStyle, BraceStyle::SameLineWhere, false, "Brace style for items";
131133
control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine, false,
132134
"Brace style for control flow constructs";
@@ -654,6 +656,7 @@ match_arm_blocks = true
654656
match_arm_leading_pipes = "Never"
655657
force_multiline_blocks = false
656658
fn_params_layout = "Tall"
659+
fn_call_layout = "Tall"
657660
brace_style = "SameLineWhere"
658661
control_brace_style = "AlwaysSameLine"
659662
trailing_semicolon = true

src/expr.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::comment::{
1212
combine_strs_with_missing_comments, contains_comment, recover_comment_removed, rewrite_comment,
1313
rewrite_missing_comment, CharClasses, FindUncommented,
1414
};
15-
use crate::config::lists::*;
15+
use crate::config::{lists::*, Density};
1616
use crate::config::{Config, ControlBraceStyle, HexLiteralCase, IndentStyle, Version};
1717
use crate::lists::{
1818
definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape,
@@ -89,7 +89,15 @@ pub(crate) fn format_expr(
8989
ast::ExprKind::Call(ref callee, ref args) => {
9090
let inner_span = mk_sp(callee.span.hi(), expr.span.hi());
9191
let callee_str = callee.rewrite(context, shape)?;
92-
rewrite_call(context, &callee_str, args, inner_span, shape)
92+
let force_list_tactic = Some(context.config.fn_call_layout());
93+
rewrite_call(
94+
context,
95+
&callee_str,
96+
args,
97+
force_list_tactic,
98+
inner_span,
99+
shape,
100+
)
93101
}
94102
ast::ExprKind::Paren(ref subexpr) => rewrite_paren(context, subexpr, shape, expr.span),
95103
ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
@@ -1264,6 +1272,7 @@ pub(crate) fn rewrite_call(
12641272
context: &RewriteContext<'_>,
12651273
callee: &str,
12661274
args: &[ptr::P<ast::Expr>],
1275+
force_list_tactic: Option<Density>,
12671276
span: Span,
12681277
shape: Shape,
12691278
) -> Option<String> {
@@ -1275,6 +1284,7 @@ pub(crate) fn rewrite_call(
12751284
span,
12761285
context.config.fn_call_width(),
12771286
choose_separator_tactic(context, span),
1287+
force_list_tactic,
12781288
)
12791289
}
12801290

@@ -1812,6 +1822,7 @@ pub(crate) fn rewrite_tuple<'a, T: 'a + IntoOverflowableItem<'a>>(
18121822
span,
18131823
context.config.fn_call_width(),
18141824
force_tactic,
1825+
None,
18151826
)
18161827
} else {
18171828
rewrite_tuple_in_visual_indent_style(context, items, span, shape, is_singleton_tuple)

src/items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,7 @@ fn format_tuple_struct(
14841484
mk_sp(lo, span.hi()),
14851485
context.config.fn_call_width(),
14861486
None,
1487+
None,
14871488
)?;
14881489
}
14891490

src/macros.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ fn rewrite_macro_inner(
279279
} else {
280280
Some(SeparatorTactic::Never)
281281
},
282+
None,
282283
)
283284
.map(|rw| match position {
284285
MacroPosition::Item => format!("{};", rw),

src/overflow.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use rustc_ast::{ast, ptr};
88
use rustc_span::Span;
99

1010
use crate::closures;
11-
use crate::config::lists::*;
1211
use crate::config::Version;
12+
use crate::config::{lists::*, Density};
1313
use crate::expr::{
1414
can_be_overflowed_expr, is_every_expr_simple, is_method_call, is_nested_call, is_simple_expr,
1515
rewrite_cond,
@@ -252,6 +252,7 @@ pub(crate) fn rewrite_with_parens<'a, T: 'a + IntoOverflowableItem<'a>>(
252252
span: Span,
253253
item_max_width: usize,
254254
force_separator_tactic: Option<SeparatorTactic>,
255+
force_list_tactic: Option<Density>,
255256
) -> Option<String> {
256257
Context::new(
257258
context,
@@ -263,6 +264,7 @@ pub(crate) fn rewrite_with_parens<'a, T: 'a + IntoOverflowableItem<'a>>(
263264
")",
264265
item_max_width,
265266
force_separator_tactic,
267+
force_list_tactic,
266268
None,
267269
)
268270
.rewrite(shape)
@@ -286,6 +288,7 @@ pub(crate) fn rewrite_with_angle_brackets<'a, T: 'a + IntoOverflowableItem<'a>>(
286288
context.config.max_width(),
287289
None,
288290
None,
291+
None,
289292
)
290293
.rewrite(shape)
291294
}
@@ -314,6 +317,7 @@ pub(crate) fn rewrite_with_square_brackets<'a, T: 'a + IntoOverflowableItem<'a>>
314317
rhs,
315318
context.config.array_width(),
316319
force_separator_tactic,
320+
None,
317321
Some(("[", "]")),
318322
)
319323
.rewrite(shape)
@@ -331,6 +335,7 @@ struct Context<'a> {
331335
item_max_width: usize,
332336
one_line_width: usize,
333337
force_separator_tactic: Option<SeparatorTactic>,
338+
force_list_tactic: Option<Density>,
334339
custom_delims: Option<(&'a str, &'a str)>,
335340
}
336341

@@ -345,6 +350,7 @@ impl<'a> Context<'a> {
345350
suffix: &'static str,
346351
item_max_width: usize,
347352
force_separator_tactic: Option<SeparatorTactic>,
353+
force_list_tactic: Option<Density>,
348354
custom_delims: Option<(&'a str, &'a str)>,
349355
) -> Context<'a> {
350356
let used_width = extra_offset(ident, shape);
@@ -369,6 +375,7 @@ impl<'a> Context<'a> {
369375
item_max_width,
370376
one_line_width,
371377
force_separator_tactic,
378+
force_list_tactic,
372379
custom_delims,
373380
}
374381
}
@@ -584,6 +591,34 @@ impl<'a> Context<'a> {
584591
_ => (),
585592
}
586593

594+
// we only care if the any element but the last has a sigle line comment
595+
let any_but_last_contains_line_comment = list_items
596+
.iter()
597+
.rev()
598+
.skip(1)
599+
.any(|item| item.has_single_line_comment());
600+
601+
match self.force_list_tactic {
602+
Some(Density::Tall)
603+
if tactic == DefinitiveListTactic::Mixed && any_but_last_contains_line_comment =>
604+
{
605+
// If we determined a `Mixed` layout, but we configured tall then force
606+
// the tactic to be vertical only if any of the items contain single line comments.
607+
// Otherwise, the tacitc was properly set above.
608+
tactic = DefinitiveListTactic::Vertical
609+
}
610+
Some(Density::Compressed) if tactic != DefinitiveListTactic::Horizontal => {
611+
// Only force a mixed layout if we haven't already decided on going horizontal
612+
tactic = DefinitiveListTactic::Mixed
613+
}
614+
// If we need to force a `Vertical` layout, we should only do so if there are
615+
// at least 2 items for us to format. Otherwise, use the tactic already determined.
616+
Some(Density::Vertical) if self.items.len() > 1 => {
617+
tactic = DefinitiveListTactic::Vertical;
618+
}
619+
_ => {}
620+
};
621+
587622
tactic
588623
}
589624

src/patterns.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@ fn rewrite_tuple_pat(
494494
} else {
495495
None
496496
},
497+
None,
497498
)
498499
}
499500

src/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,7 @@ impl Rewrite for ast::Ty {
844844
context,
845845
"typeof",
846846
&[anon_const.value.clone()],
847+
None,
847848
self.span,
848849
shape,
849850
),
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// rustfmt-fn_call_layout:Compressed
2+
3+
fn main() {
4+
empty_args();
5+
single_arg(ipsum);
6+
two_args(ipsum, dolor);
7+
8+
lorem(ipsum, dolor, sit, amet);
9+
lorem(ipsum, // some inine comment
10+
dolor, sit, amet);
11+
lorem(ipsum, /* some inine comment */
12+
dolor, sit, amet);
13+
ipsum(dolor, sit, amet, consectetur, adipiscing, elit, vivamus, ipsum, orci, rhoncus, vel, imperdiet);
14+
15+
// issue 2010
16+
let a = i8x32::new(
17+
0, 1, -1, 2,
18+
-2, 3, -3, 4,
19+
-4, 5, -5, std::i8::MAX,
20+
std::i8::MIN + 1, 100, -100, -32,
21+
0, 1, -1, 2,
22+
-2, 3, -3, 4,
23+
-4, 5, -5, std::i8::MAX,
24+
std::i8::MIN + 1, 100, -100, -32);
25+
26+
// issue 4146
27+
return_monitor_err(
28+
e,
29+
channel_state,
30+
chan,
31+
order,
32+
commitment_update.is_some(),
33+
revoke_and_ack.is_some(),
34+
);
35+
36+
37+
// other examples with more complex args
38+
more_complex_args(
39+
|a, b, c| {if a == 998765390 {- b * 3 } else {c} },
40+
std::ops::Range { start: 3, end: 5 },
41+
std::i8::MAX, String::from(" hello world!!").as_bytes(),
42+
thread::Builder::new()
43+
.name("thread1".to_string())
44+
.spawn(move || {
45+
use std::sync::Arc;
46+
47+
let mut values = Arc::<[u32]>::new_uninit_slice(3);
48+
49+
// Deferred initialization:
50+
let data = Arc::get_mut(&mut values).unwrap();
51+
data[0].write(1);
52+
data[1].write(2);
53+
data[2].write(3);
54+
55+
let values = unsafe { values.assume_init() };
56+
}), "another argument"
57+
)
58+
}

0 commit comments

Comments
 (0)