From 2fb66cd1d3963dd66c536865a8413a677f6aa470 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Tue, 11 Jul 2017 22:41:38 +0900 Subject: [PATCH] Add trailing_semicolon config option trailing_semicolon controls whether to add a trailing semicolon after break, continue and return. --- Configurations.md | 21 +++++++++++++++ src/config.rs | 1 + src/expr.rs | 6 ++++- src/items.rs | 6 ++++- src/utils.rs | 11 +++++--- src/visitor.rs | 2 +- .../configs-trailing_semicolon-false.rs | 27 +++++++++++++++++++ .../target/configs-trailing_semicolon-true.rs | 27 +++++++++++++++++++ 8 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 tests/target/configs-trailing_semicolon-false.rs create mode 100644 tests/target/configs-trailing_semicolon-true.rs diff --git a/Configurations.md b/Configurations.md index 58124b8bc93..2e1cdc9dccf 100644 --- a/Configurations.md +++ b/Configurations.md @@ -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 diff --git a/src/config.rs b/src/config.rs index 2fe6d3ea6b6..1965675a83e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -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, diff --git a/src/expr.rs b/src/expr.rs index 9adb601c9cb..e1162521859 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -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, diff --git a/src/items.rs b/src/items.rs index 7e79e0a0b45..2f3018a2552 100644 --- a/src/items.rs +++ b/src/items.rs @@ -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, diff --git a/src/utils.rs b/src/utils.rs index 2e0dce52e91..bdf5c2e4b5e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -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, diff --git a/src/visitor.rs b/src/visitor.rs index a1258092e8d..3bb533a00fd 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -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(";"); } } diff --git a/tests/target/configs-trailing_semicolon-false.rs b/tests/target/configs-trailing_semicolon-false.rs new file mode 100644 index 00000000000..9fa746e9c0f --- /dev/null +++ b/tests/target/configs-trailing_semicolon-false.rs @@ -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 +} diff --git a/tests/target/configs-trailing_semicolon-true.rs b/tests/target/configs-trailing_semicolon-true.rs new file mode 100644 index 00000000000..61b6843d677 --- /dev/null +++ b/tests/target/configs-trailing_semicolon-true.rs @@ -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; +}