@@ -97,6 +97,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
97
97
ExprKind :: Let ( ref pat, ref scrutinee) => {
98
98
self . lower_expr_if_let ( e. span , pat, scrutinee, then, else_opt. as_deref ( ) )
99
99
}
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
+ } ,
100
117
_ => self . lower_expr_if ( cond, then, else_opt. as_deref ( ) ) ,
101
118
} ,
102
119
ExprKind :: While ( ref cond, ref body, opt_label) => self
@@ -346,6 +363,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
346
363
hir:: ExprKind :: Call ( f, self . lower_exprs ( & real_args) )
347
364
}
348
365
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
+
349
385
/// Emit an error and lower `ast::ExprKind::Let(pat, scrutinee)` into:
350
386
/// ```rust
351
387
/// match scrutinee { pats => true, _ => false }
@@ -356,8 +392,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
356
392
if self . sess . opts . unstable_features . is_nightly_build ( ) {
357
393
self . sess
358
394
. 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
+ )
361
399
. emit ( ) ;
362
400
} else {
363
401
self . sess
0 commit comments