@@ -97,6 +97,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
9797 ExprKind :: Let ( ref pat, ref scrutinee) => {
9898 self . lower_expr_if_let ( e. span , pat, scrutinee, then, else_opt. as_deref ( ) )
9999 }
100+ ExprKind :: Paren ( ref paren) => match paren. peel_parens ( ) . kind {
101+ ExprKind :: Let ( ref pat, ref scrutinee) => {
102+ // A user has written `if (let Some(x) = foo) {`, we want to avoid
103+ // confusing them with mentions of nightly features.
104+ // If this logic is changed, you will also likely need to touch
105+ // `unused::UnusedParens::check_expr`.
106+ self . if_let_expr_with_parens ( cond, & paren. peel_parens ( ) ) ;
107+ self . lower_expr_if_let (
108+ e. span ,
109+ pat,
110+ scrutinee,
111+ then,
112+ else_opt. as_deref ( ) ,
113+ )
114+ }
115+ _ => self . lower_expr_if ( cond, then, else_opt. as_deref ( ) ) ,
116+ } ,
100117 _ => self . lower_expr_if ( cond, then, else_opt. as_deref ( ) ) ,
101118 } ,
102119 ExprKind :: While ( ref cond, ref body, opt_label) => self
@@ -346,6 +363,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
346363 hir:: ExprKind :: Call ( f, self . lower_exprs ( & real_args) )
347364 }
348365
366+ fn if_let_expr_with_parens ( & mut self , cond : & Expr , paren : & Expr ) {
367+ let start = cond. span . until ( paren. span ) ;
368+ let end = paren. span . shrink_to_hi ( ) . until ( cond. span . shrink_to_hi ( ) ) ;
369+ self . sess
370+ . struct_span_err (
371+ vec ! [ start, end] ,
372+ "invalid parentheses around `let` expression in `if let`" ,
373+ )
374+ . multipart_suggestion (
375+ "`if let` needs to be written without parentheses" ,
376+ vec ! [ ( start, String :: new( ) ) , ( end, String :: new( ) ) ] ,
377+ rustc_errors:: Applicability :: MachineApplicable ,
378+ )
379+ . emit ( ) ;
380+ // Ideally, we'd remove the feature gating of a `let` expression since we are already
381+ // complaining about it here, but `feature_gate::check_crate` has already run by now:
382+ // self.sess.parse_sess.gated_spans.ungate_last(sym::let_chains, paren.span);
383+ }
384+
349385 /// Emit an error and lower `ast::ExprKind::Let(pat, scrutinee)` into:
350386 /// ```rust
351387 /// match scrutinee { pats => true, _ => false }
@@ -356,8 +392,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
356392 if self . sess . opts . unstable_features . is_nightly_build ( ) {
357393 self . sess
358394 . struct_span_err ( span, "`let` expressions are not supported here" )
359- . note ( "only supported directly in conditions of `if`- and `while`-expressions" )
360- . note ( "as well as when nested within `&&` and parenthesis in those conditions" )
395+ . note (
396+ "only supported directly without parentheses in conditions of `if`- and \
397+ `while`-expressions, as well as in `let` chains within parentheses",
398+ )
361399 . emit ( ) ;
362400 } else {
363401 self . sess
0 commit comments