diff --git a/crates/compiler/fmt/src/expr.rs b/crates/compiler/fmt/src/expr.rs index b0aa8101f2..4d1bea1acd 100644 --- a/crates/compiler/fmt/src/expr.rs +++ b/crates/compiler/fmt/src/expr.rs @@ -788,6 +788,7 @@ fn fmt_parens(sub_expr: &Expr<'_>, buf: &mut Buf<'_>, indent: u16) { let should_add_newlines = match sub_expr { Expr::Closure(..) | Expr::SpaceBefore(..) + | Expr::When(..) | Expr::SpaceAfter(Expr::Closure(..), ..) | Expr::DbgStmt { .. } => false, _ => sub_expr.is_multiline(), @@ -881,7 +882,7 @@ fn starts_with_newline(expr: &Expr) -> bool { SpaceBefore(_, comment_or_newline) => { matches!(comment_or_newline.first(), Some(CommentOrNewline::Newline)) } - DbgStmt { .. } => true, + DbgStmt { .. } | When(..) => true, _ => false, } } @@ -1724,7 +1725,20 @@ fn fmt_when<'a>( buf.indent(indent + INDENT); buf.push_str(" if"); buf.spaces(1); - guard_expr.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent + INDENT); + + let guard_lifted = + expr_lift_spaces(Parens::NotNeeded, buf.text.bump(), &guard_expr.value); + + if guard_needs_parens(&guard_lifted.item) { + fmt_parens(&lower(buf.text.bump(), guard_lifted), buf, indent + INDENT); + } else { + lower(buf.text.bump(), guard_lifted).format_with_options( + buf, + Parens::NotNeeded, + Newlines::Yes, + indent + INDENT, + ); + } } buf.indent(indent + INDENT); @@ -1741,7 +1755,6 @@ fn fmt_when<'a>( buf.spaces(1); } - // expr.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, inner_indent); format_expr_only( &expr.item, buf, @@ -1760,6 +1773,16 @@ fn fmt_when<'a>( } } +fn guard_needs_parens(value: &Expr<'_>) -> bool { + match value { + Expr::When(..) => true, + Expr::ParensAround(expr) | Expr::SpaceBefore(expr, _) | Expr::SpaceAfter(expr, _) => { + guard_needs_parens(expr) + } + _ => false, + } +} + fn fmt_dbg_stmt<'a>( buf: &mut Buf, condition: &'a Loc>, diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_binops.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_binops.expr.formatted.roc index 1605846682..15c66c8655 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_binops.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_binops.expr.formatted.roc @@ -4,6 +4,5 @@ di when b is - 7 -> 7e -) + 7 -> 7e) zl \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_when_guard_wtf.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_when_guard_wtf.expr.formatted.roc new file mode 100644 index 0000000000..c9b3d03a03 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_when_guard_wtf.expr.formatted.roc @@ -0,0 +1,10 @@ +when + f +is + s if ( + when + 0 + is + z -> + f + z) -> m \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_when_guard_wtf.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_when_guard_wtf.expr.result-ast new file mode 100644 index 0000000000..0e6d6b4d85 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_when_guard_wtf.expr.result-ast @@ -0,0 +1,74 @@ +@0-35 SpaceAfter( + When( + @5-6 SpaceAfter( + Var { + module_name: "", + ident: "f", + }, + [ + Newline, + ], + ), + [ + WhenBranch { + patterns: [ + @10-11 SpaceBefore( + Identifier { + ident: "s", + }, + [ + Newline, + ], + ), + ], + value: @34-35 Var { + module_name: "", + ident: "m", + }, + guard: Some( + @15-32 When( + @20-21 SpaceAfter( + Num( + "0", + ), + [ + Newline, + ], + ), + [ + WhenBranch { + patterns: [ + @25-26 Identifier { + ident: "z", + }, + ], + value: @28-32 Apply( + @28-29 Var { + module_name: "", + ident: "f", + }, + [ + @31-32 SpaceBefore( + Var { + module_name: "", + ident: "z", + }, + [ + Newline, + ], + ), + ], + Space, + ), + guard: None, + }, + ], + ), + ), + }, + ], + ), + [ + Newline, + ], +) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_in_when_guard_wtf.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_when_guard_wtf.expr.roc new file mode 100644 index 0000000000..654521187c --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_in_when_guard_wtf.expr.roc @@ -0,0 +1,5 @@ +when f +is +s if when 0 +is z->f + z->m diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs index 21fd0d761e..523c97435f 100644 --- a/crates/compiler/test_syntax/tests/test_snapshots.rs +++ b/crates/compiler/test_syntax/tests/test_snapshots.rs @@ -764,6 +764,7 @@ mod test_snapshots { pass/when_in_list.expr, pass/when_in_parens.expr, pass/when_in_parens_indented.expr, + pass/when_in_when_guard_wtf.expr, pass/when_newline_after_condition.expr, pass/when_newline_before_is_and_in_branch_parens.expr, pass/when_result_list.expr,