//! > Test dedup of duplicated panic block.

//! > test_runner_name
test_dedup_blocks

//! > function_code
fn foo(mut a: Array<u32>) {
    a.pop_front().unwrap();
    a.pop_front().unwrap();
}

//! > function_name
foo

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: core::array::Array::<core::integer::u32>
blk0 (root):
Statements:
End:
  Match(match core::array::array_pop_front::<core::integer::u32>(v0) {
    Option::Some(v1, v2) => blk1,
    Option::None(v3) => blk4,
  })

blk1:
Statements:
  (v6: core::array::Array::<core::integer::u32>, v7: core::option::Option::<core::integer::u32>) <- core::array::ArrayImpl::<core::integer::u32>::pop_front(v1)
  (v8: core::panics::PanicResult::<(core::integer::u32,)>) <- core::option::OptionTraitImpl::<core::integer::u32>::unwrap(v7)
End:
  Match(match_enum(v8) {
    PanicResult::Ok(v9) => blk2,
    PanicResult::Err(v10) => blk3,
  })

blk2:
Statements:
  (v11: ()) <- struct_construct()
  (v12: ((),)) <- struct_construct(v11)
  (v13: core::panics::PanicResult::<((),)>) <- PanicResult::Ok(v12)
End:
  Return(v13)

blk3:
Statements:
  (v14: core::panics::PanicResult::<((),)>) <- PanicResult::Err(v10)
End:
  Return(v14)

blk4:
Statements:
  (v16: (core::panics::Panic, core::array::Array::<core::felt252>)) <- core::panic_with_const_felt252::<29721761890975875353235833581453094220424382983267374>()
  (v17: core::panics::PanicResult::<((),)>) <- PanicResult::Err(v16)
End:
  Return(v17)

//! > after
Parameters: v0: core::array::Array::<core::integer::u32>
blk0 (root):
Statements:
End:
  Match(match core::array::array_pop_front::<core::integer::u32>(v0) {
    Option::Some(v1, v2) => blk1,
    Option::None(v3) => blk4,
  })

blk1:
Statements:
  (v6: core::array::Array::<core::integer::u32>, v7: core::option::Option::<core::integer::u32>) <- core::array::ArrayImpl::<core::integer::u32>::pop_front(v1)
  (v8: core::panics::PanicResult::<(core::integer::u32,)>) <- core::option::OptionTraitImpl::<core::integer::u32>::unwrap(v7)
End:
  Match(match_enum(v8) {
    PanicResult::Ok(v9) => blk2,
    PanicResult::Err(v10) => blk3,
  })

blk2:
Statements:
  (v11: ()) <- struct_construct()
  (v12: ((),)) <- struct_construct(v11)
  (v13: core::panics::PanicResult::<((),)>) <- PanicResult::Ok(v12)
End:
  Return(v13)

blk3:
Statements:
  (v14: core::panics::PanicResult::<((),)>) <- PanicResult::Err(v10)
End:
  Return(v14)

blk4:
Statements:
  (v16: (core::panics::Panic, core::array::Array::<core::felt252>)) <- core::panic_with_const_felt252::<29721761890975875353235833581453094220424382983267374>()
  (v17: core::panics::PanicResult::<((),)>) <- PanicResult::Err(v16)
End:
  Return(v17)

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

//! > Test dedup of block with an external variable.

//! > test_runner_name
test_dedup_blocks

//! > function_code
fn foo(mut a: Array<felt252>) -> felt252 {
    if let Some(val) = a.pop_front() {
        return val + 5;
    }
    if let Some(val) = a.pop_front() {
        return val + 5;
    }
    1
}

//! > function_name
foo

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: core::array::Array::<core::felt252>
blk0 (root):
Statements:
End:
  Match(match core::array::array_pop_front::<core::felt252>(v0) {
    Option::Some(v1, v2) => blk1,
    Option::None(v3) => blk2,
  })

blk1:
Statements:
  (v4: core::felt252) <- unbox(v2)
  (v5: core::felt252) <- 5
  (v6: core::felt252) <- core::felt252_add(v4, v5)
End:
  Return(v6)

blk2:
Statements:
End:
  Match(match core::array::array_pop_front::<core::felt252>(v3) {
    Option::Some(v8, v9) => blk3,
    Option::None(v10) => blk4,
  })

blk3:
Statements:
  (v11: core::felt252) <- unbox(v9)
  (v12: core::felt252) <- 5
  (v13: core::felt252) <- core::felt252_add(v11, v12)
