@@ -87,9 +87,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
87
87
ExprKind :: Let ( ref pat, ref scrutinee) => {
88
88
self . lower_expr_let ( e. span , pat, scrutinee)
89
89
}
90
- ExprKind :: If ( ref cond, ref then, ref else_opt) => {
91
- self . lower_expr_if ( e. span , cond, then, else_opt. as_deref ( ) )
92
- }
90
+ ExprKind :: If ( ref cond, ref then, ref else_opt) => match cond. kind {
91
+ ExprKind :: Let ( ref pat, ref scrutinee) => {
92
+ self . lower_expr_if_let ( e. span , pat, scrutinee, then, else_opt. as_deref ( ) )
93
+ }
94
+ _ => self . lower_expr_if ( cond, then, else_opt. as_deref ( ) ) ,
95
+ } ,
93
96
ExprKind :: While ( ref cond, ref body, opt_label) => self
94
97
. with_loop_scope ( e. id , |this| {
95
98
this. lower_expr_while_in_loop_scope ( e. span , cond, body, opt_label)
@@ -337,10 +340,30 @@ impl<'hir> LoweringContext<'_, 'hir> {
337
340
338
341
fn lower_expr_if (
339
342
& mut self ,
340
- span : Span ,
341
343
cond : & Expr ,
342
344
then : & Block ,
343
345
else_opt : Option < & Expr > ,
346
+ ) -> hir:: ExprKind < ' hir > {
347
+ macro_rules! make_if {
348
+ ( $opt: expr) => { {
349
+ let then_expr = self . lower_block_expr( then) ;
350
+ hir:: ExprKind :: If ( self . lower_expr( cond) , self . arena. alloc( then_expr) , $opt)
351
+ } } ;
352
+ }
353
+ if let Some ( rslt) = else_opt {
354
+ make_if ! ( Some ( self . lower_expr( rslt) ) )
355
+ } else {
356
+ make_if ! ( None )
357
+ }
358
+ }
359
+
360
+ fn lower_expr_if_let (
361
+ & mut self ,
362
+ span : Span ,
363
+ pat : & Pat ,
364
+ scrutinee : & Expr ,
365
+ then : & Block ,
366
+ else_opt : Option < & Expr > ,
344
367
) -> hir:: ExprKind < ' hir > {
345
368
// FIXME(#53667): handle lowering of && and parens.
346
369
@@ -353,30 +376,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
353
376
let else_arm = self . arm ( else_pat, else_expr) ;
354
377
355
378
// Handle then + scrutinee:
356
- let ( then_pat, scrutinee, desugar) = match cond. kind {
357
- // `<pat> => <then>`:
358
- ExprKind :: Let ( ref pat, ref scrutinee) => {
359
- let scrutinee = self . lower_expr ( scrutinee) ;
360
- let pat = self . lower_pat ( pat) ;
361
- ( pat, scrutinee, hir:: MatchSource :: IfLetDesugar { contains_else_clause } )
362
- }
363
- // `true => <then>`:
364
- _ => {
365
- // Lower condition:
366
- let cond = self . lower_expr ( cond) ;
367
- let span_block =
368
- self . mark_span_with_reason ( DesugaringKind :: CondTemporary , cond. span , None ) ;
369
- // Wrap in a construct equivalent to `{ let _t = $cond; _t }`
370
- // to preserve drop semantics since `if cond { ... }` does not
371
- // let temporaries live outside of `cond`.
372
- let cond = self . expr_drop_temps ( span_block, cond, ThinVec :: new ( ) ) ;
373
- let pat = self . pat_bool ( span, true ) ;
374
- ( pat, cond, hir:: MatchSource :: IfDesugar { contains_else_clause } )
375
- }
376
- } ;
379
+ let scrutinee = self . lower_expr ( scrutinee) ;
380
+ let then_pat = self . lower_pat ( pat) ;
381
+
377
382
let then_expr = self . lower_block_expr ( then) ;
378
383
let then_arm = self . arm ( then_pat, self . arena . alloc ( then_expr) ) ;
379
384
385
+ let desugar = hir:: MatchSource :: IfLetDesugar { contains_else_clause } ;
380
386
hir:: ExprKind :: Match ( scrutinee, arena_vec ! [ self ; then_arm, else_arm] , desugar)
381
387
}
382
388
0 commit comments