Skip to content

Commit 90d937c

Browse files
KAAtheWiseGitytmimi
andcommitted
feat: add match_arm_indent option
Allows to disable the indentation of match arms. Related issue: #2937 Co-authored-by: Yacin Tmimi <[email protected]>
1 parent ee329d3 commit 90d937c

File tree

8 files changed

+138
-7
lines changed

8 files changed

+138
-7
lines changed

Configurations.md

+36
Original file line numberDiff line numberDiff line change
@@ -1862,6 +1862,42 @@ fn foo() {
18621862
}
18631863
```
18641864

1865+
## `match_arm_indent`
1866+
1867+
Controls whether match arms are indented. If disabled, match arms will be formatted at the same indentation level as the outer `match` statement. Meaning that match blocks will only be indented once, not twice.
1868+
1869+
- **Default value**: `true`
1870+
- **Possible values**: `true`, `false`
1871+
- **Stable**: No (TODO tracking issue)
1872+
1873+
#### `true` (default):
1874+
1875+
```rust
1876+
fn main() {
1877+
match value {
1878+
Enum::A => {
1879+
let mut work = first();
1880+
work += second();
1881+
}
1882+
Enum::B => short_work(),
1883+
}
1884+
}
1885+
```
1886+
1887+
#### `false`:
1888+
1889+
```rust
1890+
fn main() {
1891+
match value {
1892+
Enum::A => {
1893+
let mut work = first();
1894+
work += second();
1895+
}
1896+
Enum::B => short_work(),
1897+
}
1898+
}
1899+
```
1900+
18651901
## `match_block_trailing_comma`
18661902

18671903
Put a trailing comma after a block based match arm (non-block arms are not affected)

src/config/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ create_config! {
131131
on the same line with the pattern of arms";
132132
match_arm_leading_pipes: MatchArmLeadingPipeConfig, true,
133133
"Determines whether leading pipes are emitted on match arms";
134+
match_arm_indent: MatchArmIndent, false,
135+
"Determines whether match arms are indented";
134136
force_multiline_blocks: ForceMultilineBlocks, false,
135137
"Force multiline closure bodies and match arms to be wrapped in a block";
136138
fn_args_layout: FnArgsLayout, true,
@@ -803,6 +805,7 @@ struct_field_align_threshold = 0
803805
enum_discrim_align_threshold = 0
804806
match_arm_blocks = true
805807
match_arm_leading_pipes = "Never"
808+
match_arm_indent = true
806809
force_multiline_blocks = false
807810
fn_params_layout = "Tall"
808811
brace_style = "SameLineWhere"
@@ -894,6 +897,7 @@ struct_field_align_threshold = 0
894897
enum_discrim_align_threshold = 0
895898
match_arm_blocks = true
896899
match_arm_leading_pipes = "Never"
900+
match_arm_indent = true
897901
force_multiline_blocks = false
898902
fn_params_layout = "Tall"
899903
brace_style = "SameLineWhere"

src/config/options.rs

+1
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ config_option_with_style_edition_default!(
665665
EnumDiscrimAlignThreshold, usize, _ => 0;
666666
MatchArmBlocks, bool, _ => true;
667667
MatchArmLeadingPipeConfig, MatchArmLeadingPipe, _ => MatchArmLeadingPipe::Never;
668+
MatchArmIndent, bool, _ => true;
668669
ForceMultilineBlocks, bool, _ => false;
669670
FnArgsLayout, Density, _ => Density::Tall;
670671
FnParamsLayout, Density, _ => Density::Tall;

src/matches.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,22 @@ pub(crate) fn rewrite_match(
100100
_ => " ",
101101
};
102102

103-
let nested_indent_str = shape
104-
.indent
105-
.block_indent(context.config)
106-
.to_string(context.config);
103+
let nested_indent = if context.config.match_arm_indent() {
104+
shape.indent.block_indent(context.config)
105+
} else {
106+
shape.indent
107+
};
108+
let nested_indent_str = nested_indent.to_string(context.config);
109+
107110
// Inner attributes.
108111
let inner_attrs = &inner_attributes(attrs);
109112
let inner_attrs_str = if inner_attrs.is_empty() {
110113
String::new()
111114
} else {
112115
let shape = if context.config.style_edition() <= StyleEdition::Edition2021 {
113116
shape
117+
} else if !context.config.match_arm_indent() {
118+
shape
114119
} else {
115120
shape.block_indent(context.config.tab_spaces())
116121
};
@@ -204,9 +209,12 @@ fn rewrite_match_arms(
204209
span: Span,
205210
open_brace_pos: BytePos,
206211
) -> RewriteResult {
207-
let arm_shape = shape
208-
.block_indent(context.config.tab_spaces())
209-
.with_max_width(context.config);
212+
let arm_shape = if context.config.match_arm_indent() {
213+
shape.block_indent(context.config.tab_spaces())
214+
} else {
215+
shape
216+
}
217+
.with_max_width(context.config);
210218

211219
let arm_len = arms.len();
212220
let is_last_iter = repeat(false)

tests/source/match-unindent.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// rustfmt-match_arm_indent: false
2+
// Unindent the match arms
3+
4+
fn foo() {
5+
match x {
6+
a => {
7+
"line1";
8+
"line2"
9+
}
10+
ThisIsA::Guard if true => {
11+
"line1";
12+
"line2"
13+
}
14+
ThisIsA::ReallyLongPattern(ThatWillForce::TheGuard, ToWrapOnto::TheFollowingLine) if true => {
15+
"line1";
16+
"line2"
17+
}
18+
}
19+
}

tests/target/match-noindent-tab.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// rustfmt-match_arm_indent: false
2+
// rustfmt-hard_tabs: true
3+
// rustfmt-tab_spaces: 8
4+
5+
// Large-indentation style, brought to you by the Linux kernel
6+
fn foo() {
7+
match value {
8+
0 => {
9+
"one";
10+
"two";
11+
}
12+
1 | 2 | 3 => {
13+
"line1";
14+
"line2";
15+
}
16+
100..1000 => oneline(),
17+
18+
_ => {
19+
// catch-all
20+
todo!();
21+
}
22+
}
23+
}

tests/target/match-noindent.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// rustfmt-match_arm_indent: false
2+
// Don't indent the match arms
3+
4+
fn foo() {
5+
match value {
6+
0 => {
7+
"one";
8+
"two";
9+
}
10+
1 | 2 | 3 => {
11+
"line1";
12+
"line2";
13+
}
14+
100..1000 => oneline(),
15+
16+
_ => {
17+
// catch-all
18+
todo!();
19+
}
20+
}
21+
}

tests/target/match-unindent.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// rustfmt-match_arm_indent: false
2+
// Unindent the match arms
3+
4+
fn foo() {
5+
match x {
6+
a => {
7+
"line1";
8+
"line2"
9+
}
10+
ThisIsA::Guard if true => {
11+
"line1";
12+
"line2"
13+
}
14+
ThisIsA::ReallyLongPattern(ThatWillForce::TheGuard, ToWrapOnto::TheFollowingLine) if true => {
15+
"line1";
16+
"line2"
17+
}
18+
}
19+
}

0 commit comments

Comments
 (0)