Skip to content

Commit fc7f6e1

Browse files
Implement preserve mode for trailing-semicolon
1 parent 7289391 commit fc7f6e1

File tree

8 files changed

+91
-13
lines changed

8 files changed

+91
-13
lines changed

Configurations.md

+16-4
Original file line numberDiff line numberDiff line change
@@ -2780,20 +2780,32 @@ See also: [`match_block_trailing_comma`](#match_block_trailing_comma).
27802780

27812781
Add trailing semicolon after break, continue and return
27822782

2783-
- **Default value**: `true`
2784-
- **Possible values**: `true`, `false`
2783+
- **Default value**: `preserve`
2784+
- **Possible values**: `always`, `never`, `preserve`
27852785
- **Stable**: No (tracking issue: [#3378](https://github.com/rust-lang/rustfmt/issues/3378))
27862786

2787-
#### `true` (default):
2787+
#### `always` (default):
27882788
```rust
27892789
fn foo() -> usize {
27902790
return 0;
27912791
}
27922792
```
27932793

2794-
#### `false`:
2794+
#### `never`:
2795+
```rust
2796+
fn foo() -> usize {
2797+
return 0
2798+
}
2799+
```
2800+
2801+
2802+
#### `preserve`:
27952803
```rust
27962804
fn foo() -> usize {
2805+
return 0;
2806+
}
2807+
2808+
fn bar() -> usize {
27972809
return 0
27982810
}
27992811
```

src/config/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ create_config! {
135135
brace_style: BraceStyle, BraceStyle::SameLineWhere, false, "Brace style for items";
136136
control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine, false,
137137
"Brace style for control flow constructs";
138-
trailing_semicolon: bool, true, false,
138+
trailing_semicolon: TrailingSemicolon, TrailingSemicolon::Preserve, false,
139139
"Add trailing semicolon after break, continue and return";
140140
trailing_comma: SeparatorTactic, SeparatorTactic::Vertical, false,
141141
"How to handle trailing commas for lists";
@@ -673,7 +673,7 @@ force_multiline_blocks = false
673673
fn_params_layout = "Tall"
674674
brace_style = "SameLineWhere"
675675
control_brace_style = "AlwaysSameLine"
676-
trailing_semicolon = true
676+
trailing_semicolon = preserve
677677
trailing_comma = "Vertical"
678678
match_block_trailing_comma = false
679679
blank_lines_upper_bound = 1

src/config/options.rs

+7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ pub enum ControlBraceStyle {
4949
AlwaysNextLine,
5050
}
5151

52+
#[config_type]
53+
pub enum TrailingSemicolon {
54+
Always,
55+
Never,
56+
Preserve,
57+
}
58+
5259
#[config_type]
5360
/// How to indent.
5461
pub enum IndentStyle {

src/utils.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_span::{sym, symbol, BytePos, LocalExpnId, Span, Symbol, SyntaxContext}
1010
use unicode_width::UnicodeWidthStr;
1111

1212
use crate::comment::{filter_normal_code, CharClasses, FullCodeCharKind, LineClasses};
13-
use crate::config::{Config, Version};
13+
use crate::config::{Config, TrailingSemicolon, Version};
1414
use crate::rewrite::RewriteContext;
1515
use crate::shape::{Indent, Shape};
1616

@@ -273,15 +273,18 @@ pub(crate) fn contains_skip(attrs: &[Attribute]) -> bool {
273273
#[inline]
274274
pub(crate) fn semicolon_for_expr(context: &RewriteContext<'_>, expr: &ast::Expr) -> bool {
275275
// Never try to insert semicolons on expressions when we're inside
276-
// a macro definition - this can prevent the macro from compiling
276+
// a macro definition - this can prevent the macro from compiling
277277
// when used in expression position
278278
if context.is_macro_def {
279279
return false;
280280
}
281281

282282
match expr.kind {
283283
ast::ExprKind::Ret(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Break(..) => {
284-
context.config.trailing_semicolon()
284+
match context.config.trailing_semicolon() {
285+
TrailingSemicolon::Always => true,
286+
TrailingSemicolon::Never | TrailingSemicolon::Preserve => false,
287+
}
285288
}
286289
_ => false,
287290
}
@@ -301,7 +304,14 @@ pub(crate) fn semicolon_for_stmt(
301304
ast::ExprKind::Break(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Ret(..) => {
302305
// The only time we can skip the semi-colon is if the config option is set to false
303306
// **and** this is the last expr (even though any following exprs are unreachable)
304-
context.config.trailing_semicolon() || !is_last_expr
307+
if !is_last_expr {
308+
true
309+
} else {
310+
match context.config.trailing_semicolon() {
311+
TrailingSemicolon::Always | TrailingSemicolon::Preserve => true,
312+
TrailingSemicolon::Never => false,
313+
}
314+
}
305315
}
306316
_ => true,
307317
},

tests/target/configs/trailing_semicolon/true.rs renamed to tests/target/configs/trailing_semicolon/always.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// rustfmt-trailing_semicolon: true
1+
// rustfmt-trailing_semicolon: always
22

33
#![feature(loop_break_value)]
44

tests/target/configs/trailing_semicolon/false.rs renamed to tests/target/configs/trailing_semicolon/never.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// rustfmt-trailing_semicolon: false
1+
// rustfmt-trailing_semicolon: never
22

33
#![feature(loop_break_value)]
44

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// rustfmt-trailing_semicolon: never
2+
3+
#![feature(loop_break_value)]
4+
5+
fn main() {
6+
'a: loop {
7+
break 'a
8+
}
9+
10+
let mut done = false;
11+
'b: while !done {
12+
done = true;
13+
continue 'b
14+
}
15+
16+
let x = loop {
17+
break 5
18+
};
19+
20+
let x = 'c: loop {
21+
break 'c 5
22+
};
23+
24+
'a: loop {
25+
break 'a;
26+
}
27+
28+
let mut done = false;
29+
'b: while !done {
30+
done = true;
31+
continue 'b;
32+
}
33+
34+
let x = loop {
35+
break 5;
36+
};
37+
38+
let x = 'c: loop {
39+
break 'c 5;
40+
};
41+
}
42+
43+
fn foo() -> usize {
44+
return 0
45+
}
46+
47+
fn bar() -> usize {
48+
return 0;
49+
}

tests/target/issue-5797/retain_trailing_semicolon.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// rustfmt-trailing_semicolon: false
1+
// rustfmt-trailing_semicolon: never
22

33
fn foo() {}
44
fn main() {

0 commit comments

Comments
 (0)