Skip to content

Add trailing_semicolon config option #1783

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

Merged
merged 1 commit into from
Jul 12, 2017
Merged
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
21 changes: 21 additions & 0 deletions Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,27 @@ let Lorem {

See also: [`match_block_trailing_comma`](#match_block_trailing_comma).

## `trailing_semicolon`

Add trailing semicolon after break, continue and return

- **Default value**: `true`
- **Possible values**: `true`, `false`

#### `true`:
```rust
fn foo() -> usize {
return 0;
}
```

#### `false`:
```rust
fn foo() -> usize {
return 0
}
```

## `type_punctuation_density`

Determines if `+` or `=` are wrapped in spaces in the punctuation of types
Expand Down
1 change: 1 addition & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ create_config! {
impl_empty_single_line: bool, true, "Put empty-body implementations on a single line";
trailing_comma: SeparatorTactic, SeparatorTactic::Vertical,
"How to handle trailing commas for lists";
trailing_semicolon: bool, true, "Add trailing semicolon after break, continue and return";
fn_empty_single_line: bool, true, "Put empty-body functions on a single line";
fn_single_line: bool, false, "Put single-expression functions on a single line";
fn_return_indent: ReturnIndent, ReturnIndent::WithArgs,
Expand Down
6 changes: 5 additions & 1 deletion src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,11 @@ impl Rewrite for ast::Stmt {
let result = match self.node {
ast::StmtKind::Local(ref local) => local.rewrite(context, shape),
ast::StmtKind::Expr(ref ex) | ast::StmtKind::Semi(ref ex) => {
let suffix = if semicolon_for_stmt(self) { ";" } else { "" };
let suffix = if semicolon_for_stmt(context, self) {
";"
} else {
""
};

format_expr(
ex,
Expand Down
6 changes: 5 additions & 1 deletion src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,11 @@ impl<'a> FmtVisitor<'a> {
if let Some(ref stmt) = block.stmts.first() {
match stmt_expr(stmt) {
Some(e) => {
let suffix = if semicolon_for_expr(e) { ";" } else { "" };
let suffix = if semicolon_for_expr(&self.get_context(), e) {
";"
} else {
""
};

format_expr(
&e,
Expand Down
11 changes: 8 additions & 3 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,26 @@ pub fn end_typaram(typaram: &ast::TyParam) -> BytePos {
}

#[inline]
pub fn semicolon_for_expr(expr: &ast::Expr) -> bool {
pub fn semicolon_for_expr(context: &RewriteContext, expr: &ast::Expr) -> bool {
match expr.node {
ast::ExprKind::Ret(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Break(..) => true,
ast::ExprKind::Ret(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Break(..) => {
context.config.trailing_semicolon()
}
_ => false,
}
}

#[inline]
pub fn semicolon_for_stmt(stmt: &ast::Stmt) -> bool {
pub fn semicolon_for_stmt(context: &RewriteContext, stmt: &ast::Stmt) -> bool {
match stmt.node {
ast::StmtKind::Semi(ref expr) => match expr.node {
ast::ExprKind::While(..) |
ast::ExprKind::WhileLet(..) |
ast::ExprKind::Loop(..) |
ast::ExprKind::ForLoop(..) => false,
ast::ExprKind::Break(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Ret(..) => {
context.config.trailing_semicolon()
}
_ => true,
},
ast::StmtKind::Expr(..) => false,
Expand Down
2 changes: 1 addition & 1 deletion src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl<'a> FmtVisitor<'a> {

if !b.stmts.is_empty() {
if let Some(expr) = utils::stmt_expr(&b.stmts[b.stmts.len() - 1]) {
if utils::semicolon_for_expr(expr) {
if utils::semicolon_for_expr(&self.get_context(), expr) {
self.buffer.push_str(";");
}
}
Expand Down
27 changes: 27 additions & 0 deletions tests/target/configs-trailing_semicolon-false.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// rustfmt-trailing_semicolon: false

#![feature(loop_break_value)]

fn main() {
'a: loop {
break 'a
}

let mut done = false;
'b: while !done {
done = true;
continue 'b
}

let x = loop {
break 5
};

let x = 'c: loop {
break 'c 5
};
}

fn foo() -> usize {
return 0
}
27 changes: 27 additions & 0 deletions tests/target/configs-trailing_semicolon-true.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// rustfmt-trailing_semicolon: true

#![feature(loop_break_value)]

fn main() {
'a: loop {
break 'a;
}

let mut done = false;
'b: while !done {
done = true;
continue 'b;
}

let x = loop {
break 5;
};

let x = 'c: loop {
break 'c 5;
};
}

fn foo() -> usize {
return 0;
}