//! > Test struct folding.

//! > test_runner_name
test_split_structs

//! > function
fn foo(a: felt252) -> felt252 {
    let b = (a,);
    let c = (b,);
    let (d,) = c;
    let (e,) = d;
    e
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

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

//! > after
Parameters: v0: core::felt252
blk0 (root):
Statements:
End:
  Return(v0)

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

//! > Test destruct after merge

//! > test_runner_name
test_split_structs

//! > function
fn foo(a: felt252) -> felt252 {
    let (b,) = match a {
        0 => (0,),
        _ => (a,),
    };
    b
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: core::felt252
blk0 (root):
Statements:
End:
  Match(match core::felt252_is_zero(v0) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v1) => blk2,
  })

blk1:
Statements:
  (v2: core::felt252) <- 0
  (v3: (core::felt252,)) <- struct_construct(v2)
End:
  Goto(blk3, {v3 -> v4})

blk2:
Statements:
  (v5: (core::felt252,)) <- struct_construct(v0)
End:
  Goto(blk3, {v5 -> v4})

blk3:
Statements:
  (v6: core::felt252) <- struct_destructure(v4)
End:
  Return(v6)

//! > after
Parameters: v0: core::felt252
blk0 (root):
Statements:
End:
  Match(match core::felt252_is_zero(v0) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v1) => blk2,
  })

blk1:
Statements:
  (v2: core::felt252) <- 0
End:
  Goto(blk3, {v2 -> v7})

blk2:
Statements:
End:
  Goto(blk3, {v0 -> v7})

blk3:
Statements:
End:
  Return(v7)

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

//! > Test use in one arm 

//! > test_runner_name
test_split_structs

//! > function
fn foo(a: felt252) -> felt252 {
    let arr = array![10, 11, 12];

    let c = (a, arr);
    if a == 0 {
        let (a, _arr) = c;
        return a;
    } else {
        cosume(c);
        return 1;
    }
}

//! > function_name
foo

//! > module_code
extern fn cosume(arg: (felt252, Array<felt252>)) nopanic;

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v1: core::array::Array::<core::felt252>) <- core::array::array_new::<core::felt252>()
  (v2: core::felt252) <- 10
  (v3: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v1, v2)
  (v5: core::felt252) <- 11
  (v6: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v3, v5)
  (v8: core::felt252) <- 12
  (v9: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v6, v8)
  (v11: (core::felt252, core::array::Array::<core::felt252>)) <- struct_construct(v0, v9)
  (v12: core::felt252, v13: @core::felt252) <- snapshot(v0)
  (v14: core::felt252) <- 0
  (v15: core::felt252, v16: @core::felt252) <- snapshot(v14)
  (v17: core::felt252) <- desnap(v13)
  (v18: core::felt252) <- desnap(v16)
  (v19: core::felt252) <- core::felt252_sub(v17, v18)
End:
  Match(match core::felt252_is_zero(v19) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v20) => blk2,
  })

blk1:
Statements:
  (v21: ()) <- struct_construct()
  (v22: core::bool) <- bool::True(v21)
End:
  Goto(blk3, {v22 -> v23})

blk2:
Statements:
  (v24: ()) <- struct_construct()
  (v25: core::bool) <- bool::False(v24)
End:
  Goto(blk3, {v25 -> v23})

blk3:
Statements:
End:
  Match(match_enum(v23) {
    bool::False(v26) => blk4,
    bool::True(v27) => blk5,
  })

blk4:
Statements:
  () <- test::cosume(v11)
  (v28: core::felt252) <- 1
End:
  Return(v28)

blk5:
Statements:
  (v29: core::felt252, v30: core::array::Array::<core::felt252>) <- struct_destructure(v11)
End:
  Return(v29)

