//! > Test closure with Destruct.

//! > test_runner_name
test_generated_function

//! > function
fn foo(a: Felt252Dict<felt252>,) {
    || {
        let _ = a;
    };
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering
Main:
Parameters: v0: core::dict::Felt252Dict::<core::felt252>
blk0 (root):
Statements:
  (v1: {closure@lib.cairo:2:5: 2:7}) <- 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: {closure@lib.cairo:2:5: 2:7}
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: {closure@lib.cairo:2:5: 2:7}
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: {closure@lib.cairo:2:5: 2:7}, 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: {closure@lib.cairo:2:5: 2:7}, 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

//! > function
fn foo(a: PanicDestructable) {
    || {
        let PanicDestructable { } = a;
    };
    panic!("Panic");
}

//! > function_name
foo

//! > module_code
struct PanicDestructable {}

impl MyPanicDesruct 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;
    }
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering
Main:
Parameters: v0: test::PanicDestructable
blk0 (root):
Statements:
  (v1: {closure@lib.cairo:11:5: 11:7}) <- struct_construct(v0)
  (v2: core::array::Array::<core::felt252>) <- core::array::ArrayImpl::<core::felt252>::new()
  (v3: core::felt252) <- 1997209042069643135709344952807065910992472029923670688473712229447419591075
  (v5: core::array::Array::<core::felt252>, v4: ()) <- core::array::ArrayImpl::<core::felt252>::append(v2, v3)
  (v6: core::felt252) <- 0
  (v8: core::array::Array::<core::felt252>, v7: ()) <- core::array::ArrayImpl::<core::felt252>::append(v5, v6)
  (v9: core::felt252) <- 345232009571
  (v11: core::array::Array::<core::felt252>, v10: ()) <- core::array::ArrayImpl::<core::felt252>::append(v8, v9)
  (v12: core::felt252) <- 5
  (v14: core::array::Array::<core::felt252>, v13: ()) <- core::array::ArrayImpl::<core::felt252>::append(v11, v12)
  (v15: core::panics::Panic) <- struct_construct()
  (v16: (core::panics::Panic, core::array::Array::<core::felt252>)) <- struct_construct(v15, v14)
End:
  Panic(v16)


Final lowering:
Parameters: v0: test::PanicDestructable
blk0 (root):
Statements:
  (v1: core::array::Array::<core::felt252>) <- core::array::array_new::<core::felt252>()
  (v2: core::felt252) <- 1997209042069643135709344952807065910992472029923670688473712229447419591075
  (v3: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v1, v2)
  (v4: core::felt252) <- 0
  (v5: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v3, v4)
  (v6: core::felt252) <- 345232009571
  (v7: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v5, v6)
  (v8: core::felt252) <- 5
  (v9: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v7, v8)
  (v10: core::panics::Panic) <- struct_construct()
  (v11: core::panics::Panic) <- test::MyPanicDesruct::panic_destruct(v0, v10)
  (v12: (core::panics::Panic, core::array::Array::<core::felt252>)) <- struct_construct(v11, v9)
  (v13: core::panics::PanicResult::<((),)>) <- PanicResult::Err(v12)
End:
  Return(v13)


Generated core::traits::PanicDestruct::panic_destruct lowering for source location:
    || {
    ^^

Parameters: v0: {closure@lib.cairo:11:5: 11:7}, v1: core::panics::Panic
blk0 (root):
Statements:
  (v2: test::PanicDestructable) <- struct_destructure(v0)
  (v3: ()) <- struct_construct()
End:
  Return(v1, v3)


Final lowering:
Parameters: v0: {closure@lib.cairo:11:5: 11:7}, v1: core::panics::Panic
blk0 (root):
Statements:
  (v2: test::PanicDestructable) <- struct_destructure(v0)
  (v3: core::panics::Panic) <- test::MyPanicDesruct::panic_destruct(v2, v1)
End:
  Return(v3)


Generated core::ops::function::FnOnce::call lowering for source location:
    || {
    ^^

Parameters: v0: {closure@lib.cairo:11:5: 11:7}, 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: {closure@lib.cairo:11:5: 11:7}, v1: ()
blk0 (root):
Statements:
End:
  Return()

//! > ==========================================================================

//! > Test closure with copy.

//! > test_runner_name
test_generated_function

//! > function
fn foo(a: u32) {
    let c =  || a;
    identity(c);
    identity(c);
}

//! > function_name
foo

//! > module_code
#[inline(never)]
fn identity<T>(t: T) -> T {
    t
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering
Main:
Parameters: v0: core::integer::u32
blk0 (root):
Statements:
  (v1: {closure@lib.cairo:6:14: 6:16}) <- struct_construct(v0)
  (v2: {closure@lib.cairo:6:14: 6:16}) <- test::identity::<{closure@lib.cairo:6:14: 6:16}>(v1)
  (v3: {closure@lib.cairo:6:14: 6:16}) <- test::identity::<{closure@lib.cairo:6:14: 6:16}>(v1)
  (v4: ()) <- struct_construct()
End:
  Return(v4)


Final lowering:
Parameters: v0: core::integer::u32
blk0 (root):
Statements:
  (v1: {closure@lib.cairo:6:14: 6:16}) <- struct_construct(v0)
  (v2: {closure@lib.cairo:6:14: 6:16}) <- test::identity::<{closure@lib.cairo:6:14: 6:16}>(v1)
  (v3: {closure@lib.cairo:6:14: 6:16}) <- test::identity::<{closure@lib.cairo:6:14: 6:16}>(v1)
End:
  Return()


Generated core::ops::function::FnOnce::call lowering for source location:
    let c =  || a;
             ^^

Parameters: v0: {closure@lib.cairo:6:14: 6:16}, v1: ()
blk0 (root):
Statements:
  (v2: core::integer::u32) <- struct_destructure(v0)
  () <- struct_destructure(v1)
End:
  Return(v2)


Final lowering:
Parameters: v0: {closure@lib.cairo:6:14: 6:16}, v1: ()
blk0 (root):
Statements:
  (v2: core::integer::u32) <- struct_destructure(v0)
End:
  Return(v2)
