Skip to content

Add fn_call_layout configuration option #5337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,97 @@ trait Lorem {

See also [`fn_params_layout`](#fn_params_layout)

## `fn_call_layout`

Control the layout of arguments in function calls

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

#### `"Foo"` (default):

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

#### `"Tall"`:

```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: OverflowDensity, OverflowDensity::Foo, 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 = "Foo"
brace_style = "SameLineWhere"
control_brace_style = "AlwaysSameLine"
trailing_semicolon = true
Expand Down
16 changes: 16 additions & 0 deletions src/config/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ pub enum Density {
Vertical,
}

#[config_type]
/// allows users to specify a density for list-like items.
/// Currently only supports function arguments.
pub enum OverflowDensity {
/// To prevent breaking formatting changes, this option follows the default behavior for
/// list-like items that can overflow.
Foo,
/// Fit as much on one line as possible before wrapping to the next line.
Compressed,
/// Items are placed horizontally as long as there is sufficient space and there aren't
/// any line comments that would force a Vertical layout.
Tall,
/// Place every item on a separate line. There must be at least two items in the list.
Vertical,
}

#[config_type]
/// Spacing around type combinators.
pub enum TypeDensity {
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::*, OverflowDensity};
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<OverflowDensity>,
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 @@ -1488,6 +1488,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
39 changes: 38 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::*, OverflowDensity};
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<OverflowDensity>,
) -> 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<OverflowDensity>,
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<OverflowDensity>,
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,36 @@ 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(OverflowDensity::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(OverflowDensity::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(OverflowDensity::Vertical) if self.items.len() > 1 => {
tactic = DefinitiveListTactic::Vertical;
}
// Default behavior for calls to match rustfmts pre `fn_call_layout` formatting.
Some(OverflowDensity::Foo) => {}
_ => {}
};

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
Loading