@@ -126,10 +126,14 @@ impl Rewrite for ast::Local {
126126 ) ?;
127127
128128 if let Some ( block) = else_block {
129+ let else_kw_span = init. span . between ( block. span ) ;
130+ let force_newline_else =
131+ !same_line_else_kw_and_brace ( & result, context, else_kw_span, nested_shape) ;
129132 let else_kw = rewrite_else_kw_with_comments (
133+ force_newline_else,
130134 true ,
131135 context,
132- init . span . between ( block . span ) ,
136+ else_kw_span ,
133137 shape,
134138 ) ;
135139 result. push_str ( & else_kw) ;
@@ -148,6 +152,47 @@ impl Rewrite for ast::Local {
148152 }
149153}
150154
155+ /// When the initializer expression is multi-lined, then the else keyword and opening brace of the
156+ /// block ( i.e. "else {") should be put on the same line as the end of the initializer expression
157+ /// if all the following are true:
158+ ///
159+ /// 1. The initializer expression ends with one or more closing parentheses, square brackets,
160+ /// or braces
161+ /// 2. There is nothing else on that line
162+ /// 3. That line is not indented beyond the indent on the first line of the let keyword
163+ fn same_line_else_kw_and_brace (
164+ init_str : & str ,
165+ context : & RewriteContext < ' _ > ,
166+ else_kw_span : Span ,
167+ init_shape : Shape ,
168+ ) -> bool {
169+ if !init_str. contains ( '\n' ) {
170+ // initializer expression is single lined so the "else {" should be placed on the same line
171+ return true ;
172+ }
173+
174+ // 1. The initializer expression ends with one or more `)`, `]`, `}`.
175+ if !init_str. ends_with ( [ ')' , ']' , '}' ] ) {
176+ return false ;
177+ }
178+
179+ // 2. There is nothing else on that line
180+ // For example, there are no comments
181+ let else_kw_snippet = context. snippet ( else_kw_span) . trim ( ) ;
182+ if else_kw_snippet != "else" {
183+ return false ;
184+ }
185+
186+ // 3. The last line of the initializer expression is not indented beyond the `let` keyword
187+ let indent = init_shape. indent . to_string ( context. config ) ;
188+ init_str
189+ . lines ( )
190+ . last ( )
191+ . expect ( "initializer expression is multi-lined" )
192+ . strip_prefix ( indent. as_ref ( ) )
193+ . map_or ( false , |l| !l. starts_with ( char:: is_whitespace) )
194+ }
195+
151196// FIXME convert to using rewrite style rather than visitor
152197// FIXME format modules in this style
153198#[ allow( dead_code) ]
0 commit comments