//! > match multi numbers.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: felt252) -> felt252 {
  let b=match a {
    5=> {550},
    6 => {70},
    _=>{90}
  };
  return b;
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Unsupported match arm - numbers must be sequential starting from 0.
 --> lib.cairo:3:5
    5=> {550},
    ^

//! > lowering_flat
Parameters: v0: core::felt252

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

//! > match felt.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: felt252) -> felt252 {
  match a {
    0 =>1,
    1 =>2,
    2 =>3,
    _ =>4,
  }
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
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) <- 1u
End:
  Goto(blk9, {v2 -> v14})

blk2:
Statements:
  (v3: core::felt252) <- 1u
  (v15: core::felt252) <- core::felt252_sub(v3, v0)
End:
  Match(match core::felt252_is_zero(v15) {
    IsZeroResult::Zero => blk3,
    IsZeroResult::NonZero(v5) => blk4,
  })

blk3:
Statements:
  (v6: core::felt252) <- 2u
End:
  Goto(blk8, {v6 -> v13})

blk4:
Statements:
  (v7: core::felt252) <- 2u
  (v16: core::felt252) <- core::felt252_sub(v7, v0)
End:
  Match(match core::felt252_is_zero(v16) {
    IsZeroResult::Zero => blk5,
    IsZeroResult::NonZero(v9) => blk6,
  })

blk5:
Statements:
  (v10: core::felt252) <- 3u
End:
  Goto(blk7, {v10 -> v12})

blk6:
Statements:
  (v11: core::felt252) <- 4u
End:
  Goto(blk7, {v11 -> v12})

blk7:
Statements:
End:
  Goto(blk8, {v12 -> v13})

blk8:
Statements:
End:
  Goto(blk9, {v13 -> v14})

blk9:
Statements:
End:
  Return(v14)

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

//! > Test match 0.

//! > test_runner_name
test_function_lowering

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

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

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

blk1:
Statements:
  (v3: core::felt252) <- 1u
  (v6: core::felt252) <- core::felt252_add(v0, v3)
End:
  Goto(blk3, {v6 -> v5})

blk2:
Statements:
End:
  Goto(blk3, {v1 -> v5})

blk3:
Statements:
End:
  Return(v5)

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

//! > Test array at.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: @Array::<felt252>) -> Option<Box<@felt252>> {
  core::array::array_get(a, 0_u32)
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v7: core::RangeCheck, v0: @core::array::Array::<core::felt252>
blk0 (root):
Statements:
  (v1: core::integer::u32) <- 0u
End:
  Match(match core::array::array_get::<core::felt252>(v7, v0, v1) {
    Option::Some(v8, v2) => blk1,
    Option::None(v9) => blk2,
  })

blk1:
Statements:
  (v3: core::option::Option::<core::box::Box::<@core::felt252>>) <- Option::Some(v2)
End:
  Goto(blk3, {v8 -> v10, v3 -> v6})

blk2:
Statements:
  (v4: ()) <- struct_construct()
  (v5: core::option::Option::<core::box::Box::<@core::felt252>>) <- Option::None(v4)
End:
  Goto(blk3, {v9 -> v10, v5 -> v6})

blk3:
Statements:
End:
  Return(v10, v6)

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

//! > Test match zero with non-zero value.

//! > test_runner_name
test_function_lowering

