From cdd718b3358e2ca4639666fab81660bef9d1a5bc Mon Sep 17 00:00:00 2001 From: TomerStarkware Date: Thu, 16 Jan 2025 12:05:54 +0200 Subject: [PATCH] added closure params to semantic defs in lowering --- crates/cairo-lang-lowering/src/lower/mod.rs | 2 + .../src/lower/test_data/closure | 154 ++++++++++++++++++ tests/bug_samples/issue7083.cairo | 10 ++ tests/bug_samples/lib.cairo | 1 + 4 files changed, 167 insertions(+) create mode 100644 tests/bug_samples/issue7083.cairo diff --git a/crates/cairo-lang-lowering/src/lower/mod.rs b/crates/cairo-lang-lowering/src/lower/mod.rs index 7b852bb3192..895394ce2a4 100644 --- a/crates/cairo-lang-lowering/src/lower/mod.rs +++ b/crates/cairo-lang-lowering/src/lower/mod.rs @@ -1889,6 +1889,8 @@ fn add_closure_call_function( .add(&mut ctx, &mut builder.statements); for (param_var, param) in param_vars.into_iter().zip(expr.params.iter()) { builder.semantics.introduce((¶meter_as_member_path(param.clone())).into(), param_var); + ctx.semantic_defs + .insert(semantic::VarId::Param(param.id), semantic::Binding::Param(param.clone())); } let lowered_expr = lower_expr(&mut ctx, &mut builder, expr.body); let maybe_sealed_block = lowered_expr_to_block_scope_end(&mut ctx, builder, lowered_expr); diff --git a/crates/cairo-lang-lowering/src/lower/test_data/closure b/crates/cairo-lang-lowering/src/lower/test_data/closure index a121fe34854..4f93940c588 100644 --- a/crates/cairo-lang-lowering/src/lower/test_data/closure +++ b/crates/cairo-lang-lowering/src/lower/test_data/closure @@ -299,3 +299,157 @@ Statements: (v3: core::integer::u32) <- struct_destructure(v2) End: Return(v3) + +//! > ========================================================================== + +//! > Test closure with branching. + +//! > test_runner_name +test_generated_function + +//! > function +fn foo(a: u32) { + let f = |a: felt252| { + let mut b = @0; + if 1 == 2 { + b = @a; + } else { + b = @a; + } + }; + let _ = f(0); +} + +//! > function_name +foo + +//! > module_code + +//! > semantic_diagnostics + +//! > lowering_diagnostics + +//! > lowering +Main: +Parameters: v0: core::integer::u32 +blk0 (root): +Statements: + (v1: {closure@lib.cairo:2:13: 2:25}) <- struct_construct() + (v2: {closure@lib.cairo:2:13: 2:25}, v3: @{closure@lib.cairo:2:13: 2:25}) <- snapshot(v1) + (v4: core::felt252) <- 0 + (v5: (core::felt252,)) <- struct_construct(v4) + (v6: ()) <- Generated core::ops::function::Fn::<{closure@lib.cairo:2:13: 2:25}, (core::felt252,)>::call(v3, v5) + (v7: ()) <- struct_construct() +End: + Return(v7) + + +Final lowering: +Parameters: v0: core::integer::u32 +blk0 (root): +Statements: + (v1: core::felt252) <- 1 + (v2: core::felt252) <- 2 + (v3: core::felt252) <- core::felt252_sub(v1, v2) +End: + Match(match core::felt252_is_zero(v3) { + IsZeroResult::Zero => blk1, + IsZeroResult::NonZero(v4) => blk2, + }) + +blk1: +Statements: +End: + Return() + +blk2: +Statements: +End: + Return() + + +Generated core::traits::Destruct::destruct lowering for source location: + let f = |a: felt252| { + ^^^^^^^^^^^^ + +Parameters: v0: {closure@lib.cairo:2:13: 2:25} +blk0 (root): +Statements: + () <- struct_destructure(v0) + (v1: ()) <- struct_construct() +End: + Return(v1) + + +Final lowering: +Parameters: v0: {closure@lib.cairo:2:13: 2:25} +blk0 (root): +Statements: +End: + Return() + + +Generated core::ops::function::Fn::call lowering for source location: + let f = |a: felt252| { + ^^^^^^^^^^^^ + +Parameters: v0: @{closure@lib.cairo:2:13: 2:25}, v2: (core::felt252,) +blk0 (root): +Statements: + (v1: {closure@lib.cairo:2:13: 2:25}) <- desnap(v0) + () <- struct_destructure(v1) + (v3: core::felt252) <- struct_destructure(v2) + (v4: core::felt252) <- 0 + (v5: core::felt252, v6: @core::felt252) <- snapshot(v4) + (v7: core::felt252) <- 1 + (v8: core::felt252, v9: @core::felt252) <- snapshot(v7) + (v10: core::felt252) <- 2 + (v11: core::felt252, v12: @core::felt252) <- snapshot(v10) + (v13: core::bool) <- core::Felt252PartialEq::eq(v9, v12) +End: + Match(match_enum(v13) { + bool::False(v17) => blk2, + bool::True(v14) => blk1, + }) + +blk1: +Statements: + (v15: core::felt252, v16: @core::felt252) <- snapshot(v3) +End: + Goto(blk3, {v15 -> v20, v16 -> v21}) + +blk2: +Statements: + (v18: core::felt252, v19: @core::felt252) <- snapshot(v3) +End: + Goto(blk3, {v18 -> v20, v19 -> v21}) + +blk3: +Statements: + (v22: ()) <- struct_construct() +End: + Return(v22) + + +Final lowering: +Parameters: v0: @{closure@lib.cairo:2:13: 2:25}, v1: (core::felt252,) +blk0 (root): +Statements: + (v2: core::felt252) <- 1 + (v3: core::felt252) <- 2 + (v4: core::felt252) <- core::felt252_sub(v2, v3) +End: + Match(match core::felt252_is_zero(v4) { + IsZeroResult::Zero => blk1, + IsZeroResult::NonZero(v5) => blk2, + }) + +blk1: +Statements: +End: + Return() + +blk2: +Statements: +End: + Return() diff --git a/tests/bug_samples/issue7083.cairo b/tests/bug_samples/issue7083.cairo new file mode 100644 index 00000000000..ab4f10fd0a5 --- /dev/null +++ b/tests/bug_samples/issue7083.cairo @@ -0,0 +1,10 @@ +fn main() { + let zero: ByteArray = "0"; + + let format_string = |acc: ByteArray, x: u8| { + format!("({acc} + {x})") + }; + + let result = format_string(zero, 1); + assert_eq!(result, "(0 + 1)"); +} diff --git a/tests/bug_samples/lib.cairo b/tests/bug_samples/lib.cairo index a3d01f3e257..9d035b98434 100644 --- a/tests/bug_samples/lib.cairo +++ b/tests/bug_samples/lib.cairo @@ -57,6 +57,7 @@ mod issue7031; mod issue7038; mod issue7060; mod issue7071; +mod issue7083; mod loop_break_in_match; mod loop_only_change; mod partial_param_local;