//! > after
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v1: core::array::Array::<core::felt252>) <- core::array::array_new::<core::felt252>()
  (v2: core::felt252) <- 10
  (v3: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v1, v2)
  (v5: core::felt252) <- 11
  (v6: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v3, v5)
  (v8: core::felt252) <- 12
  (v9: core::array::Array::<core::felt252>) <- core::array::array_append::<core::felt252>(v6, v8)
  (v12: core::felt252, v13: @core::felt252) <- snapshot(v0)
  (v14: core::felt252) <- 0
  (v15: core::felt252, v16: @core::felt252) <- snapshot(v14)
  (v17: core::felt252) <- desnap(v13)
  (v18: core::felt252) <- desnap(v16)
  (v19: core::felt252) <- core::felt252_sub(v17, v18)
End:
  Match(match core::felt252_is_zero(v19) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v20) => blk2,
  })

blk1:
Statements:
  (v21: ()) <- struct_construct()
  (v22: core::bool) <- bool::True(v21)
End:
  Goto(blk3, {v22 -> v23})

blk2:
Statements:
  (v24: ()) <- struct_construct()
  (v25: core::bool) <- bool::False(v24)
End:
  Goto(blk3, {v25 -> v23})

blk3:
Statements:
End:
  Match(match_enum(v23) {
    bool::False(v26) => blk4,
    bool::True(v27) => blk5,
  })

blk4:
Statements:
  (v31: (core::felt252, core::array::Array::<core::felt252>)) <- struct_construct(v0, v9)
  () <- test::cosume(v31)
  (v28: core::felt252) <- 1
End:
  Return(v28)

blk5:
Statements:
End:
  Return(v0)

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

//! > Test destructure after merge.

//! > test_runner_name
test_split_structs

//! > function
fn foo(a: felt252) -> felt252 {
    let tuple = match a {
        0 => (1, (2, 3)),
        _ => {
            let tuple = (a, (2, a));
            use_tuple(tuple);
            tuple
        },
    };
    let (b, (c, d)) = tuple;
    b + c + d
}

//! > function_name
foo

//! > module_code
extern fn use_tuple<T>(a: (felt252, T)) nopanic;

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: core::felt252
blk0 (root):
Statements:
End:
  Match(match core::felt252_is_zero(v0) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v1) => blk2,
  })

blk1:
Statements:
  (v2: core::felt252) <- 1
  (v3: core::felt252) <- 2
  (v4: core::felt252) <- 3
  (v5: (core::felt252, core::felt252)) <- struct_construct(v3, v4)
  (v6: (core::felt252, (core::felt252, core::felt252))) <- struct_construct(v2, v5)
End:
  Goto(blk3, {v6 -> v7})

blk2:
Statements:
  (v8: core::felt252) <- 2
  (v9: (core::felt252, core::felt252)) <- struct_construct(v8, v0)
  (v10: (core::felt252, (core::felt252, core::felt252))) <- struct_construct(v0, v9)
  () <- test::use_tuple::<(core::felt252, core::felt252)>(v10)
End:
  Goto(blk3, {v10 -> v7})

blk3:
Statements:
  (v11: core::felt252, v12: (core::felt252, core::felt252)) <- struct_destructure(v7)
  (v13: core::felt252, v14: core::felt252) <- struct_destructure(v12)
  (v15: core::felt252) <- core::felt252_add(v11, v13)
  (v16: core::felt252) <- core::felt252_add(v15, v14)
End:
  Return(v16)

//! > after
Parameters: v0: core::felt252
blk0 (root):
Statements:
End:
  Match(match core::felt252_is_zero(v0) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v1) => blk2,
  })

blk1:
Statements:
  (v2: core::felt252) <- 1
  (v3: core::felt252) <- 2
  (v4: core::felt252) <- 3
End:
  Goto(blk3, {v2 -> v17, v3 -> v19, v4 -> v20})

blk2:
Statements:
  (v8: core::felt252) <- 2
  (v9: (core::felt252, core::felt252)) <- struct_construct(v8, v0)
  (v10: (core::felt252, (core::felt252, core::felt252))) <- struct_construct(v0, v9)
  () <- test::use_tuple::<(core::felt252, core::felt252)>(v10)
End:
  Goto(blk3, {v0 -> v17, v8 -> v19, v0 -> v20})

