@@ -87,9 +87,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
8787 ExprKind :: Let ( ref pat, ref scrutinee) => {
8888 self . lower_expr_let ( e. span , pat, scrutinee)
8989 }
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+ } ,
9396 ExprKind :: While ( ref cond, ref body, opt_label) => self
9497 . with_loop_scope ( e. id , |this| {
9598 this. lower_expr_while_in_loop_scope ( e. span , cond, body, opt_label)
@@ -337,10 +340,30 @@ impl<'hir> LoweringContext<'_, 'hir> {
337340
338341 fn lower_expr_if (
339342 & mut self ,
340- span : Span ,
341343 cond : & Expr ,
342344 then : & Block ,
343345 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 > ,
344367 ) -> hir:: ExprKind < ' hir > {
345368 // FIXME(#53667): handle lowering of && and parens.
346369
@@ -353,30 +376,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
353376 let else_arm = self . arm ( else_pat, else_expr) ;
354377
355378 // 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+
377382 let then_expr = self . lower_block_expr ( then) ;
378383 let then_arm = self . arm ( then_pat, self . arena . alloc ( then_expr) ) ;
379384
385+ let desugar = hir:: MatchSource :: IfLetDesugar { contains_else_clause } ;
380386 hir:: ExprKind :: Match ( scrutinee, arena_vec ! [ self ; then_arm, else_arm] , desugar)
381387 }
382388
0 commit comments