Skip to content

Commit

Permalink
Add fn_call_layout configuration option
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ytmimi committed Jul 14, 2022
1 parent 0cb294f commit d0b3bd1
Show file tree
Hide file tree
Showing 16 changed files with 584 additions and 4 deletions.
69 changes: 69 additions & 0 deletions Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,75 @@ trait Lorem {

See also [`fn_params_layout`](#fn_params_layout)

## `fn_call_layout`

Control the layout of arguments in function calls

- **Default value**: `"Tall"`
- **Possible values**: `"Compressed"`, `"Tall"`, `"Vertical"`
- **Stable**: No (tracking issue: N/A)

#### `"Tall"` (default):

```rust
fn main() {
lorem(ipsum, dolor, sit, amet);
ipsum(
dolor,
sit,
amet,
consectetur,
adipiscing,
elit,
vivamus,
ipsum,
orci,
rhoncus,
vel,
imperdiet,
);
}
```

#### `"Compressed"`:

```rust
fn main() {
lorem(ipsum, dolor, sit, amet);
ipsum(
dolor, sit, amet, consectetur, adipiscing, elit, vivamus, ipsum, orci, rhoncus, vel,
imperdiet,
);
}
```

#### `"Vertical"`:

```rust
fn main() {
lorem(
ipsum,
dolor,
sit,
amet,
);
ipsum(
dolor,
sit,
amet,
consectetur,
adipiscing,
elit,
vivamus,
ipsum,
orci,
rhoncus,
vel,
imperdiet,
);
}
```

## `fn_call_width`

Maximum width of the args of a function call before falling back to vertical formatting.
Expand Down
1 change: 1 addition & 0 deletions src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ impl Rewrite for ast::MetaItem {
} else {
SeparatorTactic::Never
}),
None,
)?
}
ast::MetaItemKind::NameValue(ref literal) => {
Expand Down
2 changes: 1 addition & 1 deletion src/chains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ impl ChainItem {
format!("::<{}>", type_list.join(", "))
};
let callee_str = format!(".{}{}", rewrite_ident(context, method_name), type_str);
rewrite_call(context, &callee_str, &args[1..], span, shape)
rewrite_call(context, &callee_str, &args[1..], None, span, shape)
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ create_config! {
"(deprecated: use fn_params_layout instead)";
fn_params_layout: Density, Density::Tall, true,
"Control the layout of parameters in function signatures.";
fn_call_layout: Density, Density::Tall, false,
"Control the layout of arguments in a function call";
brace_style: BraceStyle, BraceStyle::SameLineWhere, false, "Brace style for items";
control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine, false,
"Brace style for control flow constructs";
Expand Down Expand Up @@ -654,6 +656,7 @@ match_arm_blocks = true
match_arm_leading_pipes = "Never"
force_multiline_blocks = false
fn_params_layout = "Tall"
fn_call_layout = "Tall"
brace_style = "SameLineWhere"
control_brace_style = "AlwaysSameLine"
trailing_semicolon = true
Expand Down
15 changes: 13 additions & 2 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::comment::{
combine_strs_with_missing_comments, contains_comment, recover_comment_removed, rewrite_comment,
rewrite_missing_comment, CharClasses, FindUncommented,
};
use crate::config::lists::*;
use crate::config::{lists::*, Density};
use crate::config::{Config, ControlBraceStyle, HexLiteralCase, IndentStyle, Version};
use crate::lists::{
definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape,
Expand Down Expand Up @@ -89,7 +89,15 @@ pub(crate) fn format_expr(
ast::ExprKind::Call(ref callee, ref args) => {
let inner_span = mk_sp(callee.span.hi(), expr.span.hi());
let callee_str = callee.rewrite(context, shape)?;
rewrite_call(context, &callee_str, args, inner_span, shape)
let force_list_tactic = Some(context.config.fn_call_layout());
rewrite_call(
context,
&callee_str,
args,
force_list_tactic,
inner_span,
shape,
)
}
ast::ExprKind::Paren(ref subexpr) => rewrite_paren(context, subexpr, shape, expr.span),
ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
Expand Down Expand Up @@ -1264,6 +1272,7 @@ pub(crate) fn rewrite_call(
context: &RewriteContext<'_>,
callee: &str,
args: &[ptr::P<ast::Expr>],
force_list_tactic: Option<Density>,
span: Span,
shape: Shape,
) -> Option<String> {
Expand All @@ -1275,6 +1284,7 @@ pub(crate) fn rewrite_call(
span,
context.config.fn_call_width(),
choose_separator_tactic(context, span),
force_list_tactic,
)
}

Expand Down Expand Up @@ -1812,6 +1822,7 @@ pub(crate) fn rewrite_tuple<'a, T: 'a + IntoOverflowableItem<'a>>(
span,
context.config.fn_call_width(),
force_tactic,
None,
)
} else {
rewrite_tuple_in_visual_indent_style(context, items, span, shape, is_singleton_tuple)
Expand Down
1 change: 1 addition & 0 deletions src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1484,6 +1484,7 @@ fn format_tuple_struct(
mk_sp(lo, span.hi()),
context.config.fn_call_width(),
None,
None,
)?;
}

Expand Down
1 change: 1 addition & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ fn rewrite_macro_inner(
} else {
Some(SeparatorTactic::Never)
},
None,
)
.map(|rw| match position {
MacroPosition::Item => format!("{};", rw),
Expand Down
37 changes: 36 additions & 1 deletion src/overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use rustc_ast::{ast, ptr};
use rustc_span::Span;

use crate::closures;
use crate::config::lists::*;
use crate::config::Version;
use crate::config::{lists::*, Density};
use crate::expr::{
can_be_overflowed_expr, is_every_expr_simple, is_method_call, is_nested_call, is_simple_expr,
rewrite_cond,
Expand Down Expand Up @@ -252,6 +252,7 @@ pub(crate) fn rewrite_with_parens<'a, T: 'a + IntoOverflowableItem<'a>>(
span: Span,
item_max_width: usize,
force_separator_tactic: Option<SeparatorTactic>,
force_list_tactic: Option<Density>,
) -> Option<String> {
Context::new(
context,
Expand All @@ -263,6 +264,7 @@ pub(crate) fn rewrite_with_parens<'a, T: 'a + IntoOverflowableItem<'a>>(
")",
item_max_width,
force_separator_tactic,
force_list_tactic,
None,
)
.rewrite(shape)
Expand All @@ -286,6 +288,7 @@ pub(crate) fn rewrite_with_angle_brackets<'a, T: 'a + IntoOverflowableItem<'a>>(
context.config.max_width(),
None,
None,
None,
)
.rewrite(shape)
}
Expand Down Expand Up @@ -314,6 +317,7 @@ pub(crate) fn rewrite_with_square_brackets<'a, T: 'a + IntoOverflowableItem<'a>>
rhs,
context.config.array_width(),
force_separator_tactic,
None,
Some(("[", "]")),
)
.rewrite(shape)
Expand All @@ -331,6 +335,7 @@ struct Context<'a> {
item_max_width: usize,
one_line_width: usize,
force_separator_tactic: Option<SeparatorTactic>,
force_list_tactic: Option<Density>,
custom_delims: Option<(&'a str, &'a str)>,
}

