@@ -67,40 +67,7 @@ impl LoweringContext<'_> {
6767 let ohs = P ( self . lower_expr ( ohs) ) ;
6868 hir:: ExprKind :: AddrOf ( m, ohs)
6969 }
70- ExprKind :: Let ( ref pats, ref scrutinee) => {
71- // If we got here, the `let` expression is not allowed.
72- self . sess
73- . struct_span_err ( e. span , "`let` expressions are not supported here" )
74- . note ( "only supported directly in conditions of `if`- and `while`-expressions" )
75- . note ( "as well as when nested within `&&` and parenthesis in those conditions" )
76- . emit ( ) ;
77-
78- // For better recovery, we emit:
79- // ```
80- // match scrutinee { pats => true, _ => false }
81- // ```
82- // While this doesn't fully match the user's intent, it has key advantages:
83- // 1. We can avoid using `abort_if_errors`.
84- // 2. We can typeck both `pats` and `scrutinee`.
85- // 3. `pats` is allowed to be refutable.
86- // 4. The return type of the block is `bool` which seems like what the user wanted.
87- let scrutinee = self . lower_expr ( scrutinee) ;
88- let then_arm = {
89- let pats = pats. iter ( ) . map ( |pat| self . lower_pat ( pat) ) . collect ( ) ;
90- let expr = self . expr_bool ( e. span , true ) ;
91- self . arm ( pats, P ( expr) )
92- } ;
93- let else_arm = {
94- let pats = hir_vec ! [ self . pat_wild( e. span) ] ;
95- let expr = self . expr_bool ( e. span , false ) ;
96- self . arm ( pats, P ( expr) )
97- } ;
98- hir:: ExprKind :: Match (
99- P ( scrutinee) ,
100- vec ! [ then_arm, else_arm] . into ( ) ,
101- hir:: MatchSource :: Normal ,
102- )
103- }
70+ ExprKind :: Let ( ref pats, ref scrutinee) => self . lower_expr_let ( e. span , pats, scrutinee) ,
10471 ExprKind :: If ( ref cond, ref then, ref else_opt) => {
10572 self . lower_expr_if ( e. span , cond, then, else_opt. as_deref ( ) )
10673 }
@@ -240,6 +207,50 @@ impl LoweringContext<'_> {
240207 }
241208 }
242209
210+ /// Emit an error and lower `ast::ExprKind::Let(pats, scrutinee)` into:
211+ /// ```rust
212+ /// match scrutinee { pats => true, _ => false }
213+ /// ```
214+ fn lower_expr_let (
215+ & mut self ,
216+ span : Span ,
217+ pats : & [ AstP < Pat > ] ,
218+ scrutinee : & Expr
219+ ) -> hir:: ExprKind {
220+ // If we got here, the `let` expression is not allowed.
221+ self . sess
222+ . struct_span_err ( span, "`let` expressions are not supported here" )
223+ . note ( "only supported directly in conditions of `if`- and `while`-expressions" )
224+ . note ( "as well as when nested within `&&` and parenthesis in those conditions" )
225+ . emit ( ) ;
226+
227+ // For better recovery, we emit:
228+ // ```
229+ // match scrutinee { pats => true, _ => false }
230+ // ```
231+ // While this doesn't fully match the user's intent, it has key advantages:
232+ // 1. We can avoid using `abort_if_errors`.
233+ // 2. We can typeck both `pats` and `scrutinee`.
234+ // 3. `pats` is allowed to be refutable.
235+ // 4. The return type of the block is `bool` which seems like what the user wanted.
236+ let scrutinee = self . lower_expr ( scrutinee) ;
237+ let then_arm = {
238+ let pats = pats. iter ( ) . map ( |pat| self . lower_pat ( pat) ) . collect ( ) ;
239+ let expr = self . expr_bool ( span, true ) ;
240+ self . arm ( pats, P ( expr) )
241+ } ;
242+ let else_arm = {
243+ let pats = hir_vec ! [ self . pat_wild( span) ] ;
244+ let expr = self . expr_bool ( span, false ) ;
245+ self . arm ( pats, P ( expr) )
246+ } ;
247+ hir:: ExprKind :: Match (
248+ P ( scrutinee) ,
249+ vec ! [ then_arm, else_arm] . into ( ) ,
250+ hir:: MatchSource :: Normal ,
251+ )
252+ }
253+
243254 fn lower_expr_if (
244255 & mut self ,
245256 span : Span ,
0 commit comments