@@ -286,34 +286,39 @@ fn check_array(cx: &EarlyContext<'_>, expr: &Expr) {
286286}
287287
288288fn check_missing_else ( cx : & EarlyContext < ' _ > , first : & Expr , second : & Expr ) {
289- if !differing_macro_contexts ( first. span , second. span )
290- && !first. span . from_expansion ( )
291- && is_if ( first)
292- && ( is_block ( second) || is_if ( second) )
293- {
294- // where the else would be
295- let else_span = first. span . between ( second. span ) ;
289+ if_chain ! {
290+ if !differing_macro_contexts( first. span, second. span) ;
291+ if !first. span. from_expansion( ) ;
292+ if let ExprKind :: If ( cond_expr, ..) = & first. kind;
293+ if is_block( second) || is_if( second) ;
296294
297- if let Some ( else_snippet) = snippet_opt ( cx, else_span) {
298- if !else_snippet. contains ( '\n' ) {
299- let ( looks_like, next_thing) = if is_if ( second) {
300- ( "an `else if`" , "the second `if`" )
301- } else {
302- ( "an `else {..}`" , "the next block" )
303- } ;
295+ // Proc-macros can give weird spans. Make sure this is actually an `if`.
296+ if let Some ( if_snip) = snippet_opt( cx, first. span. until( cond_expr. span) ) ;
297+ if if_snip. starts_with( "if" ) ;
304298
305- span_lint_and_note (
306- cx,
307- SUSPICIOUS_ELSE_FORMATTING ,
308- else_span,
309- & format ! ( "this looks like {} but the `else` is missing" , looks_like) ,
310- None ,
311- & format ! (
312- "to remove this lint, add the missing `else` or add a new line before {}" ,
313- next_thing,
314- ) ,
315- ) ;
316- }
299+ // If there is a line break between the two expressions, don't lint.
300+ // If there is a non-whitespace character, this span came from a proc-macro.
301+ let else_span = first. span. between( second. span) ;
302+ if let Some ( else_snippet) = snippet_opt( cx, else_span) ;
303+ if !else_snippet. chars( ) . any( |c| c == '\n' || !c. is_whitespace( ) ) ;
304+ then {
305+ let ( looks_like, next_thing) = if is_if( second) {
306+ ( "an `else if`" , "the second `if`" )
307+ } else {
308+ ( "an `else {..}`" , "the next block" )
309+ } ;
310+
311+ span_lint_and_note(
312+ cx,
313+ SUSPICIOUS_ELSE_FORMATTING ,
314+ else_span,
315+ & format!( "this looks like {} but the `else` is missing" , looks_like) ,
316+ None ,
317+ & format!(
318+ "to remove this lint, add the missing `else` or add a new line before {}" ,
319+ next_thing,
320+ ) ,
321+ ) ;
317322 }
318323 }
319324}
0 commit comments