//! > Test struct constructor.

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo(a: felt252) -> MyStruct {
    MyStruct { a: (), c: (3, 7), b: a }
}

//! > function_name
foo

//! > module_code
struct MyStruct {
    a: (),
    b: felt252,
    c: (felt252, felt252),
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v1: core::felt252) <- 3
  (v2: core::felt252) <- 7
  (v3: ()) <- struct_construct()
  (v4: (core::felt252, core::felt252)) <- struct_construct(v1, v2)
  (v5: test::MyStruct) <- struct_construct(v3, v0, v4)
End:
  Return(v5)

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

//! > Test struct member access.

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo(s: MyStruct) -> felt252 {
    s.b
}

//! > function_name
foo

//! > module_code
struct MyStruct {
    a: (),
    b: felt252,
    c: (felt252, felt252),
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::MyStruct
blk0 (root):
Statements:
  (v1: (), v2: core::felt252, v3: (core::felt252, core::felt252)) <- struct_destructure(v0)
End:
  Return(v2)

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

//! > Test struct destructure.

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo(s: MyStruct) -> (felt252, felt252) {
    let MyStruct { a: _, c: (v, _), b } = s;
    (v, b)
}

//! > function_name
foo

//! > module_code
struct MyStruct {
    a: (),
    b: felt252,
    c: (felt252, felt252),
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::MyStruct
blk0 (root):
Statements:
  (v1: (), v2: core::felt252, v3: (core::felt252, core::felt252)) <- struct_destructure(v0)
  (v4: core::felt252, v5: core::felt252) <- struct_destructure(v3)
  (v6: (core::felt252, core::felt252)) <- struct_construct(v4, v2)
End:
  Return(v6)

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

//! > Test struct tail construction.

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo(s: MyStruct) -> MyStruct {
    MyStruct { c: (1, 2), ..s }
}

//! > function_name
foo

//! > module_code
#[derive(Copy)]
struct MyStruct {
    a: (),
    b: felt252,
    c: (felt252, felt252),
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::MyStruct
blk0 (root):
Statements:
  (v1: core::felt252) <- 1
  (v2: core::felt252) <- 2
  (v3: (), v4: core::felt252, v5: (core::felt252, core::felt252)) <- struct_destructure(v0)
  (v6: (core::felt252, core::felt252)) <- struct_construct(v1, v2)
  (v7: test::MyStruct) <- struct_construct(v3, v4, v6)
End:
  Return(v7)

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

//! > Test struct construction members' order.

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo() -> MyStruct {
    MyStruct { c: f2(), a: (), b: f1() }
}

//! > function_name
foo

//! > module_code
struct MyStruct {
    b: felt252,
    a: (),
    c: (felt252, felt252),
}
extern fn f1() -> felt252 nopanic;
extern fn f2() -> (felt252, felt252) nopanic;

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters:
blk0 (root):
Statements:
  (v0: core::felt252, v1: core::felt252) <- test::f2()
  (v2: core::felt252) <- test::f1()
  (v3: ()) <- struct_construct()
  (v4: (core::felt252, core::felt252)) <- struct_construct(v0, v1)
  (v5: test::MyStruct) <- struct_construct(v2, v3, v4)
End:
  Return(v5)