End:
  Return(v13)

blk4:
Statements:
  (v15: core::felt252) <- 1
End:
  Return(v15)

//! > after
Parameters: v0: core::array::Array::<core::felt252>
blk0 (root):
Statements:
End:
  Match(match core::array::array_pop_front::<core::felt252>(v0) {
    Option::Some(v1, v2) => blk6,
    Option::None(v3) => blk2,
  })

blk1:
Statements:
  (v4: core::felt252) <- unbox(v2)
  (v5: core::felt252) <- 5
  (v6: core::felt252) <- core::felt252_add(v4, v5)
End:
  Return(v6)

blk2:
Statements:
End:
  Match(match core::array::array_pop_front::<core::felt252>(v3) {
    Option::Some(v8, v9) => blk7,
    Option::None(v10) => blk4,
  })

blk3:
Statements:
  (v11: core::felt252) <- unbox(v9)
  (v12: core::felt252) <- 5
  (v13: core::felt252) <- core::felt252_add(v11, v12)
End:
  Return(v13)

blk4:
Statements:
  (v15: core::felt252) <- 1
End:
  Return(v15)

blk5:
Statements:
  (v17: core::felt252) <- unbox(v16)
  (v18: core::felt252) <- 5
  (v19: core::felt252) <- core::felt252_add(v17, v18)
End:
  Return(v19)

blk6:
Statements:
End:
  Goto(blk5, {v2 -> v16})

blk7:
Statements:
End:
  Goto(blk5, {v9 -> v16})

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

//! > Test dedup that modifies goto statement.

//! > test_runner_name
test_dedup_blocks

//! > function_code
fn foo(t: MyEnum) -> felt252 {
    let mut w = 8;
    let v = match t {
        MyEnum::V0(v) => { return v + w; },
        MyEnum::V1(v) => { return v + w; },
        MyEnum::V2(v) => {
            w = 9;
            v
        },
        MyEnum::V3(v) => v,
    };
    v + w
}

//! > module_code
enum MyEnum {
    V0: felt252,
    V1: felt252,
    V2: felt252,
    V3: felt252,
}

//! > function_name
foo

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > before
Parameters: v0: test::MyEnum
blk0 (root):
Statements:
  (v1: core::felt252) <- 8
End:
  Match(match_enum(v0) {
    MyEnum::V0(v2) => blk1,
    MyEnum::V1(v3) => blk2,
    MyEnum::V2(v4) => blk3,
    MyEnum::V3(v5) => blk4,
  })

blk1:
Statements:
  (v6: core::felt252) <- core::felt252_add(v2, v1)
End:
  Return(v6)

blk2:
Statements:
  (v7: core::felt252) <- core::felt252_add(v3, v1)
End:
  Return(v7)

blk3:
Statements:
  (v8: core::felt252) <- 9
End:
  Goto(blk5, {v8 -> v9, v4 -> v10})

blk4:
Statements:
End:
  Goto(blk5, {v1 -> v9, v5 -> v10})

blk5:
Statements:
  (v11: core::felt252) <- core::felt252_add(v10, v9)
End:
  Return(v11)

//! > after
Parameters: v0: test::MyEnum
blk0 (root):
Statements:
  (v1: core::felt252) <- 8
End:
  Match(match_enum(v0) {
    MyEnum::V0(v2) => blk7,
    MyEnum::V1(v3) => blk8,
    MyEnum::V2(v4) => blk3,
    MyEnum::V3(v5) => blk4,
  })

blk1:
Statements:
  (v6: core::felt252) <- core::felt252_add(v2, v1)
End:
  Return(v6)

blk2:
Statements:
  (v7: core::felt252) <- core::felt252_add(v3, v1)
End:
  Return(v7)

blk3:
Statements:
  (v8: core::felt252) <- 9
End:
  Goto(blk6, {v4 -> v12, v8 -> v13})

blk4:
Statements:
End:
  Goto(blk6, {v5 -> v12, v1 -> v13})

blk5:
Statements:
  (v11: core::felt252) <- core::felt252_add(v10, v9)
End:
  Return(v11)

blk6:
Statements:
  (v14: core::felt252) <- core::felt252_add(v12, v13)
End:
  Return(v14)

blk7:
Statements:
End:
  Goto(blk6, {v2 -> v12, v1 -> v13})

blk8:
Statements:
End:
  Goto(blk6, {v3 -> v12, v1 -> v13})
