@@ -13,9 +13,33 @@ use crate::plan::bodies::{
1313use crate :: plan:: placement:: { requires_temp_var, try_elide_tail_let} ;
1414use crate :: plan:: values:: { ValuePlan , value_plan_from_statements} ;
1515use crate :: utils:: wrap_if_struct_literal;
16- use syntax:: ast:: { BinaryOperator , Expression , Literal } ;
16+ use syntax:: ast:: { BinaryOperator , Expression , Literal , MatchArm , Pattern , TypedPattern } ;
1717use syntax:: types:: Type ;
1818
19+ fn if_let_match_arms (
20+ pattern : & Pattern ,
21+ typed_pattern : & Option < TypedPattern > ,
22+ consequence : & Expression ,
23+ alternative : & Expression ,
24+ ) -> Vec < MatchArm > {
25+ vec ! [
26+ MatchArm {
27+ pattern: pattern. clone( ) ,
28+ guard: None ,
29+ typed_pattern: typed_pattern. clone( ) ,
30+ expression: Box :: new( consequence. clone( ) ) ,
31+ } ,
32+ MatchArm {
33+ pattern: Pattern :: WildCard {
34+ span: alternative. get_span( ) ,
35+ } ,
36+ guard: None ,
37+ typed_pattern: None ,
38+ expression: Box :: new( alternative. clone( ) ) ,
39+ } ,
40+ ]
41+ }
42+
1943impl Planner < ' _ > {
2044 /// Allocate a fresh operand-temp result var and its `var V T` declaration
2145 /// as a typed setup leaf. The control-flow that assigns it follows as a
@@ -67,7 +91,7 @@ impl Planner<'_> {
6791 value_plan_from_statements ( vec ! [ declaration, LoweredStatement :: If ( plan) ] , result_var)
6892 }
6993
70- /// Lower a value-position `match`/`select` to a fresh operand-temp
94+ /// Lower a value-position `if let`/` match`/`select` to a fresh operand-temp
7195 /// variable. Only valid for non-never result types; never-typed branches
7296 /// route through `lower_to_operand_temp` as a diverging statement.
7397 pub ( crate ) fn plan_branching_as_operand_temp (
@@ -309,6 +333,22 @@ impl Planner<'_> {
309333 self . build_assignment_plan ( target, value, compound_operator. as_ref ( ) , fx) ;
310334 directed ( directive, LoweredStatement :: Assign ( plan) )
311335 }
336+ Expression :: IfLet {
337+ pattern,
338+ scrutinee,
339+ consequence,
340+ alternative,
341+ typed_pattern,
342+ ..
343+ } => {
344+ let directive = self . maybe_line_directive ( & expression. get_span ( ) ) ;
345+ let arms = if_let_match_arms ( pattern, typed_pattern, consequence, alternative) ;
346+ let body = self . lower_match_to_block ( scrutinee, & arms, & PlacePlan :: Statement , fx) ;
347+ directed (
348+ directive,
349+ LoweredStatement :: Match ( MatchStatementPlan { body } ) ,
350+ )
351+ }
312352 Expression :: Match { subject, arms, .. } => {
313353 let directive = self . maybe_line_directive ( & expression. get_span ( ) ) ;
314354 let body = self . lower_match_to_block ( subject, arms, & PlacePlan :: Statement , fx) ;
@@ -701,7 +741,7 @@ impl Planner<'_> {
701741 LoweredBlock { statements }
702742 }
703743
704- /// Lower a branching expression (`if`, `match`, `select`) into a
744+ /// Lower a branching expression (`if`, `if let`, ` match`, `select`) into a
705745 /// `LoweredBlock` targeting `place`. Centralises the dispatch shared by old
706746 /// emit paths that need to render a branching tail/assignment.
707747 pub ( crate ) fn lower_branching_to_block (
@@ -722,13 +762,24 @@ impl Planner<'_> {
722762 statements : vec ! [ LoweredStatement :: If ( plan) ] ,
723763 }
724764 }
765+ Expression :: IfLet {
766+ pattern,
767+ scrutinee,
768+ consequence,
769+ alternative,
770+ typed_pattern,
771+ ..
772+ } => {
773+ let arms = if_let_match_arms ( pattern, typed_pattern, consequence, alternative) ;
774+ self . lower_match_to_block ( scrutinee, & arms, place, fx)
775+ }
725776 Expression :: Match { subject, arms, .. } => {
726777 self . lower_match_to_block ( subject, arms, place, fx)
727778 }
728779 Expression :: Select { arms, .. } => LoweredBlock {
729780 statements : vec ! [ LoweredStatement :: Select ( self . lower_select( arms, place, fx) ) ] ,
730781 } ,
731- _ => unreachable ! ( "lower_branching_to_block: expected if/match/select" ) ,
782+ _ => unreachable ! ( "lower_branching_to_block: expected if/if-let/ match/select" ) ,
732783 }
733784 }
734785
@@ -795,7 +846,7 @@ impl Planner<'_> {
795846 /// Lower a single tail expression in return position to its return
796847 /// statements. Shared by branch-arm return lowering and function-body
797848 /// lowering; only leaf values and lowered-ABI returns become `RawGo`,
798- /// `if`/`match`/`select` tails recurse structurally with a `Return` place.
849+ /// `if`/`if let`/` match`/`select` tails recurse structurally with a `Return` place.
799850 pub ( crate ) fn lower_return_tail (
800851 & mut self ,
801852 last : & Expression ,
@@ -832,6 +883,21 @@ impl Planner<'_> {
832883 self . lower_if ( condition, consequence, alternative, & PlacePlan :: Return , fx) ;
833884 statements. push ( directed ( directive, LoweredStatement :: If ( plan) ) ) ;
834885 }
886+ Expression :: IfLet {
887+ pattern,
888+ scrutinee,
889+ consequence,
890+ alternative,
891+ typed_pattern,
892+ ..
893+ } => {
894+ if !directive. is_empty ( ) {
895+ statements. push ( LoweredStatement :: RawGo ( directive) ) ;
896+ }
897+ let arms = if_let_match_arms ( pattern, typed_pattern, consequence, alternative) ;
898+ let block = self . lower_match_to_block ( scrutinee, & arms, & PlacePlan :: Return , fx) ;
899+ statements. extend ( block. statements ) ;
900+ }
835901 Expression :: Match { subject, arms, .. } => {
836902 if !directive. is_empty ( ) {
837903 statements. push ( LoweredStatement :: RawGo ( directive) ) ;
0 commit comments