@@ -549,26 +549,14 @@ impl Formatter {
549549 let fields = preserve. fields . join ( "\n " ) ;
550550 format ! ( "preserve {} from {} {{\n {}\n }}" , preserve. output_name, preserve. input_name, fields)
551551 }
552- Expr :: Block ( stmts) => {
553- let inner = stmts
554- . iter ( )
555- . map ( |stmt| {
556- let mut formatter = Formatter :: new ( self . config . clone ( ) ) ;
557- formatter. indent_level = 0 ;
558- formatter. format_stmt ( stmt) ;
559- formatter. output . trim ( ) . to_string ( )
560- } )
561- . collect :: < Vec < _ > > ( )
562- . join ( " " ) ;
563- format ! ( "{{ {} }}" , inner)
564- }
552+ Expr :: Block ( stmts) => format ! ( "{{ {} }}" , self . format_expr_block_body( stmts) ) ,
565553 Expr :: Tuple ( items) => format ! ( "({})" , items. iter( ) . map( |item| self . format_expr( item) ) . collect:: <Vec <_>>( ) . join( ", " ) ) ,
566554 Expr :: Array ( items) => format ! ( "[{}]" , items. iter( ) . map( |item| self . format_expr( item) ) . collect:: <Vec <_>>( ) . join( ", " ) ) ,
567555 Expr :: If ( if_expr) => format ! (
568556 "if {} {{ {} }} else {{ {} }}" ,
569557 self . format_expr( & if_expr. condition) ,
570- self . format_expr ( & if_expr. then_branch) ,
571- self . format_expr ( & if_expr. else_branch)
558+ self . format_branch_expr_body ( & if_expr. then_branch) ,
559+ self . format_branch_expr_body ( & if_expr. else_branch)
572560 ) ,
573561 Expr :: Cast ( cast) => format ! ( "{} as {}" , self . format_expr( & cast. expr) , format_type( & cast. ty) ) ,
574562 Expr :: Range ( range) => format ! ( "{}..{}" , self . format_expr( & range. start) , self . format_expr( & range. end) ) ,
@@ -599,6 +587,26 @@ impl Formatter {
599587 }
600588 }
601589
590+ fn format_branch_expr_body ( & self , expr : & Expr ) -> String {
591+ match expr {
592+ Expr :: Block ( stmts) => self . format_expr_block_body ( stmts) ,
593+ expr => self . format_expr ( expr) ,
594+ }
595+ }
596+
597+ fn format_expr_block_body ( & self , stmts : & [ Stmt ] ) -> String {
598+ stmts
599+ . iter ( )
600+ . map ( |stmt| {
601+ let mut formatter = Formatter :: new ( self . config . clone ( ) ) ;
602+ formatter. indent_level = 0 ;
603+ formatter. format_stmt ( stmt) ;
604+ formatter. output . trim ( ) . to_string ( )
605+ } )
606+ . collect :: < Vec < _ > > ( )
607+ . join ( " " )
608+ }
609+
602610 fn format_field_initializer ( & self , name : & str , value : & Expr ) -> String {
603611 if matches ! ( value, Expr :: Identifier ( identifier) if identifier == name) {
604612 name. to_string ( )
@@ -867,6 +875,28 @@ where
867875 assert ! ( formatted. contains( "create token = Token { amount, symbol }" ) , "unexpected formatted source:\n {}" , formatted) ;
868876 }
869877
878+ #[ test]
879+ fn format_if_expression_branch_blocks_are_idempotent ( ) {
880+ let source = r#"
881+ module demo
882+
883+ action choose(flag: bool) -> u64
884+ where
885+ let pair = if flag { (1, 2) } else { (3, 4) }
886+ return pair.0
887+ "# ;
888+ let tokens = lexer:: lex ( source) . unwrap ( ) ;
889+ let module = parser:: parse ( & tokens) . unwrap ( ) ;
890+ let formatted = format_default ( & module) . unwrap ( ) ;
891+ let tokens2 = lexer:: lex ( & formatted) . unwrap ( ) ;
892+ let module2 = parser:: parse ( & tokens2) . unwrap ( ) ;
893+ let formatted2 = format_default ( & module2) . unwrap ( ) ;
894+
895+ assert_eq ! ( formatted, formatted2) ;
896+ assert ! ( formatted. contains( "let pair = if flag { (1, 2) } else { (3, 4) }" ) , "unexpected formatted source:\n {}" , formatted) ;
897+ assert ! ( !formatted. contains( "{{" ) , "unexpected formatted source:\n {}" , formatted) ;
898+ }
899+
870900 #[ test]
871901 fn format_uses_canonical_assert_and_no_const_semicolon ( ) {
872902 let source = r#"
0 commit comments