Skip to content

Commit 5f3dfe6

Browse files
authored
Format the if expression at the end of the block in a single line (rust-lang#3338)
1 parent 4f3a353 commit 5f3dfe6

File tree

6 files changed

+199
-10
lines changed

6 files changed

+199
-10
lines changed

src/expr.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -664,11 +664,7 @@ fn to_control_flow(expr: &ast::Expr, expr_type: ExprType) -> Option<ControlFlow<
664664
}
665665

666666
fn choose_matcher(pats: &[&ast::Pat]) -> &'static str {
667-
if pats.is_empty() {
668-
""
669-
} else {
670-
"let"
671-
}
667+
if pats.is_empty() { "" } else { "let" }
672668
}
673669

674670
impl<'a> ControlFlow<'a> {
@@ -1182,6 +1178,16 @@ pub fn stmt_is_expr(stmt: &ast::Stmt) -> bool {
11821178
}
11831179
}
11841180

1181+
pub(crate) fn stmt_is_if(stmt: &ast::Stmt) -> bool {
1182+
match stmt.node {
1183+
ast::StmtKind::Expr(ref e) => match e.node {
1184+
ast::ExprKind::If(..) => true,
1185+
_ => false,
1186+
},
1187+
_ => false,
1188+
}
1189+
}
1190+
11851191
pub fn is_unsafe_block(block: &ast::Block) -> bool {
11861192
if let ast::BlockCheckMode::Unsafe(..) = block.rules {
11871193
true

src/visitor.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use syntax::{ast, visit};
66

77
use crate::attr::*;
88
use crate::comment::{CodeCharKind, CommentCodeSlices, FindUncommented};
9-
use crate::config::{BraceStyle, Config};
9+
use crate::config::{BraceStyle, Config, Version};
10+
use crate::expr::{format_expr, ExprType};
1011
use crate::items::{
1112
format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item,
1213
rewrite_associated_impl_type, rewrite_associated_type, rewrite_existential_impl_type,
@@ -20,7 +21,7 @@ use crate::source_map::{LineRangeUtils, SpanUtils};
2021
use crate::spanned::Spanned;
2122
use crate::utils::{
2223
self, contains_skip, count_newlines, inner_attributes, mk_sp, ptr_vec_to_ref_vec,
23-
rewrite_ident, DEPR_SKIP_ANNOTATION,
24+
rewrite_ident, stmt_expr, DEPR_SKIP_ANNOTATION,
2425
};
2526
use crate::{ErrorKind, FormatReport, FormattingError};
2627

@@ -177,7 +178,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
177178
self.walk_block_stmts(b);
178179

179180
if !b.stmts.is_empty() {
180-
if let Some(expr) = utils::stmt_expr(&b.stmts[b.stmts.len() - 1]) {
181+
if let Some(expr) = stmt_expr(&b.stmts[b.stmts.len() - 1]) {
181182
if utils::semicolon_for_expr(&self.get_context(), expr) {
182183
self.push_str(";");
183184
}
@@ -694,8 +695,22 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
694695
.collect();
695696

696697
if items.is_empty() {
697-
self.visit_stmt(&stmts[0]);
698-
self.walk_stmts(&stmts[1..]);
698+
// The `if` expression at the end of the block should be formatted in a single
699+
// line if possible.
700+
if self.config.version() == Version::Two
701+
&& stmts.len() == 1
702+
&& crate::expr::stmt_is_if(&stmts[0])
703+
&& !contains_skip(get_attrs_from_stmt(&stmts[0]))
704+
{
705+
let shape = self.shape();
706+
let rewrite = self.with_context(|ctx| {
707+
format_expr(stmt_expr(&stmts[0])?, ExprType::SubExpression, ctx, shape)
708+
});
709+
self.push_rewrite(stmts[0].span(), rewrite);
710+
} else {
711+
self.visit_stmt(&stmts[0]);
712+
self.walk_stmts(&stmts[1..]);
713+
}
699714
} else {
700715
self.visit_items_with_reordering(&items);
701716
self.walk_stmts(&stmts[items.len()..]);

tests/source/one_line_if_v1.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// rustfmt-version: One
2+
3+
fn plain_if(x: bool) -> u8 {
4+
if x {
5+
0
6+
} else {
7+
1
8+
}
9+
}
10+
11+
fn paren_if(x: bool) -> u8 {
12+
(if x { 0 } else { 1 })
13+
}
14+
15+
fn let_if(x: bool) -> u8 {
16+
let x = if x {
17+
foo()
18+
} else {
19+
bar()
20+
};
21+
x
22+
}
23+
24+
fn return_if(x: bool) -> u8 {
25+
return if x {
26+
0
27+
} else {
28+
1
29+
};
30+
}
31+
32+
fn multi_if() {
33+
use std::io;
34+
if x { foo() } else { bar() }
35+
if x { foo() } else { bar() }
36+
}
37+
38+
fn middle_if() {
39+
use std::io;
40+
if x { foo() } else { bar() }
41+
let x = 1;
42+
}

tests/source/one_line_if_v2.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// rustfmt-version: Two
2+
3+
fn plain_if(x: bool) -> u8 {
4+
if x {
5+
0
6+
} else {
7+
1
8+
}
9+
}
10+
11+
fn paren_if(x: bool) -> u8 {
12+
(if x { 0 } else { 1 })
13+
}
14+
15+
fn let_if(x: bool) -> u8 {
16+
let x = if x {
17+
foo()
18+
} else {
19+
bar()
20+
};
21+
x
22+
}
23+
24+
fn return_if(x: bool) -> u8 {
25+
return if x {
26+
0
27+
} else {
28+
1
29+
};
30+
}
31+
32+
fn multi_if() {
33+
use std::io;
34+
if x { foo() } else { bar() }
35+
if x { foo() } else { bar() }
36+
}
37+
38+
fn middle_if() {
39+
use std::io;
40+
if x { foo() } else { bar() }
41+
let x = 1;
42+
}

tests/target/one_line_if_v1.rs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// rustfmt-version: One
2+
3+
fn plain_if(x: bool) -> u8 {
4+
if x {
5+
0
6+
} else {
7+
1
8+
}
9+
}
10+
11+
fn paren_if(x: bool) -> u8 {
12+
(if x { 0 } else { 1 })
13+
}
14+
15+
fn let_if(x: bool) -> u8 {
16+
let x = if x { foo() } else { bar() };
17+
x
18+
}
19+
20+
fn return_if(x: bool) -> u8 {
21+
return if x { 0 } else { 1 };
22+
}
23+
24+
fn multi_if() {
25+
use std::io;
26+
if x {
27+
foo()
28+
} else {
29+
bar()
30+
}
31+
if x {
32+
foo()
33+
} else {
34+
bar()
35+
}
36+
}
37+
38+
fn middle_if() {
39+
use std::io;
40+
if x {
41+
foo()
42+
} else {
43+
bar()
44+
}
45+
let x = 1;
46+
}

tests/target/one_line_if_v2.rs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// rustfmt-version: Two
2+
3+
fn plain_if(x: bool) -> u8 {
4+
if x { 0 } else { 1 }
5+
}
6+
7+
fn paren_if(x: bool) -> u8 {
8+
(if x { 0 } else { 1 })
9+
}
10+
11+
fn let_if(x: bool) -> u8 {
12+
let x = if x { foo() } else { bar() };
13+
x
14+
}
15+
16+
fn return_if(x: bool) -> u8 {
17+
return if x { 0 } else { 1 };
18+
}
19+
20+
fn multi_if() {
21+
use std::io;
22+
if x {
23+
foo()
24+
} else {
25+
bar()
26+
}
27+
if x { foo() } else { bar() }
28+
}
29+
30+
fn middle_if() {
31+
use std::io;
32+
if x {
33+
foo()
34+
} else {
35+
bar()
36+
}
37+
let x = 1;
38+
}

0 commit comments

Comments
 (0)