@@ -1988,25 +1988,34 @@ impl<'a> Parser<'a> {
1988
1988
let lo = self . prev_token . span ;
1989
1989
let cond = self . parse_cond_expr ( ) ?;
1990
1990
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
+
1991
1999
// Verify that the parsed `if` condition makes sense as a condition. If it is a block, then
1992
2000
// verify that the last statement is either an implicit return (no `;`) or an explicit
1993
2001
// return. This won't catch blocks with an explicit `return`, but that would be caught by
1994
2002
// 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
+ }
1997
2010
} else {
1998
2011
let attrs = self . parse_outer_attributes ( ) ?. take_for_recovery ( ) ; // For recovery.
1999
2012
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| {
2001
2014
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
2008
2018
}
2009
- err
2010
2019
} ) ?;
2011
2020
self . error_on_if_block_attrs ( lo, false , block. span , & attrs) ;
2012
2021
block
@@ -2015,6 +2024,28 @@ impl<'a> Parser<'a> {
2015
2024
Ok ( self . mk_expr ( lo. to ( self . prev_token . span ) , ExprKind :: If ( cond, thn, els) , attrs) )
2016
2025
}
2017
2026
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
+
2018
2049
fn error_missing_if_cond ( & self , lo : Span , span : Span ) -> P < ast:: Block > {
2019
2050
let sp = self . sess . source_map ( ) . next_point ( lo) ;
2020
2051
self . struct_span_err ( sp, "missing condition for `if` expression" )
0 commit comments