blk3:
Statements:
  (v15: core::felt252) <- core::felt252_add(v17, v19)
  (v16: core::felt252) <- core::felt252_add(v15, v20)
End:
  Return(v16)

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

//! > Test construct after destruct.

//! > test_runner_name
test_split_structs

//! > function
fn foo(a: felt252) -> (felt252, felt252) {
    let b = (a, a);
    let tuple = match a {
        0 => { b },
        _ => {
            let (c, _) = b;
            (c, c)
        },
    };
    tuple
}

//! > function_name
foo

//! > module_code
extern fn use_tuple<T>(a: (felt252, T)) nopanic;

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v1: (core::felt252, core::felt252)) <- struct_construct(v0, v0)
End:
  Match(match core::felt252_is_zero(v0) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v2) => blk2,
  })

blk1:
Statements:
End:
  Goto(blk3, {v1 -> v3})

blk2:
Statements:
  (v4: core::felt252, v5: core::felt252) <- struct_destructure(v1)
  (v6: (core::felt252, core::felt252)) <- struct_construct(v4, v4)
End:
  Goto(blk3, {v6 -> v3})

blk3:
Statements:
End:
  Return(v3)

//! > after
Parameters: v0: core::felt252
blk0 (root):
Statements:
End:
  Match(match core::felt252_is_zero(v0) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v2) => blk2,
  })

blk1:
Statements:
End:
  Goto(blk3, {v0 -> v7, v0 -> v8})

blk2:
Statements:
End:
  Goto(blk3, {v0 -> v7, v0 -> v8})

blk3:
Statements:
  (v3: (core::felt252, core::felt252)) <- struct_construct(v7, v8)
End:
  Return(v3)

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

//! > Test split var used in two arms (Optimization does not apply.)

//! > test_runner_name
test_split_structs

//! > function
fn foo(a: felt252) {
    let b = (a, a);
    match a {
        0 => {
            let (_, _) = b;
            use_tuple(b);
        },
        _ => {
            let (_, _) = b;
            use_tuple(b);
        },
    };
}

//! > function_name
foo

//! > module_code
extern fn use_tuple<T>(a: (felt252, T)) nopanic;

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v1: (core::felt252, core::felt252)) <- struct_construct(v0, v0)
End:
  Match(match core::felt252_is_zero(v0) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v2) => blk2,
  })

blk1:
Statements:
  () <- test::use_tuple::<core::felt252>(v1)
End:
  Goto(blk3, {})

blk2:
Statements:
  () <- test::use_tuple::<core::felt252>(v1)
End:
  Goto(blk3, {})

blk3:
Statements:
End:
  Return()

//! > after
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v1: (core::felt252, core::felt252)) <- struct_construct(v0, v0)
End:
  Match(match core::felt252_is_zero(v0) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v2) => blk2,
  })

blk1:
Statements:
  () <- test::use_tuple::<core::felt252>(v1)
End:
  Goto(blk3, {})

blk2:
Statements:
  () <- test::use_tuple::<core::felt252>(v1)
End:
  Goto(blk3, {})

blk3:
Statements:
End:
  Return()

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

//! > Test tuple constructed only in one arm.

//! > test_runner_name
test_split_structs

//! > function
fn foo(a: felt252) -> felt252 {
    let b = (a, a);
    let c = if a == 0 {
        (a, b)
    } else {
        get_tuple()
    };
    if a == 0 {
        let (d, e) = c;
        if d == 0 {
            let (f, g) = e;
            return f + g;
        }
    }
    return a;
}

//! > function_name
foo

//! > module_code
extern fn use_tuple<T>(a: (felt252, T)) nopanic;

extern fn get_tuple<T>() -> (felt252, T) nopanic;

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v1: (core::felt252, core::felt252)) <- struct_construct(v0, v0)
  (v2: core::felt252, v3: @core::felt252) <- snapshot(v0)
  (v4: core::felt252) <- 0
  (v5: core::felt252, v6: @core::felt252) <- snapshot(v4)
  (v7: core::felt252) <- desnap(v3)
  (v8: core::felt252) <- desnap(v6)
  (v9: core::felt252) <- core::felt252_sub(v7, v8)
