Skip to content

Commit 960fec8

Browse files
committed
Force to use block for closure's body when there is only a single control expr
1 parent e4f13df commit 960fec8

File tree

1 file changed

+50
-2
lines changed

1 file changed

+50
-2
lines changed

src/expr.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -641,8 +641,12 @@ fn rewrite_closure(
641641
};
642642
if no_return_type && !needs_block {
643643
// block.stmts.len() == 1
644-
if let Some(expr) = stmt_expr(&block.stmts[0]) {
645-
if let Some(rw) = rewrite_closure_expr(expr, &prefix, context, body_shape) {
644+
if let Some(ref expr) = stmt_expr(&block.stmts[0]) {
645+
if let Some(rw) = if is_block_closure_forced(expr) {
646+
rewrite_closure_with_block(context, shape, &prefix, expr)
647+
} else {
648+
rewrite_closure_expr(expr, &prefix, context, body_shape)
649+
} {
646650
return Some(rw);
647651
}
648652
}
@@ -2247,7 +2251,34 @@ fn rewrite_last_closure(
22472251
if prefix.contains('\n') {
22482252
return None;
22492253
}
2254+
// If we are inside macro, we do not want to add or remove block from closure body.
2255+
if context.inside_macro {
2256+
return expr.rewrite(context, shape);
2257+
}
2258+
22502259
let body_shape = shape.offset_left(extra_offset)?;
2260+
2261+
// We force to use block for the body of the closure for certain kinds of expressions.
2262+
if is_block_closure_forced(body) {
2263+
return rewrite_closure_with_block(context, body_shape, &prefix, body).and_then(
2264+
|body_str| {
2265+
// If the expression can fit in a single line, we need not force block closure.
2266+
if body_str.lines().count() <= 7 {
2267+
match rewrite_closure_expr(body, &prefix, context, shape) {
2268+
Some(ref single_line_body_str)
2269+
if !single_line_body_str.contains('\n') =>
2270+
{
2271+
Some(single_line_body_str.clone())
2272+
}
2273+
_ => Some(body_str),
2274+
}
2275+
} else {
2276+
Some(body_str)
2277+
}
2278+
},
2279+
);
2280+
}
2281+
22512282
// When overflowing the closure which consists of a single control flow expression,
22522283
// force to use block if its condition uses multi line.
22532284
let is_multi_lined_cond = rewrite_cond(context, body, body_shape)
@@ -2263,6 +2294,23 @@ fn rewrite_last_closure(
22632294
None
22642295
}
22652296

2297+
fn is_block_closure_forced(expr: &ast::Expr) -> bool {
2298+
match expr.node {
2299+
ast::ExprKind::If(..) |
2300+
ast::ExprKind::IfLet(..) |
2301+
ast::ExprKind::Loop(..) |
2302+
ast::ExprKind::While(..) |
2303+
ast::ExprKind::WhileLet(..) |
2304+
ast::ExprKind::ForLoop(..) => true,
2305+
ast::ExprKind::AddrOf(_, ref expr) |
2306+
ast::ExprKind::Box(ref expr) |
2307+
ast::ExprKind::Try(ref expr) |
2308+
ast::ExprKind::Unary(_, ref expr) |
2309+
ast::ExprKind::Cast(ref expr, _) => is_block_closure_forced(expr),
2310+
_ => false,
2311+
}
2312+
}
2313+
22662314
fn rewrite_last_arg_with_overflow<'a, T>(
22672315
context: &RewriteContext,
22682316
args: &[&T],

0 commit comments

Comments
 (0)