//! > Test unreachable code.

//! > test_function_name
test_function_lowering

//! > function
fn foo(a: felt) -> felt {
    return a + a * a;
    5;6;7
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics
error: Unreachable code
 --> lib.cairo:3:5
    5;6;7
    ^**^

//! > lowering_format
blk0 (root):
Inputs: v0: core::felt
Statements:
  (v1: core::felt) <- core::felt_mul(v0, v0)
  (v2: core::felt) <- core::felt_add(v0, v1)
Drops: v0, v1
End:
  Return(v2)

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

//! > Test single patterns.

//! > test_function_name
test_function_lowering

//! > function
fn foo(a: felt) -> felt {
    let (_, b) = (1, a);
    5
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_format
blk0 (root):
Inputs: v0: core::felt
Statements:
  (v1: core::felt) <- 1u
  (v2: core::felt) <- 5u
Drops: v0, v1
End:
  Callsite(v2)

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

//! > Test compound expressions.

//! > test_function_name
test_function_lowering

//! > function
fn foo(a: felt) -> felt {
  let x = {7;};
  {x;}
  let y = if 1 == 1 { 6 } else { 7 };
  foo(3) + 5 * {3; a + 0}
}

//! > function_name
foo

//! > module_code

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_format
blk0:
Inputs:
Statements:
  (v1: core::felt) <- 7u
Drops: v1
End:
  Callsite()

blk1:
Inputs:
Statements:
Drops:
End:
  Callsite()

blk2:
Inputs:
Statements:
  (v6: core::felt) <- 6u
Drops:
End:
  Callsite(v6)

blk3:
Inputs: v7: core::NonZero::<core::felt>
Statements:
  (v8: core::felt) <- 7u
Drops: v7
End:
  Callsite(v8)

blk4:
Inputs:
Statements:
  (v13: core::felt) <- 3u
  (v14: core::felt) <- 0u
  (v15: core::felt) <- core::felt_add(v0, v14)
Drops: v13, v14
End:
  Callsite(v15)

blk5 (root):
Inputs: v0: core::felt
Statements:
  () <- blk0()
  (v2: ()) <- struct_construct()
  () <- blk1()
  (v3: core::felt) <- 1u
  (v4: core::felt) <- 1u
  (v5: core::felt) <- core::felt_sub(v3, v4)
  (v9: core::felt) <- match core::felt_jump_nz(v5) {
    () => blk2,
    (v7) => blk3,
  }
  (v10: core::felt) <- 3u
  (v11: core::felt) <- test::foo(v10)
  (v12: core::felt) <- 5u
  (v16: core::felt) <- blk4()
  (v17: core::felt) <- core::felt_mul(v12, v16)
  (v18: core::felt) <- core::felt_add(v11, v17)
Drops: v0, v2, v3, v4, v5, v9, v10, v11, v12, v16, v17
End:
  Callsite(v18)

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

//! > Test match enum.

//! > test_function_name
test_function_lowering

//! > function
fn foo(x: MyEnum) -> felt {
  match x {
    MyEnum::A(inner) => {return 5;},
    MyEnum::B(inner) => {inner},
    MyEnum::C(inner) => {7}
  }
}

//! > function_name
foo

//! > module_code
enum MyEnum {
  A: (),
  B: felt,
  C: Box::<((), felt)>,
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_format
blk0:
Inputs:
Statements:
  (v2: core::felt) <- 5u
Drops: v1, v0
End:
  Return(v2)

blk1:
Inputs:
Statements:
Drops:
End:
  Callsite(v3)

blk2:
Inputs:
Statements:
  (v6: core::felt) <- 7u
Drops:
End:
  Callsite(v6)

blk3:
Inputs: v1: ()
Statements:
  () <- blk0()
Drops:
End:
  Unreachable

blk4:
Inputs: v3: core::felt
Statements:
  (v4: core::felt) <- blk1()
Drops: v3
End:
  Callsite(v4)

blk5:
Inputs: v5: core::box::Box::<((), core::felt)>
Statements:
  (v7: core::felt) <- blk2()
Drops: v5
End:
  Callsite(v7)

blk6 (root):
Inputs: v0: test::MyEnum
Statements:
  (v8: core::felt) <- match_enum(v0) {
    MyEnum::A => blk3,
    MyEnum::B => blk4,
    MyEnum::C => blk5,
  }
Drops:
End:
  Callsite(v8)

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

//! > Test literal generic argument.

//! > test_function_name
test_function_lowering

//! > function
fn foo(a : Array::<felt, 5>) -> felt {
  felt_const::<17>()
}

//! > function_name
foo

//! > module_code
extern type Array<T, N>;

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_format
blk0 (root):
Inputs: v0: test::Array::<core::felt, 5>
Statements:
  (v1: core::felt) <- core::felt_const<Literal(LiteralLongId { value: 17 }),>()
Drops: v0
End:
  Callsite(v1)
