@@ -1988,25 +1988,34 @@ impl<'a> Parser<'a> {
19881988 let lo = self . prev_token . span ;
19891989 let cond = self . parse_cond_expr ( ) ?;
19901990
1991+ let missing_then_block_binop_span = || {
1992+ match cond. kind {
1993+ ExprKind :: Binary ( Spanned { span : binop_span, .. } , _, ref right)
1994+ if let ExprKind :: Block ( ..) = right. kind => Some ( binop_span) ,
1995+ _ => None
1996+ }
1997+ } ;
1998+
19911999 // Verify that the parsed `if` condition makes sense as a condition. If it is a block, then
19922000 // verify that the last statement is either an implicit return (no `;`) or an explicit
19932001 // return. This won't catch blocks with an explicit `return`, but that would be caught by
19942002 // the dead code lint.
1995- let thn = if self . eat_keyword ( kw:: Else ) || !cond. returns ( ) {
1996- self . error_missing_if_cond ( lo, cond. span )
2003+ let thn = if self . token . is_keyword ( kw:: Else ) || !cond. returns ( ) {
2004+ if let Some ( binop_span) = missing_then_block_binop_span ( ) {
2005+ self . error_missing_if_then_block ( lo, None , Some ( binop_span) ) . emit ( ) ;
2006+ self . mk_block_err ( cond. span )
2007+ } else {
2008+ self . error_missing_if_cond ( lo, cond. span )
2009+ }
19972010 } else {
19982011 let attrs = self . parse_outer_attributes ( ) ?. take_for_recovery ( ) ; // For recovery.
19992012 let not_block = self . token != token:: OpenDelim ( token:: Brace ) ;
2000- let block = self . parse_block ( ) . map_err ( |mut err| {
2013+ let block = self . parse_block ( ) . map_err ( |err| {
20012014 if not_block {
2002- err. span_label ( lo, "this `if` expression has a condition, but no block" ) ;
2003- if let ExprKind :: Binary ( _, _, ref right) = cond. kind {
2004- if let ExprKind :: Block ( _, _) = right. kind {
2005- err. help ( "maybe you forgot the right operand of the condition?" ) ;
2006- }
2007- }
2015+ self . error_missing_if_then_block ( lo, Some ( err) , missing_then_block_binop_span ( ) )
2016+ } else {
2017+ err
20082018 }
2009- err
20102019 } ) ?;
20112020 self . error_on_if_block_attrs ( lo, false , block. span , & attrs) ;
20122021 block
@@ -2015,6 +2024,28 @@ impl<'a> Parser<'a> {
20152024 Ok ( self . mk_expr ( lo. to ( self . prev_token . span ) , ExprKind :: If ( cond, thn, els) , attrs) )
20162025 }
20172026
2027+ fn error_missing_if_then_block (
2028+ & self ,
2029+ if_span : Span ,
2030+ err : Option < DiagnosticBuilder < ' a > > ,
2031+ binop_span : Option < Span > ,
2032+ ) -> DiagnosticBuilder < ' a > {
2033+ let msg = "this `if` expression has a condition, but no block" ;
2034+
2035+ let mut err = if let Some ( mut err) = err {
2036+ err. span_label ( if_span, msg) ;
2037+ err
2038+ } else {
2039+ self . struct_span_err ( if_span, msg)
2040+ } ;
2041+
2042+ if let Some ( binop_span) = binop_span {
2043+ err. span_help ( binop_span, "maybe you forgot the right operand of the condition?" ) ;
2044+ }
2045+
2046+ err
2047+ }
2048+
20182049 fn error_missing_if_cond ( & self , lo : Span , span : Span ) -> P < ast:: Block > {
20192050 let sp = self . sess . source_map ( ) . next_point ( lo) ;
20202051 self . struct_span_err ( sp, "missing condition for `if` expression" )
0 commit comments