Use special rules when overflowing the last argument
When overflowing the last argument of function call, if it is a closure,
we apply some special rules in order to avoid weird formatting.
@@ -2207,24 +2207,17 @@ fn last_arg_shape(
})
}
-fn rewrite_last_arg_with_overflow<'a, T>(
+// Rewriting closure which is placed at the end of the function call's arg.
+// Returns `None` if the reformatted closure 'looks bad'.
+fn rewrite_last_closure(
context: &RewriteContext,
- last_arg: &T,
- last_item: &mut ListItem,
+ expr: &ast::Expr,
shape: Shape,
-) -> (Option<String>, Option<String>)
-where
- T: Rewrite + Spanned + ToExpr + 'a,
-{
- let rewrite = if let Some(expr) = last_arg.to_expr() {
- match expr.node {
- // When overflowing the closure which consists of a single control flow expression,
- // force to use block if its condition uses multi line.
- ast::ExprKind::Closure(capture, ref fn_decl, ref body, _) => {
- let try_closure_with_block = || {
+) -> Option<String> {
+ if let ast::ExprKind::Closure(capture, ref fn_decl, ref body, _) = expr.node {
let body = match body.node {
ast::ExprKind::Block(ref block) if block.stmts.len() == 1 => {
- try_opt!(stmt_expr(&block.stmts[0]))
+ stmt_expr(&block.stmts[0]).unwrap_or(body)
}
_ => body,
};
@@ -2236,15 +2229,40 @@ where
context,
shape,
));
- let shape = try_opt!(shape.offset_left(extra_offset));
- rewrite_cond(context, body, shape).map_or(None, |cond| if cond.contains('\n') {
- rewrite_closure_with_block(context, shape, &prefix, body)
- } else {
+ // If the closure goes multi line before its body, do not overflow the closure.
+ if prefix.contains('\n') {
+ return None;
+ }
+ let body_shape = try_opt!(shape.offset_left(extra_offset));
+ // When overflowing the closure which consists of a single control flow expression,
+ // force to use block if its condition uses multi line.
+ if rewrite_cond(context, body, body_shape)
+ .map(|cond| cond.contains('\n'))
+ .unwrap_or(false)
+ {
+ return rewrite_closure_with_block(context, body_shape, &prefix, body);
+ }
+
+ // Seems fine, just format the closure in usual manner.
+ return expr.rewrite(context, shape);
+ }
None
- })
- };
- try_closure_with_block().or_else(|| expr.rewrite(context, shape))
}
+
+fn rewrite_last_arg_with_overflow<'a, T>(
+ context: &RewriteContext,
+ last_arg: &T,
+ last_item: &mut ListItem,
+ shape: Shape,
+) -> (Option<String>, Option<String>)
+where
+ T: Rewrite + Spanned + ToExpr + 'a,
+{
+ let rewrite = if let Some(expr) = last_arg.to_expr() {
+ match expr.node {
+ // When overflowing the closure which consists of a single control flow expression,
+ // force to use block if its condition uses multi line.
+ ast::ExprKind::Closure(..) => rewrite_last_closure(context, expr, shape),
_ => expr.rewrite(context, shape),
}
} else {
