//! > Test closure with Destruct.
//! > test_runner_name
test_generated_function
//! > cairo_code
#[target_function]
fn foo(a: Felt252Dict<felt252>) {
|| {
let _ = a;
};
}
//! > semantic_diagnostics
//! > lowering_diagnostics
//! > lowering
Main:
Parameters: v0: core::dict::Felt252Dict::<core::felt252>
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- struct_construct(v0)
(v2: ()) <- struct_construct()
End:
Return(v2)
Final lowering:
Parameters: v0: core::RangeCheck, v1: core::SegmentArena, v2: core::gas::GasBuiltin, v3: core::dict::Felt252Dict::<core::felt252>
blk0 (root):
Statements:
(v4: core::RangeCheck, v5: core::SegmentArena, v6: core::gas::GasBuiltin, v7: core::dict::SquashedFelt252Dict::<core::felt252>) <- core::dict::Felt252DictImpl::<core::felt252, core::Felt252Felt252DictValue>::squash(v0, v1, v2, v3)
End:
Return(v4, v5, v6)
Generated core::traits::Destruct::destruct lowering for source location:
|| {
^^
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
(v1: core::dict::Felt252Dict::<core::felt252>) <- struct_destructure(v0)
(v2: ()) <- struct_construct()
End:
Return(v2)
Final lowering:
Parameters: v0: core::RangeCheck, v1: core::SegmentArena, v2: core::gas::GasBuiltin, v3: test::foo::{closure#0}
blk0 (root):
Statements:
(v4: core::dict::Felt252Dict::<core::felt252>) <- struct_destructure(v3)
(v5: core::RangeCheck, v6: core::SegmentArena, v7: core::gas::GasBuiltin, v8: core::dict::SquashedFelt252Dict::<core::felt252>) <- core::dict::Felt252DictImpl::<core::felt252, core::Felt252Felt252DictValue>::squash(v0, v1, v2, v4)
End:
Return(v5, v6, v7)
Generated core::ops::function::FnOnce::call lowering for source location:
|| {
^^
Parameters: v0: test::foo::{closure#0}, v1: ()
blk0 (root):
Statements:
(v2: core::dict::Felt252Dict::<core::felt252>) <- struct_destructure(v0)
() <- struct_destructure(v1)
(v3: ()) <- struct_construct()
End:
Return(v3)
Final lowering:
Parameters: v0: core::RangeCheck, v1: core::SegmentArena, v2: core::gas::GasBuiltin, v3: test::foo::{closure#0}, v4: ()
blk0 (root):
Statements:
(v5: core::dict::Felt252Dict::<core::felt252>) <- struct_destructure(v3)
(v6: core::RangeCheck, v7: core::SegmentArena, v8: core::gas::GasBuiltin, v9: core::dict::SquashedFelt252Dict::<core::felt252>) <- core::dict::Felt252DictImpl::<core::felt252, core::Felt252Felt252DictValue>::squash(v0, v1, v2, v5)
End:
Return(v6, v7, v8)
//! > ==========================================================================
//! > Test closure with PanicDestruct.
//! > test_runner_name
test_generated_function
//! > cairo_code
struct PanicDestructable {}
impl MyPanicDestruct of PanicDestruct<PanicDestructable> {
// Disable inlining to see the panic_destruct call in the lowering output.
#[inline(never)]
fn panic_destruct(self: PanicDestructable, ref panic: Panic) nopanic {
let PanicDestructable { } = self;
}
}
#[target_function]
fn foo(a: PanicDestructable) {
|| {
let PanicDestructable { } = a;
};
panic!("Panic");
}
//! > semantic_diagnostics
//! > lowering_diagnostics
//! > lowering
Main:
Parameters: v0: test::PanicDestructable
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- struct_construct(v0)
(v2: core::array::Array::<core::bytes_31::bytes31>) <- core::array::array_new::<core::bytes_31::bytes31>()
(v3: core::felt252) <- 345232009571
(v4: core::internal::bounded_int::BoundedInt::<0, 30>) <- 5
(v5: core::byte_array::ByteArray) <- struct_construct(v2, v3, v4)
(v6: core::byte_array::ByteArray, v7: @core::byte_array::ByteArray) <- snapshot(v5)
(v8: core::never) <- core::panics::panic_with_byte_array(v7)
End:
Match(match_enum(v8) {
})
Final lowering:
Parameters: v0: test::PanicDestructable
blk0 (root):
Statements:
(v1: core::panics::Panic) <- struct_construct()
(v2: core::panics::Panic) <- test::MyPanicDestruct::panic_destruct(v0, v1)
(v3: core::array::Array::<core::felt252>) <- core::array::array_new::<core::felt252>()
(v4: core::felt252) <- 1997209042069643135709344952807065910992472029923670688473712229447419591075
(v5: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v3, v4)
(v6: core::felt252) <- 0
(v7: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v5, v6)
(v8: core::felt252) <- 345232009571
(v9: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v7, v8)
(v10: core::felt252) <- 5
(v11: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v9, v10)
(v12: (core::panics::Panic, core::array::Array::<core::felt252>)) <- struct_construct(v2, v11)
(v13: core::panics::PanicResult::<((),)>) <- PanicResult::Err(v12)
End:
Return(v13)
Generated core::traits::PanicDestruct::panic_destruct lowering for source location:
|| {
^^
Parameters: v0: test::foo::{closure#0}, v1: core::panics::Panic
blk0 (root):
Statements:
(v2: test::PanicDestructable) <- struct_destructure(v0)
(v3: ()) <- struct_construct()
End:
Return(v1, v3)
Final lowering:
Parameters: v0: test::foo::{closure#0}, v1: core::panics::Panic
blk0 (root):
Statements:
(v2: test::PanicDestructable) <- struct_destructure(v0)
(v3: core::panics::Panic) <- test::MyPanicDestruct::panic_destruct(v2, v1)
End:
Return(v3)
Generated core::ops::function::FnOnce::call lowering for source location:
|| {
^^
Parameters: v0: test::foo::{closure#0}, v1: ()
blk0 (root):
Statements:
(v2: test::PanicDestructable) <- struct_destructure(v0)
() <- struct_destructure(v1)
() <- struct_destructure(v2)
(v3: ()) <- struct_construct()
End:
Return(v3)
Final lowering:
Parameters: v0: test::foo::{closure#0}, v1: ()
blk0 (root):
Statements:
(v2: test::PanicDestructable) <- struct_destructure(v0)
() <- struct_destructure(v2)
End:
Return()
//! > ==========================================================================
//! > Test closure with copy.
//! > test_runner_name
test_generated_function
//! > cairo_code
#[inline(never)]
fn identity<T>(t: T) -> T {
t
}
#[target_function]
fn foo(a: u32) {
let c = || a;
identity(c);
identity(c);
}
//! > semantic_diagnostics
//! > lowering_diagnostics
//! > lowering
Main:
Parameters: v0: core::integer::u32
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- struct_construct(v0)
(v2: test::foo::{closure#0}) <- test::identity::<test::foo::{closure#0}>(v1)
(v3: test::foo::{closure#0}) <- test::identity::<test::foo::{closure#0}>(v1)
(v4: ()) <- struct_construct()
End:
Return(v4)
Final lowering:
Parameters: v0: core::integer::u32
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- struct_construct(v0)
(v2: test::foo::{closure#0}) <- test::identity::<test::foo::{closure#0}>(v1)
(v3: test::foo::{closure#0}) <- test::identity::<test::foo::{closure#0}>(v1)
End:
Return()
Generated core::traits::Destruct::destruct lowering for source location:
let c = || a;
^^
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
(v1: core::integer::u32) <- struct_destructure(v0)
(v2: ()) <- struct_construct()
End:
Return(v2)
Final lowering:
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
End:
Return()
Generated core::ops::function::Fn::call lowering for source location:
let c = || a;
^^
Parameters: v0: @test::foo::{closure#0}, v2: ()
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- desnap(v0)
(v3: core::integer::u32) <- struct_destructure(v1)
() <- struct_destructure(v2)
End:
Return(v3)
Final lowering:
Parameters: v0: @test::foo::{closure#0}, v1: ()
blk0 (root):
Statements:
(v2: test::foo::{closure#0}) <- desnap(v0)
(v3: core::integer::u32) <- struct_destructure(v2)
End:
Return(v3)
//! > ==========================================================================
//! > Test closure with branching.
//! > test_runner_name
test_generated_function
//! > cairo_code
#[inline(never)]
fn bar(a: felt252) -> felt252 {
a + 1
}
#[target_function]
fn foo(a: u32) {
let f = |a: felt252| {
let mut b = @0;
if 1 == bar(2) {
b = @a;
} else {
b = @a;
}
};
let _ = f(0);
}
//! > semantic_diagnostics
//! > lowering_diagnostics
//! > lowering
Main:
Parameters: v0: core::integer::u32
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- struct_construct()
(v2: test::foo::{closure#0}, v3: @test::foo::{closure#0}) <- snapshot(v1)
(v4: core::felt252) <- 0
(v5: (core::felt252,)) <- struct_construct(v4)
(v6: ()) <- Generated `core::ops::function::Fn::call` for test::foo::{closure#0}(v3, v5)
(v7: ()) <- struct_construct()
End:
Return(v7)
Final lowering:
Parameters: v0: core::integer::u32
blk0 (root):
Statements:
(v1: core::felt252) <- 2
(v2: core::felt252) <- test::bar(v1)
(v3: core::felt252) <- 1
(v4: core::felt252) <- core::felt252_sub(v3, v2)
End:
Match(match core::felt252_is_zero(v4) {
IsZeroResult::Zero => blk1,
IsZeroResult::NonZero(v5) => blk2,
})
blk1:
Statements:
End:
Return()
blk2:
Statements:
End:
Return()
Generated core::traits::Destruct::destruct lowering for source location:
let f = |a: felt252| {
^^^^^^^^^^^^
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
() <- struct_destructure(v0)
(v1: ()) <- struct_construct()
End:
Return(v1)
Final lowering:
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
End:
Return()
Generated core::ops::function::Fn::call lowering for source location:
let f = |a: felt252| {
^^^^^^^^^^^^
Parameters: v0: @test::foo::{closure#0}, v2: (core::felt252,)
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- 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) <- test::bar(v10)
(v12: core::felt252, v13: @core::felt252) <- snapshot(v11)
(v14: core::bool) <- core::Felt252PartialEq::eq(v9, v13)
End:
Match(match_enum(v14) {
bool::False(v16) => blk2,
bool::True(v15) => blk1,
})
blk1:
Statements:
(v19: core::felt252, v20: @core::felt252) <- snapshot(v3)
End:
Goto(blk3, {v19 -> v21, v20 -> v22})
blk2:
Statements:
(v17: core::felt252, v18: @core::felt252) <- snapshot(v3)
End:
Goto(blk3, {v17 -> v21, v18 -> v22})
blk3:
Statements:
(v23: ()) <- struct_construct()
End:
Return(v23)
Final lowering:
Parameters: v0: @test::foo::{closure#0}, v1: (core::felt252,)
blk0 (root):
Statements:
(v2: core::felt252) <- 2
(v3: core::felt252) <- test::bar(v2)
(v4: core::felt252) <- 1
(v5: core::felt252) <- core::felt252_sub(v4, v3)
End:
Match(match core::felt252_is_zero(v5) {
IsZeroResult::Zero => blk1,
IsZeroResult::NonZero(v6) => blk2,
})
blk1:
Statements:
End:
Return()
blk2:
Statements:
End:
Return()
//! > ==========================================================================
//! > Test passing non-inlined closure to a generic function.
//! > test_runner_name
test_generated_function
//! > cairo_code
fn apply<F, +Drop<F>, impl func: core::ops::FnOnce<F, (felt252,)>, +Drop<func::Output>>(f: F) {
f(2);
}
#[target_function]
fn foo() {
let uninlined_closure = |mut a| {
// Making sure the closure is long enough to not be inlined.
a += a + a + a + a + a;
a += a + a + a + a + a;
a += a + a + a + a + a;
a += a + a + a + a + a;
a += a + a + a + a + a;
return a;
};
// Call the function which applies the closure.
apply(uninlined_closure);
}
//! > semantic_diagnostics
//! > lowering_diagnostics
//! > lowering
Main:
Parameters:
blk0 (root):
Statements:
(v0: test::foo::{closure#0}) <- struct_construct()
(v1: ()) <- test::apply::<test::foo::{closure#0}, Generated core::traits::Drop::<test::foo::{closure#0}>, core::ops::function::FnOnceImpl::<test::foo::{closure#0}, (core::felt252,), core::traits::DestructFromDrop::<test::foo::{closure#0}, Generated core::traits::Drop::<test::foo::{closure#0}>>, Generated core::ops::function::Fn::<test::foo::{closure#0}, (core::felt252,)>>, core::felt252Drop>(v0)
(v2: ()) <- struct_construct()
End:
Return(v2)
Final lowering:
Parameters:
blk0 (root):
Statements:
End:
Return()
Generated core::traits::Destruct::destruct lowering for source location:
let uninlined_closure = |mut a| {
^^^^^^^
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
() <- struct_destructure(v0)
(v1: ()) <- struct_construct()
End:
Return(v1)
Final lowering:
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
End:
Return()
Generated core::ops::function::Fn::call lowering for source location:
let uninlined_closure = |mut a| {
^^^^^^^
Parameters: v0: @test::foo::{closure#0}, v2: (core::felt252,)
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- desnap(v0)
() <- struct_destructure(v1)
(v3: core::felt252) <- struct_destructure(v2)
(v4: core::felt252) <- core::Felt252Add::add(v3, v3)
(v5: core::felt252) <- core::Felt252Add::add(v4, v3)
(v6: core::felt252) <- core::Felt252Add::add(v5, v3)
(v7: core::felt252) <- core::Felt252Add::add(v6, v3)
(v9: core::felt252, v8: ()) <- core::ops::arith::DeprecatedAddAssign::<core::felt252, core::Felt252AddEq>::add_assign(v3, v7)
(v10: core::felt252) <- core::Felt252Add::add(v9, v9)
(v11: core::felt252) <- core::Felt252Add::add(v10, v9)
(v12: core::felt252) <- core::Felt252Add::add(v11, v9)
(v13: core::felt252) <- core::Felt252Add::add(v12, v9)
(v15: core::felt252, v14: ()) <- core::ops::arith::DeprecatedAddAssign::<core::felt252, core::Felt252AddEq>::add_assign(v9, v13)
(v16: core::felt252) <- core::Felt252Add::add(v15, v15)
(v17: core::felt252) <- core::Felt252Add::add(v16, v15)
(v18: core::felt252) <- core::Felt252Add::add(v17, v15)
(v19: core::felt252) <- core::Felt252Add::add(v18, v15)
(v21: core::felt252, v20: ()) <- core::ops::arith::DeprecatedAddAssign::<core::felt252, core::Felt252AddEq>::add_assign(v15, v19)
(v22: core::felt252) <- core::Felt252Add::add(v21, v21)
(v23: core::felt252) <- core::Felt252Add::add(v22, v21)
(v24: core::felt252) <- core::Felt252Add::add(v23, v21)
(v25: core::felt252) <- core::Felt252Add::add(v24, v21)
(v27: core::felt252, v26: ()) <- core::ops::arith::DeprecatedAddAssign::<core::felt252, core::Felt252AddEq>::add_assign(v21, v25)
(v28: core::felt252) <- core::Felt252Add::add(v27, v27)
(v29: core::felt252) <- core::Felt252Add::add(v28, v27)
(v30: core::felt252) <- core::Felt252Add::add(v29, v27)
(v31: core::felt252) <- core::Felt252Add::add(v30, v27)
(v33: core::felt252, v32: ()) <- core::ops::arith::DeprecatedAddAssign::<core::felt252, core::Felt252AddEq>::add_assign(v27, v31)
End:
Return(v33)
Final lowering:
Parameters: v0: @test::foo::{closure#0}, v1: (core::felt252,)
blk0 (root):
Statements:
(v2: core::felt252) <- struct_destructure(v1)
(v3: core::felt252) <- core::felt252_add(v2, v2)
(v4: core::felt252) <- core::felt252_add(v3, v2)
(v5: core::felt252) <- core::felt252_add(v4, v2)
(v6: core::felt252) <- core::felt252_add(v5, v2)
(v7: core::felt252) <- core::felt252_add(v2, v6)
(v8: core::felt252) <- core::felt252_add(v7, v7)
(v9: core::felt252) <- core::felt252_add(v8, v7)
(v10: core::felt252) <- core::felt252_add(v9, v7)
(v11: core::felt252) <- core::felt252_add(v10, v7)
(v12: core::felt252) <- core::felt252_add(v7, v11)
(v13: core::felt252) <- core::felt252_add(v12, v12)
(v14: core::felt252) <- core::felt252_add(v13, v12)
(v15: core::felt252) <- core::felt252_add(v14, v12)
(v16: core::felt252) <- core::felt252_add(v15, v12)
(v17: core::felt252) <- core::felt252_add(v12, v16)
(v18: core::felt252) <- core::felt252_add(v17, v17)
(v19: core::felt252) <- core::felt252_add(v18, v17)
(v20: core::felt252) <- core::felt252_add(v19, v17)
(v21: core::felt252) <- core::felt252_add(v20, v17)
(v22: core::felt252) <- core::felt252_add(v17, v21)
(v23: core::felt252) <- core::felt252_add(v22, v22)
(v24: core::felt252) <- core::felt252_add(v23, v22)
(v25: core::felt252) <- core::felt252_add(v24, v22)
(v26: core::felt252) <- core::felt252_add(v25, v22)
(v27: core::felt252) <- core::felt252_add(v22, v26)
End:
Return(v27)
//! > ==========================================================================
//! > Test Nested closure
//! > test_runner_name
test_generated_function
//! > cairo_code
#[target_function]
fn foo(a: Array<felt252>) -> u32 {
let inner = |x| {
let nested = |y| {
y + a.len()
};
nested(x)
};
inner(42)
}
//! > semantic_diagnostics
//! > lowering_diagnostics
//! > lowering
Main:
Parameters: v0: core::array::Array::<core::felt252>
blk0 (root):
Statements:
(v1: core::array::Array::<core::felt252>, v2: @core::array::Array::<core::felt252>) <- snapshot(v0)
(v3: test::foo::{closure#0}) <- struct_construct(v2)
(v4: test::foo::{closure#0}, v5: @test::foo::{closure#0}) <- snapshot(v3)
(v6: core::integer::u32) <- 42
(v7: (core::integer::u32,)) <- struct_construct(v6)
(v8: core::integer::u32) <- Generated `core::ops::function::Fn::call` for test::foo::{closure#0}(v5, v7)
End:
Return(v8)
Final lowering:
Parameters: v0: core::RangeCheck, v1: core::array::Array::<core::felt252>
blk0 (root):
Statements:
(v2: core::array::Array::<core::felt252>, v3: @core::array::Array::<core::felt252>) <- snapshot(v1)
(v4: core::integer::u32) <- core::array::array_len::<core::felt252>(v3)
(v5: core::integer::u32) <- 42
End:
Match(match core::integer::u32_overflowing_add(v0, v5, v4) {
Result::Ok(v6, v7) => blk1,
Result::Err(v8, v9) => blk2,
})
blk1:
Statements:
(v10: (core::integer::u32,)) <- struct_construct(v7)
(v11: core::panics::PanicResult::<(core::integer::u32,)>) <- PanicResult::Ok(v10)
End:
Return(v6, v11)
blk2:
Statements:
(v12: (core::panics::Panic, core::array::Array::<core::felt252>)) <- core::panic_with_const_felt252::<155785504323917466144735657540098748279>()
(v13: core::panics::PanicResult::<(core::integer::u32,)>) <- PanicResult::Err(v12)
End:
Return(v8, v13)
Generated core::traits::Destruct::destruct lowering for source location:
let inner = |x| {
^^^
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
(v1: @core::array::Array::<core::felt252>) <- struct_destructure(v0)
(v2: ()) <- struct_construct()
End:
Return(v2)
Final lowering:
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
End:
Return()
Generated core::traits::Destruct::destruct lowering for source location:
let nested = |y| {
^^^
Parameters: v0: test::foo::{closure#0}::{closure#0}
blk0 (root):
Statements:
(v1: @core::array::Array::<core::felt252>) <- struct_destructure(v0)
(v2: ()) <- struct_construct()
End:
Return(v2)
Final lowering:
Parameters: v0: test::foo::{closure#0}::{closure#0}
blk0 (root):
Statements:
End:
Return()
Generated core::ops::function::Fn::call lowering for source location:
let nested = |y| {
^^^
Parameters: v0: @test::foo::{closure#0}::{closure#0}, v2: (core::integer::u32,)
blk0 (root):
Statements:
(v1: test::foo::{closure#0}::{closure#0}) <- desnap(v0)
(v3: @core::array::Array::<core::felt252>) <- struct_destructure(v1)
(v4: core::integer::u32) <- struct_destructure(v2)
(v5: core::integer::u32) <- core::array::ArrayImpl::<core::felt252>::len(v3)
(v6: core::integer::u32) <- core::integer::U32Add::add(v4, v5)
End:
Return(v6)
Final lowering:
Parameters: v0: core::RangeCheck, v1: @test::foo::{closure#0}::{closure#0}, v2: (core::integer::u32,)
blk0 (root):
Statements:
(v3: test::foo::{closure#0}::{closure#0}) <- desnap(v1)
(v4: @core::array::Array::<core::felt252>) <- struct_destructure(v3)
(v5: core::integer::u32) <- core::array::array_len::<core::felt252>(v4)
(v6: core::integer::u32) <- struct_destructure(v2)
End:
Match(match core::integer::u32_overflowing_add(v0, v6, v5) {
Result::Ok(v7, v8) => blk1,
Result::Err(v9, v10) => blk2,
})
blk1:
Statements:
(v11: (core::integer::u32,)) <- struct_construct(v8)
(v12: core::panics::PanicResult::<(core::integer::u32,)>) <- PanicResult::Ok(v11)
End:
Return(v7, v12)
blk2:
Statements:
(v13: (core::panics::Panic, core::array::Array::<core::felt252>)) <- core::panic_with_const_felt252::<155785504323917466144735657540098748279>()
(v14: core::panics::PanicResult::<(core::integer::u32,)>) <- PanicResult::Err(v13)
End:
Return(v9, v14)
Generated core::ops::function::Fn::call lowering for source location:
let inner = |x| {
^^^
Parameters: v0: @test::foo::{closure#0}, v2: (core::integer::u32,)
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- desnap(v0)
(v3: @core::array::Array::<core::felt252>) <- struct_destructure(v1)
(v4: core::integer::u32) <- struct_destructure(v2)
(v5: test::foo::{closure#0}::{closure#0}) <- struct_construct(v3)
(v6: test::foo::{closure#0}::{closure#0}, v7: @test::foo::{closure#0}::{closure#0}) <- snapshot(v5)
(v8: (core::integer::u32,)) <- struct_construct(v4)
(v9: core::integer::u32) <- Generated `core::ops::function::Fn::call` for test::foo::{closure#0}::{closure#0}(v7, v8)
End:
Return(v9)
Final lowering:
Parameters: v0: core::RangeCheck, v1: @test::foo::{closure#0}, v2: (core::integer::u32,)
blk0 (root):
Statements:
(v3: test::foo::{closure#0}) <- desnap(v1)
(v4: @core::array::Array::<core::felt252>) <- struct_destructure(v3)
(v5: core::integer::u32) <- core::array::array_len::<core::felt252>(v4)
(v6: core::integer::u32) <- struct_destructure(v2)
End:
Match(match core::integer::u32_overflowing_add(v0, v6, v5) {
Result::Ok(v7, v8) => blk1,
Result::Err(v9, v10) => blk2,
})
blk1:
Statements:
(v11: (core::integer::u32,)) <- struct_construct(v8)
(v12: core::panics::PanicResult::<(core::integer::u32,)>) <- PanicResult::Ok(v11)
End:
Return(v7, v12)
blk2:
Statements:
(v13: (core::panics::Panic, core::array::Array::<core::felt252>)) <- core::panic_with_const_felt252::<155785504323917466144735657540098748279>()
(v14: core::panics::PanicResult::<(core::integer::u32,)>) <- PanicResult::Err(v13)
End:
Return(v9, v14)
//! > ==========================================================================
//! > Test closure with `return` inside a loop does not add loop early-return machinery.
//! > test_runner_name
test_generated_function
//! > cairo_code
#[target_function]
fn foo(n: felt252) -> felt252 {
let mut i = n;
loop {
let f = || -> felt252 {
return 7;
};
i = i + f();
if i == 100 {
break i;
};
}
}
//! > semantic_diagnostics
//! > lowering_diagnostics
//! > lowering
Main:
Parameters: v0: core::felt252
blk0 (root):
Statements:
(v2: core::felt252, v1: core::felt252) <- test::foo::{loop#0}(v0)
End:
Return(v1)
Final lowering:
Parameters: v0: core::RangeCheck, v1: core::gas::GasBuiltin, v2: core::felt252
blk0 (root):
Statements:
(v3: core::RangeCheck, v4: core::gas::GasBuiltin, v5: core::panics::PanicResult::<(core::felt252, core::felt252)>) <- test::foo::{loop#0}(v0, v1, v2)
End:
Match(match_enum(v5) {
PanicResult::Ok(v6) => blk1,
PanicResult::Err(v7) => blk2,
})
blk1:
Statements:
(v8: core::gas::GasBuiltin) <- core::gas::redeposit_gas(v4)
(v9: core::felt252, v10: core::felt252) <- struct_destructure(v6)
(v11: (core::felt252,)) <- struct_construct(v10)
(v12: core::panics::PanicResult::<(core::felt252,)>) <- PanicResult::Ok(v11)
End:
Return(v3, v8, v12)
blk2:
Statements:
(v13: core::panics::PanicResult::<(core::felt252,)>) <- PanicResult::Err(v7)
End:
Return(v3, v4, v13)
Generated core::traits::Destruct::destruct lowering for source location:
let f = || -> felt252 {
^^
Parameters: v0: test::foo::{loop#0}::{closure#0}
blk0 (root):
Statements:
() <- struct_destructure(v0)
(v1: ()) <- struct_construct()
End:
Return(v1)
Final lowering:
Parameters: v0: test::foo::{loop#0}::{closure#0}
blk0 (root):
Statements:
End:
Return()
Generated core::ops::function::Fn::call lowering for source location:
let f = || -> felt252 {
^^
Parameters: v0: @test::foo::{loop#0}::{closure#0}, v2: ()
blk0 (root):
Statements:
(v1: test::foo::{loop#0}::{closure#0}) <- desnap(v0)
() <- struct_destructure(v1)
() <- struct_destructure(v2)
(v3: core::felt252) <- 7
End:
Return(v3)
Final lowering:
Parameters: v0: @test::foo::{loop#0}::{closure#0}, v1: ()
blk0 (root):
Statements:
(v2: core::felt252) <- 7
End:
Return(v2)
Generated loop lowering for source location:
loop {
_____^
| ...
| }
|_____^
Parameters: v0: core::felt252
blk0 (root):
Statements:
(v1: test::foo::{loop#0}::{closure#0}) <- struct_construct()
(v2: test::foo::{loop#0}::{closure#0}, v3: @test::foo::{loop#0}::{closure#0}) <- snapshot(v1)
(v4: ()) <- struct_construct()
(v5: core::felt252) <- Generated `core::ops::function::Fn::call` for test::foo::{loop#0}::{closure#0}(v3, v4)
(v6: core::felt252) <- core::Felt252Add::add(v0, v5)
(v7: core::felt252, v8: @core::felt252) <- snapshot(v6)
(v9: core::felt252) <- 100
(v10: core::felt252, v11: @core::felt252) <- snapshot(v9)
(v12: core::bool) <- core::Felt252PartialEq::eq(v8, v11)
End:
Match(match_enum(v12) {
bool::False(v14) => blk2,
bool::True(v13) => blk1,
})
blk1:
Statements:
End:
Return(v7, v7)
blk2:
Statements:
End:
Goto(blk3, {})
blk3:
Statements:
(v16: core::felt252, v15: core::felt252) <- test::foo::{loop#0}(v7)
End:
Return(v16, v15)
Final lowering:
Parameters: v0: core::RangeCheck, v1: core::gas::GasBuiltin, v2: core::felt252
blk0 (root):
Statements:
End:
Match(match core::gas::withdraw_gas(v0, v1) {
Option::Some(v3, v4) => blk1,
Option::None(v5, v6) => blk4,
})
blk1:
Statements:
(v7: core::felt252) <- 7
(v8: core::felt252) <- core::felt252_add(v2, v7)
(v9: core::felt252) <- 100
(v10: core::felt252) <- core::felt252_sub(v8, v9)
End:
Match(match core::felt252_is_zero(v10) {
IsZeroResult::Zero => blk2,
IsZeroResult::NonZero(v11) => blk3,
})
blk2:
Statements:
(v12: core::gas::GasBuiltin) <- core::gas::redeposit_gas(v4)
(v13: (core::felt252, core::felt252)) <- struct_construct(v8, v8)
(v14: core::panics::PanicResult::<(core::felt252, core::felt252)>) <- PanicResult::Ok(v13)
End:
Return(v3, v12, v14)
blk3:
Statements:
(v15: core::gas::GasBuiltin) <- core::gas::redeposit_gas(v4)
(v16: core::RangeCheck, v17: core::gas::GasBuiltin, v18: core::panics::PanicResult::<(core::felt252, core::felt252)>) <- test::foo::{loop#0}(v3, v15, v8)
End:
Return(v16, v17, v18)
blk4:
Statements:
(v19: (core::panics::Panic, core::array::Array::<core::felt252>)) <- core::panic_with_const_felt252::<375233589013918064796019>()
(v20: core::panics::PanicResult::<(core::felt252, core::felt252)>) <- PanicResult::Err(v19)
End:
Return(v5, v6, v20)
Final lowering of specialized call "test::foo::{loop#0}":
Parameters: v0: core::RangeCheck, v1: core::gas::GasBuiltin, v2: core::felt252
blk0 (root):
Statements:
End:
Match(match core::gas::withdraw_gas(v0, v1) {
Option::Some(v3, v4) => blk1,
Option::None(v5, v6) => blk4,
})
blk1:
Statements:
(v7: core::felt252) <- 7
(v8: core::felt252) <- core::felt252_add(v2, v7)
(v9: core::felt252) <- 100
(v10: core::felt252) <- core::felt252_sub(v8, v9)
End:
Match(match core::felt252_is_zero(v10) {
IsZeroResult::Zero => blk2,
IsZeroResult::NonZero(v11) => blk3,
})
blk2:
Statements:
(v12: core::gas::GasBuiltin) <- core::gas::redeposit_gas(v4)
(v13: (core::felt252, core::felt252)) <- struct_construct(v8, v8)
(v14: core::panics::PanicResult::<(core::felt252, core::felt252)>) <- PanicResult::Ok(v13)
End:
Return(v3, v12, v14)
blk3:
Statements:
(v15: core::gas::GasBuiltin) <- core::gas::redeposit_gas(v4)
(v16: core::RangeCheck, v17: core::gas::GasBuiltin, v18: core::panics::PanicResult::<(core::felt252, core::felt252)>) <- test::foo::{loop#0}(v3, v15, v8)
End:
Return(v16, v17, v18)
blk4:
Statements:
(v19: (core::panics::Panic, core::array::Array::<core::felt252>)) <- core::panic_with_const_felt252::<375233589013918064796019>()
(v20: core::panics::PanicResult::<(core::felt252, core::felt252)>) <- PanicResult::Err(v19)
End:
Return(v5, v6, v20)
//! > ==========================================================================
//! > Test closure desnapping a snapshot-only captured variable.
//! > test_runner_name
test_generated_function
//! > cairo_code
#[target_function]
fn foo(a: felt252) -> felt252 {
let f = || *(@a);
f()
}
//! > semantic_diagnostics
//! > lowering_diagnostics
//! > lowering
Main:
Parameters: v0: core::felt252
blk0 (root):
Statements:
(v1: core::felt252, v2: @core::felt252) <- snapshot(v0)
(v3: test::foo::{closure#0}) <- struct_construct(v2)
(v4: test::foo::{closure#0}, v5: @test::foo::{closure#0}) <- snapshot(v3)
(v6: ()) <- struct_construct()
(v7: core::felt252) <- Generated `core::ops::function::Fn::call` for test::foo::{closure#0}(v5, v6)
End:
Return(v7)
Final lowering:
Parameters: v0: core::felt252
blk0 (root):
Statements:
End:
Return(v0)
Generated core::traits::Destruct::destruct lowering for source location:
let f = || *(@a);
^^
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
(v1: @core::felt252) <- struct_destructure(v0)
(v2: ()) <- struct_construct()
End:
Return(v2)
Final lowering:
Parameters: v0: test::foo::{closure#0}
blk0 (root):
Statements:
End:
Return()
Generated core::ops::function::Fn::call lowering for source location:
let f = || *(@a);
^^
Parameters: v0: @test::foo::{closure#0}, v2: ()
blk0 (root):
Statements:
(v1: test::foo::{closure#0}) <- desnap(v0)
(v3: @core::felt252) <- struct_destructure(v1)
() <- struct_destructure(v2)
(v4: core::felt252) <- desnap(v3)
End:
Return(v4)
Final lowering:
Parameters: v0: @test::foo::{closure#0}, v1: ()
blk0 (root):
Statements:
(v2: test::foo::{closure#0}) <- desnap(v0)
(v3: @core::felt252) <- struct_destructure(v2)
(v4: core::felt252) <- desnap(v3)
End:
Return(v4)