//! > function
fn foo() -> felt252 {
  let x = 7;
  match x {
      12 => x,
      _ => 7,
  }
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Unsupported match arm - numbers must be sequential starting from 0.
 --> lib.cairo:4:7
      12 => x,
      ^^

//! > lowering_flat
Parameters:

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

//! > Test unsupported match zero.

//! > test_runner_name
test_function_lowering

//! > function
fn foo() -> felt252 {
  let x = 7;
  match x {
      0 => x,
      1 => 7,
  }
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Match is non exhaustive - match over a numerical value must have a wildcard card pattern (`_`).
 --> lib.cairo:5:7
      1 => 7,
      ^

//! > lowering_flat
Parameters:

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

//! > Test unsupported match non felt252 value.

//! > test_runner_name
test_function_lowering

//! > function
fn foo() {
  match 5_u32 {
      0 => 7,
      _ => 8,
  };
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Unsupported matched value. Currently, only matches on enums and felt252s are supported.
 --> lib.cairo:2:9
  match 5_u32 {
        ^***^

//! > lowering_flat
Parameters:

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

//! > Test empty enum match.

//! > test_runner_name
test_function_lowering

//! > function
fn foo() {
  match Option::Some(5) {};
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Enum variant `Some` not covered.
 --> lib.cairo:2:3
  match Option::Some(5) {};
  ^**********************^

error: Enum variant `None` not covered.
 --> lib.cairo:2:3
  match Option::Some(5) {};
  ^**********************^

//! > lowering_flat
Parameters:

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

//! > Test empty enum match on empty enum.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(e: EmptyEnum) {
  match e {};
}

//! > function_name
foo

//! > module_code
enum EmptyEnum {}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::EmptyEnum
blk0 (root):
Statements:
End:
  Match(match_enum(v0) {
  })

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

//! > Test empty extern match.

//! > test_runner_name
test_function_lowering

//! > function
fn foo() {
  match felt252_is_zero(5) {};
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Enum variant `Zero` not covered.
 --> lib.cairo:2:9
  match felt252_is_zero(5) {};
        ^****************^

//! > lowering_flat
Parameters:

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

//! > Test otherwise extern match arm.

//! > test_runner_name
test_function_lowering

//! > function
fn foo() {
  match get_a() {
    A::One(_) => {},
    _ => {},
  };
}

//! > function_name
foo

//! > module_code
enum A {
  One: (),
  Two: (),
  Three: (),
}

extern fn get_a() -> A nopanic;

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters:
blk0 (root):
Statements:
End:
  Match(match test::get_a() {
    A::One => blk1,
    A::Two => blk2,
    A::Three => blk3,
  })

blk1:
Statements:
End:
  Goto(blk4, {})

blk2:
Statements:
End:
  Goto(blk4, {})

blk3:
Statements:
End:
  Goto(blk4, {})

blk4:
Statements:
  (v0: ()) <- struct_construct()
End:
  Return(v0)

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

//! > Test otherwise match arm.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: A) -> felt252 {
  match a {
    A::Two(_) => 2,
    A::One(_) => 1,
    _ => 3,
    A::Two(_) => 4,
    A::Three(_) => 5,
  }
}

//! > function_name
foo

//! > module_code
enum A {
  One: (),
  Two: (),
  Three: (),
  Four: (),
}

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Unreachable pattern arm.
 --> lib.cairo:12:5
    A::Two(_) => 4,
    ^*******^

error: Unreachable pattern arm.
 --> lib.cairo:13:5
    A::Three(_) => 5,
    ^*********^

//! > lowering_flat
Parameters: v0: test::A
blk0 (root):
Statements:
End:
  Match(match_enum(v0) {
    A::One(v1) => blk1,
    A::Two(v3) => blk2,
    A::Three(v5) => blk3,
    A::Four(v7) => blk4,
  })

blk1:
Statements:
  (v2: core::felt252) <- 1u
End:
  Goto(blk5, {v2 -> v9})

blk2:
Statements:
  (v4: core::felt252) <- 2u
End:
  Goto(blk5, {v4 -> v9})

blk3:
Statements:
  (v6: core::felt252) <- 3u
End:
  Goto(blk5, {v6 -> v9})

blk4:
Statements:
  (v8: core::felt252) <- 3u
End:
  Goto(blk5, {v8 -> v9})

blk5:
Statements:
End:
  Return(v9)

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

//! > Test out of order extern match arm.

//! > test_runner_name
test_function_lowering

//! > function
fn foo() -> felt252 {
  match get_a() {
      A::Two(_) => { 2 },
      A::One(_) => { 1 },
  }
}

//! > function_name
foo

//! > module_code
enum A {
  One: (),
  Two: (),
}

extern fn get_a() -> A nopanic;

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters:
blk0 (root):
Statements:
End:
  Match(match test::get_a() {
    A::One => blk1,
    A::Two => blk2,
  })

blk1:
Statements:
  (v0: core::felt252) <- 1u
End:
  Goto(blk3, {v0 -> v2})

blk2:
Statements:
  (v1: core::felt252) <- 2u
End:
  Goto(blk3, {v1 -> v2})

blk3:
Statements:
End:
  Return(v2)

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

//! > Test out of order match arm.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: A) -> felt252 {
  match a {
      A::Two(_) => { 2 },
      A::One(_) => { 1 },
  }
}

//! > function_name
foo

//! > module_code
enum A {
  One: (),
  Two: (),
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::A
blk0 (root):
Statements:
End:
  Match(match_enum(v0) {
    A::One(v1) => blk1,
    A::Two(v3) => blk2,
  })

blk1:
Statements:
  (v2: core::felt252) <- 1u
End:
  Goto(blk3, {v2 -> v5})

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

blk3:
Statements:
End:
  Return(v5)

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

//! > Match on tuples.

//! > test_runner_name
test_function_lowering

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

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Unsupported matched value. Currently, only matches on enums and felt252s are supported.
 --> lib.cairo:2:11
    match a {
          ^

//! > lowering_flat
Parameters: v0: (core::felt252, core::felt252)

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

//! > Match with complex patterns.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: Option<Option<felt252>>) -> felt252 {
    match a {
        Option::Some(Option::Some(x)) => x,
        Option::None(_) => 1,
        
    }
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Inner patterns are not in this context.
 --> lib.cairo:3:22
        Option::Some(Option::Some(x)) => x,
                     ^*************^

//! > lowering_flat
Parameters: v0: core::option::Option::<core::option::Option::<core::felt252>>

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

//! > Test missing arms.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: A) -> felt252 {
  match a {
    A::Two(_) => 2,
    A::One(_) => 1,
  }
}

//! > function_name
foo

//! > module_code
enum A {
  One: (),
  Two: (),
  Three: (),
  Four: (),
}

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Enum variant `Three` not covered.
 --> lib.cairo:8:3
  match a {
  ^*******^

error: Enum variant `Four` not covered.
 --> lib.cairo:8:3
  match a {
  ^*******^

//! > lowering_flat
Parameters: v0: test::A

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

//! > Test match on bool literals.

//! > test_runner_name
test_function_lowering

//! > function
fn foo(a: bool) -> felt252 {
  match a {
    true => 2,
    false => 1,
  }
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: core::bool
blk0 (root):
Statements:
End:
  Match(match_enum(v0) {
    bool::False(v1) => blk1,
    bool::True(v3) => blk2,
  })

blk1:
Statements:
  (v2: core::felt252) <- 1u
End:
  Goto(blk3, {v2 -> v5})

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

blk3:
Statements:
End:
  Return(v5)