Expand All @@ -345,6 +350,7 @@ impl<'a> Context<'a> {
suffix: &'static str,
item_max_width: usize,
force_separator_tactic: Option<SeparatorTactic>,
force_list_tactic: Option<Density>,
custom_delims: Option<(&'a str, &'a str)>,
) -> Context<'a> {
let used_width = extra_offset(ident, shape);
Expand All @@ -369,6 +375,7 @@ impl<'a> Context<'a> {
item_max_width,
one_line_width,
force_separator_tactic,
force_list_tactic,
custom_delims,
}
}
Expand Down Expand Up @@ -584,6 +591,34 @@ impl<'a> Context<'a> {
_ => (),
}

// we only care if the any element but the last has a sigle line comment
let any_but_last_contains_line_comment = list_items
.iter()
.rev()
.skip(1)
.any(|item| item.has_single_line_comment());

match self.force_list_tactic {
Some(Density::Tall)
if tactic == DefinitiveListTactic::Mixed && any_but_last_contains_line_comment =>
{
// If we determined a `Mixed` layout, but we configured tall then force
// the tactic to be vertical only if any of the items contain single line comments.
// Otherwise, the tacitc was properly set above.
tactic = DefinitiveListTactic::Vertical
}
Some(Density::Compressed) if tactic != DefinitiveListTactic::Horizontal => {
// Only force a mixed layout if we haven't already decided on going horizontal
tactic = DefinitiveListTactic::Mixed
}
// If we need to force a `Vertical` layout, we should only do so if there are
// at least 2 items for us to format. Otherwise, use the tactic already determined.
Some(Density::Vertical) if self.items.len() > 1 => {
tactic = DefinitiveListTactic::Vertical;
}
_ => {}
};

tactic
}

Expand Down
1 change: 1 addition & 0 deletions src/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ fn rewrite_tuple_pat(
} else {
None
},
None,
)
}

Expand Down
1 change: 1 addition & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ impl Rewrite for ast::Ty {
context,
"typeof",
&[anon_const.value.clone()],
None,
self.span,
shape,
),
Expand Down
58 changes: 58 additions & 0 deletions tests/source/configs/fn_call_layout/compressed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// rustfmt-fn_call_layout:Compressed

fn main() {
empty_args();
single_arg(ipsum);
two_args(ipsum, dolor);

lorem(ipsum, dolor, sit, amet);
lorem(ipsum, // some inine comment
dolor, sit, amet);
lorem(ipsum, /* some inine comment */
dolor, sit, amet);
ipsum(dolor, sit, amet, consectetur, adipiscing, elit, vivamus, ipsum, orci, rhoncus, vel, imperdiet);

// issue 2010
let a = i8x32::new(
0, 1, -1, 2,
-2, 3, -3, 4,
-4, 5, -5, std::i8::MAX,
std::i8::MIN + 1, 100, -100, -32,
0, 1, -1, 2,
-2, 3, -3, 4,
-4, 5, -5, std::i8::MAX,
std::i8::MIN + 1, 100, -100, -32);

// issue 4146
return_monitor_err(
e,
channel_state,
chan,
order,
commitment_update.is_some(),
revoke_and_ack.is_some(),
);


// other examples with more complex args
more_complex_args(
|a, b, c| {if a == 998765390 {- b * 3 } else {c} },
std::ops::Range { start: 3, end: 5 },
std::i8::MAX, String::from(" hello world!!").as_bytes(),
thread::Builder::new()
.name("thread1".to_string())
.spawn(move || {
use std::sync::Arc;

let mut values = Arc::<[u32]>::new_uninit_slice(3);

// Deferred initialization:
let data = Arc::get_mut(&mut values).unwrap();
data[0].write(1);
data[1].write(2);
data[2].write(3);

let values = unsafe { values.assume_init() };
}), "another argument"
)
}
Loading

0 comments on commit d0b3bd1

Please sign in to comment.