From d92dd3d915c0936f78fb0cf80c830dbd7fda211e Mon Sep 17 00:00:00 2001 From: Marcus Klaas Date: Tue, 25 Aug 2015 22:07:02 +0200 Subject: [PATCH 1/1] Prevent nested if-else from being put on a single line. This is done using a pretty terribad hack, introducing an extra function parameter and some code duplication. Unfortunately, there seem to be few alternatives. --- src/expr.rs | 40 ++++++++++++++++++++++++----- tests/source/single-line-if-else.rs | 4 +++ tests/target/single-line-if-else.rs | 8 +++++- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index 1797617e7fd..14659815d72 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -80,7 +80,8 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Opti else_block.as_ref().map(|e| &**e), None, width, - offset) + offset, + true) } ast::Expr_::ExprIfLet(ref pat, ref cond, ref if_block, ref else_block) => { rewrite_if_else(context, @@ -89,7 +90,8 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Opti else_block.as_ref().map(|e| &**e), Some(pat), width, - offset) + offset, + true) } // We reformat it ourselves because rustc gives us a bad span // for ranges, see rust#27162 @@ -415,7 +417,8 @@ fn rewrite_if_else(context: &RewriteContext, else_block_opt: Option<&ast::Expr>, pat: Option<&ast::Pat>, width: usize, - offset: usize) + offset: usize, + allow_single_line: bool) -> Option { // 3 = "if ", 2 = " {" let pat_expr_string = try_opt!(rewrite_pat_expr(context, @@ -427,7 +430,7 @@ fn rewrite_if_else(context: &RewriteContext, offset + 3)); // Try to format if-else on single line. - if context.config.single_line_if_else { + if allow_single_line && context.config.single_line_if_else { let trial = single_line_if_else(context, &pat_expr_string, if_block, else_block_opt, width); if trial.is_some() { @@ -439,10 +442,34 @@ fn rewrite_if_else(context: &RewriteContext, let mut result = format!("if {} {}", pat_expr_string, if_block_string); if let Some(else_block) = else_block_opt { - let else_block_string = try_opt!(else_block.rewrite(context, width, offset)); + let rewrite = match else_block.node { + // If the else expression is another if-else expression, prevent it + // from being formatted on a single line. + ast::Expr_::ExprIfLet(ref pat, ref cond, ref if_block, ref else_block) => { + rewrite_if_else(context, + cond, + if_block, + else_block.as_ref().map(|e| &**e), + Some(pat), + width, + offset, + false) + } + ast::Expr_::ExprIf(ref cond, ref if_block, ref else_block) => { + rewrite_if_else(context, + cond, + if_block, + else_block.as_ref().map(|e| &**e), + None, + width, + offset, + false) + } + _ => else_block.rewrite(context, width, offset), + }; result.push_str(" else "); - result.push_str(&else_block_string); + result.push_str(&&try_opt!(rewrite)); } Some(result) @@ -491,6 +518,7 @@ fn is_simple_block(block: &ast::Block, codemap: &CodeMap) -> bool { let snippet = codemap.span_to_snippet(block.span).unwrap(); + // FIXME: fails when either // or /* is contained in a string literal. !snippet.contains("//") && !snippet.contains("/*") } diff --git a/tests/source/single-line-if-else.rs b/tests/source/single-line-if-else.rs index 25ba58cabf8..42629ab8e37 100644 --- a/tests/source/single-line-if-else.rs +++ b/tests/source/single-line-if-else.rs @@ -26,6 +26,10 @@ fn main() { 10 }; + let d = if let Some(val) = turbo + { "cool" } else { + "beans" }; + if cond() { statement(); } else { other_statement(); } if true { diff --git a/tests/target/single-line-if-else.rs b/tests/target/single-line-if-else.rs index dff06e69b2d..27b6d773da5 100644 --- a/tests/target/single-line-if-else.rs +++ b/tests/target/single-line-if-else.rs @@ -7,7 +7,11 @@ fn main() { let a = if x { 1 - } else if y { 2 } else { 3 }; + } else if y { + 2 + } else { + 3 + }; let b = if cond() { 5 @@ -24,6 +28,8 @@ fn main() { 10 }; + let d = if let Some(val) = turbo { "cool" } else { "beans" }; + if cond() { statement(); } else { -- 2.44.0