End:
  Match(match core::felt252_is_zero(v9) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v10) => blk2,
  })

blk1:
Statements:
  (v11: ()) <- struct_construct()
  (v12: core::bool) <- bool::True(v11)
End:
  Goto(blk3, {v12 -> v13})

blk2:
Statements:
  (v14: ()) <- struct_construct()
  (v15: core::bool) <- bool::False(v14)
End:
  Goto(blk3, {v15 -> v13})

blk3:
Statements:
End:
  Match(match_enum(v13) {
    bool::False(v16) => blk4,
    bool::True(v17) => blk5,
  })

blk4:
Statements:
  (v18: core::felt252, v19: (core::felt252, core::felt252)) <- test::get_tuple::<(core::felt252, core::felt252)>()
  (v20: (core::felt252, (core::felt252, core::felt252))) <- struct_construct(v18, v19)
End:
  Goto(blk6, {v20 -> v21})

blk5:
Statements:
  (v22: (core::felt252, (core::felt252, core::felt252))) <- struct_construct(v2, v1)
End:
  Goto(blk6, {v22 -> v21})

blk6:
Statements:
  (v23: core::felt252, v24: @core::felt252) <- snapshot(v2)
  (v25: core::felt252) <- 0
  (v26: core::felt252, v27: @core::felt252) <- snapshot(v25)
  (v28: core::felt252) <- desnap(v24)
  (v29: core::felt252) <- desnap(v27)
  (v30: core::felt252) <- core::felt252_sub(v28, v29)
End:
  Match(match core::felt252_is_zero(v30) {
    IsZeroResult::Zero => blk7,
    IsZeroResult::NonZero(v31) => blk8,
  })

blk7:
Statements:
  (v32: ()) <- struct_construct()
  (v33: core::bool) <- bool::True(v32)
End:
  Goto(blk9, {v33 -> v34})

blk8:
Statements:
  (v35: ()) <- struct_construct()
  (v36: core::bool) <- bool::False(v35)
End:
  Goto(blk9, {v36 -> v34})

blk9:
Statements:
End:
  Match(match_enum(v34) {
    bool::False(v37) => blk10,
    bool::True(v38) => blk11,
  })

blk10:
Statements:
End:
  Goto(blk16, {})

blk11:
Statements:
  (v39: core::felt252, v40: (core::felt252, core::felt252)) <- struct_destructure(v21)
  (v41: core::felt252, v42: @core::felt252) <- snapshot(v39)
  (v43: core::felt252) <- 0
  (v44: core::felt252, v45: @core::felt252) <- snapshot(v43)
  (v46: core::felt252) <- desnap(v42)
  (v47: core::felt252) <- desnap(v45)
  (v48: core::felt252) <- core::felt252_sub(v46, v47)
End:
  Match(match core::felt252_is_zero(v48) {
    IsZeroResult::Zero => blk12,
    IsZeroResult::NonZero(v49) => blk13,
  })

blk12:
Statements:
  (v50: ()) <- struct_construct()
  (v51: core::bool) <- bool::True(v50)
End:
  Goto(blk14, {v51 -> v52})

blk13:
Statements:
  (v53: ()) <- struct_construct()
  (v54: core::bool) <- bool::False(v53)
End:
  Goto(blk14, {v54 -> v52})

blk14:
Statements:
End:
  Match(match_enum(v52) {
    bool::False(v55) => blk15,
    bool::True(v56) => blk17,
  })

blk15:
Statements:
End:
  Goto(blk16, {})

blk16:
Statements:
End:
  Return(v23)

blk17:
Statements:
  (v57: core::felt252, v58: core::felt252) <- struct_destructure(v40)
  (v59: core::felt252) <- core::felt252_add(v57, v58)
End:
  Return(v59)

