@@ -5,7 +5,7 @@ use cairo_lang_diagnostics::Maybe;
55use cairo_lang_filesystem:: flag:: Flag ;
66use cairo_lang_filesystem:: ids:: FlagId ;
77use cairo_lang_semantic:: {
8- self as semantic, ConcreteEnumId , ConcreteVariant , GenericArgumentId , corelib,
8+ self as semantic, ConcreteEnumId , ConcreteVariant , GenericArgumentId , VarId , corelib,
99} ;
1010use cairo_lang_syntax:: node:: TypedStablePtr ;
1111use cairo_lang_syntax:: node:: ids:: SyntaxStablePtrId ;
@@ -28,6 +28,7 @@ use super::context::{
2828 LoweredExpr , LoweredExprExternEnum , LoweringContext , LoweringFlowError , LoweringResult ,
2929 lowering_flow_error_to_sealed_block,
3030} ;
31+ use super :: lower_let_else:: lower_success_arm_body;
3132use super :: {
3233 alloc_empty_block, generators, lower_expr_block, lower_expr_literal, lower_tail_expr,
3334 lowered_expr_to_block_scope_end, recursively_call_loop_func,
@@ -63,6 +64,9 @@ pub enum MatchArmWrapper<'a> {
6364 ElseClause ( semantic:: ExprId ) ,
6465 /// Default clause when else clause is not provided (if-let/while-let).
6566 DefaultClause ,
67+ /// The success arm of a let-else statement. See [super::lower_let_else::lower_let_else] for
68+ /// more details.
69+ LetElseSuccess ( & ' a [ PatternId ] , Vec < ( VarId , SyntaxStablePtrId ) > , SyntaxStablePtrId ) ,
6670}
6771
6872impl < ' a > From < & ' a semantic:: MatchArm > for MatchArmWrapper < ' a > {
@@ -72,21 +76,13 @@ impl<'a> From<&'a semantic::MatchArm> for MatchArmWrapper<'a> {
7276}
7377
7478impl MatchArmWrapper < ' _ > {
75- /// Returns the expression of the guarded by the match arm.
76- pub fn expr ( & self ) -> Option < semantic:: ExprId > {
77- match self {
78- MatchArmWrapper :: Arm ( _, expr) => Some ( * expr) ,
79- MatchArmWrapper :: ElseClause ( expr) => Some ( * expr) ,
80- MatchArmWrapper :: DefaultClause => None ,
81- }
82- }
83-
8479 /// Returns the patterns of the match arm.
8580 pub fn patterns ( & self ) -> Option < & [ PatternId ] > {
8681 match self {
8782 MatchArmWrapper :: Arm ( patterns, _) => Some ( patterns) ,
8883 MatchArmWrapper :: ElseClause ( _) => None ,
8984 MatchArmWrapper :: DefaultClause => None ,
85+ MatchArmWrapper :: LetElseSuccess ( patterns, _, _) => Some ( patterns) ,
9086 }
9187 }
9288
@@ -180,8 +176,8 @@ fn get_underscore_pattern_path_and_mark_unreachable(
180176 . iter ( )
181177 . enumerate ( )
182178 . filter_map ( |( arm_index, arm) | {
183- let pattern_index = match arm {
184- MatchArmWrapper :: Arm ( patterns, _ ) => {
179+ let pattern_index = match arm. patterns ( ) {
180+ Some ( patterns) => {
185181 let position = patterns. iter ( ) . position ( |pattern| {
186182 matches ! (
187183 ctx. function_body. arenas. patterns[ * pattern] ,
@@ -190,15 +186,15 @@ fn get_underscore_pattern_path_and_mark_unreachable(
190186 } ) ?;
191187 Some ( position)
192188 }
193- MatchArmWrapper :: DefaultClause | MatchArmWrapper :: ElseClause ( _ ) => None ,
189+ None => None ,
194190 } ;
195191 Some ( PatternPath { arm_index, pattern_index } )
196192 } )
197193 . next ( ) ?;
198194
199195 for arm in arms. iter ( ) . skip ( otherwise_variant. arm_index + 1 ) {
200196 match arm {
201- MatchArmWrapper :: Arm ( patterns, _expr ) => {
197+ MatchArmWrapper :: Arm ( patterns, _ ) | MatchArmWrapper :: LetElseSuccess ( patterns , _ , _ ) => {
202198 for pattern in * patterns {
203199 let pattern_ptr = ctx. function_body . arenas . patterns [ * pattern] . stable_ptr ( ) ;
204200 ctx. diagnostics . report (
@@ -1176,6 +1172,7 @@ trait EnumVariantScopeBuilder {
11761172 continue ;
11771173 }
11781174 MatchArmWrapper :: Arm ( patterns, _) => patterns,
1175+ MatchArmWrapper :: LetElseSuccess ( patterns, _, _) => patterns,
11791176 } ;
11801177 for ( pattern_index, pattern) in patterns. iter ( ) . copied ( ) . enumerate ( ) {
11811178 let pattern_path = PatternPath { arm_index, pattern_index : Some ( pattern_index) } ;
@@ -1347,7 +1344,7 @@ trait EnumVariantScopeBuilder {
13471344
13481345 /// Creates subscopes for match arms and collects them into block builders.
13491346 /// It then merges the blocks and returns the resulting lowered expression.
1350- ///
1347+ ///
13511348 /// This function is responsible for:
13521349 /// * Building a pattern tree to track variant coverage
13531350 /// * Creating subscopes for each match variant
@@ -1378,6 +1375,7 @@ trait EnumVariantScopeBuilder {
13781375 ) ;
13791376 } ,
13801377 MatchArmWrapper :: DefaultClause => ( ) ,
1378+ MatchArmWrapper :: LetElseSuccess ( _, _, _) => todo ! ( ) ,
13811379 }
13821380 }
13831381 return builder_context. builder . merge_and_end_with_match (
@@ -1779,10 +1777,16 @@ fn lower_arm_expr_and_seal(
17791777 arm : & MatchArmWrapper < ' _ > ,
17801778 mut subscope : BlockBuilder ,
17811779) -> Maybe < SealedBlockBuilder > {
1782- match ( arm. expr ( ) , kind) {
1783- ( Some ( expr) , MatchKind :: IfLet | MatchKind :: Match ) => lower_tail_expr ( ctx, subscope, expr) ,
1784- ( Some ( expr) , MatchKind :: WhileLet ( loop_expr_id, stable_ptr) ) => {
1785- let semantic:: Expr :: Block ( expr) = ctx. function_body . arenas . exprs [ expr] . clone ( ) else {
1780+ match ( arm, kind) {
1781+ (
1782+ MatchArmWrapper :: Arm ( _, expr) | MatchArmWrapper :: ElseClause ( expr) ,
1783+ MatchKind :: IfLet | MatchKind :: Match ,
1784+ ) => lower_tail_expr ( ctx, subscope, * expr) ,
1785+ (
1786+ MatchArmWrapper :: Arm ( _, expr) | MatchArmWrapper :: ElseClause ( expr) ,
1787+ MatchKind :: WhileLet ( loop_expr_id, stable_ptr) ,
1788+ ) => {
1789+ let semantic:: Expr :: Block ( expr) = ctx. function_body . arenas . exprs [ * expr] . clone ( ) else {
17861790 unreachable ! ( "WhileLet expression should be a block" ) ;
17871791 } ;
17881792 let block_expr = ( || {
@@ -1792,7 +1796,13 @@ fn lower_arm_expr_and_seal(
17921796
17931797 lowered_expr_to_block_scope_end ( ctx, subscope, block_expr)
17941798 }
1795- ( None , _) => Ok ( subscope. goto_callsite ( None ) ) ,
1799+ ( MatchArmWrapper :: DefaultClause , _) => Ok ( subscope. goto_callsite ( None ) ) ,
1800+ ( MatchArmWrapper :: LetElseSuccess ( _, vars, stable_ptr) , MatchKind :: Match ) => {
1801+ Ok ( lower_success_arm_body ( ctx, subscope, vars, stable_ptr) )
1802+ }
1803+ ( MatchArmWrapper :: LetElseSuccess ( _, _, _) , _) => {
1804+ unreachable ! ( "Invalid MatchKind for LetElseSuccess." )
1805+ }
17961806 }
17971807}
17981808
0 commit comments