//! > after
Parameters: v0: core::felt252
blk0 (root):
Statements:
  (v2: core::felt252, v3: @core::felt252) <- snapshot(v0)
  (v4: core::felt252) <- 0
  (v5: core::felt252, v6: @core::felt252) <- snapshot(v4)
  (v7: core::felt252) <- desnap(v3)
  (v8: core::felt252) <- desnap(v6)
  (v9: core::felt252) <- core::felt252_sub(v7, v8)
End:
  Match(match core::felt252_is_zero(v9) {
    IsZeroResult::Zero => blk1,
    IsZeroResult::NonZero(v10) => blk2,
  })

blk1:
Statements:
  (v11: ()) <- struct_construct()
  (v12: core::bool) <- bool::True(v11)
End:
  Goto(blk3, {v12 -> v13})

blk2:
Statements:
  (v14: ()) <- struct_construct()
  (v15: core::bool) <- bool::False(v14)
End:
  Goto(blk3, {v15 -> v13})

blk3:
Statements:
End:
  Match(match_enum(v13) {
    bool::False(v16) => blk4,
    bool::True(v17) => blk5,
  })

blk4:
Statements:
  (v18: core::felt252, v19: (core::felt252, core::felt252)) <- test::get_tuple::<(core::felt252, core::felt252)>()
  (v64: core::felt252, v65: core::felt252) <- struct_destructure(v19)
End:
  Goto(blk6, {v18 -> v60, v64 -> v62, v65 -> v63})

blk5:
Statements:
End:
  Goto(blk6, {v2 -> v60, v0 -> v62, v0 -> v63})

blk6:
Statements:
  (v23: core::felt252, v24: @core::felt252) <- snapshot(v2)
  (v25: core::felt252) <- 0
  (v26: core::felt252, v27: @core::felt252) <- snapshot(v25)
  (v28: core::felt252) <- desnap(v24)
  (v29: core::felt252) <- desnap(v27)
  (v30: core::felt252) <- core::felt252_sub(v28, v29)
End:
  Match(match core::felt252_is_zero(v30) {
    IsZeroResult::Zero => blk7,
    IsZeroResult::NonZero(v31) => blk8,
  })

blk7:
Statements:
  (v32: ()) <- struct_construct()
  (v33: core::bool) <- bool::True(v32)
End:
  Goto(blk9, {v33 -> v34})

blk8:
Statements:
  (v35: ()) <- struct_construct()
  (v36: core::bool) <- bool::False(v35)
End:
  Goto(blk9, {v36 -> v34})

blk9:
Statements:
End:
  Match(match_enum(v34) {
    bool::False(v37) => blk10,
    bool::True(v38) => blk11,
  })

blk10:
Statements:
End:
  Goto(blk16, {})

blk11:
Statements:
  (v41: core::felt252, v42: @core::felt252) <- snapshot(v60)
  (v43: core::felt252) <- 0
  (v44: core::felt252, v45: @core::felt252) <- snapshot(v43)
  (v46: core::felt252) <- desnap(v42)
  (v47: core::felt252) <- desnap(v45)
  (v48: core::felt252) <- core::felt252_sub(v46, v47)
End:
  Match(match core::felt252_is_zero(v48) {
    IsZeroResult::Zero => blk12,
    IsZeroResult::NonZero(v49) => blk13,
  })

blk12:
Statements:
  (v50: ()) <- struct_construct()
  (v51: core::bool) <- bool::True(v50)
End:
  Goto(blk14, {v51 -> v52})

blk13:
Statements:
  (v53: ()) <- struct_construct()
  (v54: core::bool) <- bool::False(v53)
End:
  Goto(blk14, {v54 -> v52})

blk14:
Statements:
End:
  Match(match_enum(v52) {
    bool::False(v55) => blk15,
    bool::True(v56) => blk17,
  })

blk15:
Statements:
End:
  Goto(blk16, {})

blk16:
Statements:
End:
  Return(v23)

blk17:
Statements:
  (v59: core::felt252) <- core::felt252_add(v62, v63)
End:
  Return(v59)

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

//! > Test split a struct with a non-dup members.

//! > test_runner_name
test_split_structs

//! > function
fn foo(a: felt252, e: ThreeCases) -> (felt252, NonDupStruct) {
    let b = (a, NonDupStruct { a });
    match e {
        ThreeCases::One => {
            let (_, non_dup) = b;
            use_struct(non_dup);
            (a, NonDupStruct { a: 0 })
        },
        ThreeCases::Two => {
            let (_, non_dup) = b;
            use_struct(non_dup);
            (a, NonDupStruct { a: 1 })
        },
        ThreeCases::Three => {
            use_tuple(b);
            (a, NonDupStruct { a: 0 })
        },
    }
}

//! > function_name
foo

//! > module_code
extern fn use_tuple<T>(a: (felt252, T)) nopanic;
extern fn use_struct(a: NonDupStruct) nopanic;

struct NonDupStruct {
    a: felt252,
}

enum ThreeCases {
    One,
    Two,
    Three,
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: core::felt252, v1: test::ThreeCases
blk0 (root):
Statements:
  (v2: test::NonDupStruct) <- struct_construct(v0)
  (v3: (core::felt252, test::NonDupStruct)) <- struct_construct(v0, v2)
End:
  Match(match_enum(v1) {
    ThreeCases::One(v4) => blk1,
    ThreeCases::Two(v5) => blk2,
    ThreeCases::Three(v6) => blk3,
  })

blk1:
Statements:
  (v7: core::felt252, v8: test::NonDupStruct) <- struct_destructure(v3)
  () <- test::use_struct(v8)
  (v9: core::felt252) <- 0
  (v10: test::NonDupStruct) <- struct_construct(v9)
  (v11: (core::felt252, test::NonDupStruct)) <- struct_construct(v0, v10)
End:
  Goto(blk4, {v11 -> v12})

blk2:
Statements:
  (v13: core::felt252, v14: test::NonDupStruct) <- struct_destructure(v3)
  () <- test::use_struct(v14)
  (v15: core::felt252) <- 1
  (v16: test::NonDupStruct) <- struct_construct(v15)
  (v17: (core::felt252, test::NonDupStruct)) <- struct_construct(v0, v16)
End:
  Goto(blk4, {v17 -> v12})

blk3:
Statements:
  () <- test::use_tuple::<test::NonDupStruct>(v3)
  (v18: core::felt252) <- 0
  (v19: test::NonDupStruct) <- struct_construct(v18)
  (v20: (core::felt252, test::NonDupStruct)) <- struct_construct(v0, v19)
End:
  Goto(blk4, {v20 -> v12})

blk4:
Statements:
End:
  Return(v12)

//! > after
Parameters: v0: core::felt252, v1: test::ThreeCases
blk0 (root):
Statements:
End:
  Match(match_enum(v1) {
    ThreeCases::One(v4) => blk1,
    ThreeCases::Two(v5) => blk2,
    ThreeCases::Three(v6) => blk3,
  })

blk1:
Statements:
  (v27: test::NonDupStruct) <- struct_construct(v0)
  () <- test::use_struct(v27)
  (v9: core::felt252) <- 0
End:
  Goto(blk4, {v0 -> v21, v9 -> v23})

blk2:
Statements:
  (v26: test::NonDupStruct) <- struct_construct(v0)
  () <- test::use_struct(v26)
  (v15: core::felt252) <- 1
End:
  Goto(blk4, {v0 -> v21, v15 -> v23})

blk3:
Statements:
  (v24: test::NonDupStruct) <- struct_construct(v0)
  (v25: (core::felt252, test::NonDupStruct)) <- struct_construct(v0, v24)
  () <- test::use_tuple::<test::NonDupStruct>(v25)
  (v18: core::felt252) <- 0
End:
  Goto(blk4, {v0 -> v21, v18 -> v23})

blk4:
Statements:
  (v22: test::NonDupStruct) <- struct_construct(v23)
  (v12: (core::felt252, test::NonDupStruct)) <- struct_construct(v21, v22)
End:
  Return(v12)
