//! > Test expansion of panic_with.

//! > test_runner_name
test_expand_plugin(expect_diagnostics: false)

//! > cairo_code
#[feature("deprecated-panic-with")]
#[panic_with('1', foo_improved)]
#[allow(extern_outside_corelib)]
extern fn foo(a: felt252, ref b: other) -> Option<()> implicits(RangeCheck, GasBuiltin) nopanic;

#[feature("deprecated-panic-with")]
#[panic_with('2', bar_changed)]
#[allow(extern_outside_corelib)]
extern fn bar() -> Result<felt252, Err> nopanic;

#[feature("deprecated-panic-with")]
#[panic_with('3', non_extern_stuff)]
fn non_extern(_a: some_type) -> Option<(felt252, other)> nopanic {
    (4, 56)
}

#[feature("deprecated-panic-with")]
#[panic_with('4', generic_panic)]
#[allow(extern_outside_corelib)]
extern fn generic<T>(t: T, v: felt252) -> Result<T, Err> nopanic;

#[feature("deprecated-panic-with")]
#[panic_with('5', wrapped_possibly_panic)]
fn possibly_panic() -> Result<felt252, Err> {
    Result::<felt252, Err>::Ok(1)
}

//! > expanded_cairo_code
#[feature("deprecated-panic-with")]
#[panic_with('1', foo_improved)]
#[allow(extern_outside_corelib)]
extern fn foo(a: felt252, ref b: other) -> Option<()> implicits(RangeCheck, GasBuiltin) nopanic;

#[feature("deprecated-panic-with")]
#[panic_with('2', bar_changed)]
#[allow(extern_outside_corelib)]
extern fn bar() -> Result<felt252, Err> nopanic;

#[feature("deprecated-panic-with")]
#[panic_with('3', non_extern_stuff)]
fn non_extern(_a: some_type) -> Option<(felt252, other)> nopanic {
    (4, 56)
}

#[feature("deprecated-panic-with")]
#[panic_with('4', generic_panic)]
#[allow(extern_outside_corelib)]
extern fn generic<T>(t: T, v: felt252) -> Result<T, Err> nopanic;

#[feature("deprecated-panic-with")]
#[panic_with('5', wrapped_possibly_panic)]
fn possibly_panic() -> Result<felt252, Err> {
    Result::<felt252, Err>::Ok(1)
}
fn foo_improved(a: felt252, ref b: other) -> () {
    match foo(a, ref b) {
        Option::Some(v) => v,
        Option::None(_) => core::panic_with_const_felt252::<'1'>(),
    }
}
fn bar_changed() -> felt252 {
    match bar() {
        Result::Ok(v) => v,
        Result::Err(_) => core::panic_with_const_felt252::<'2'>(),
    }
}
fn non_extern_stuff(_a: some_type) -> (felt252, other) {
    match non_extern(_a) {
        Option::Some(v) => v,
        Option::None(_) => core::panic_with_const_felt252::<'3'>(),
    }
}
fn generic_panic<T>(t: T, v: felt252) -> T {
    match generic(t, v) {
        Result::Ok(v) => v,
        Result::Err(_) => core::panic_with_const_felt252::<'4'>(),
    }
}
fn wrapped_possibly_panic() -> felt252 {
    match possibly_panic() {
        Result::Ok(v) => v,
        Result::Err(_) => core::panic_with_const_felt252::<'5'>(),
    }
}

//! > expected_diagnostics

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

//! > Test diagnostics of panic with.

//! > test_runner_name
test_expand_plugin(expect_diagnostics: true)

//! > cairo_code
#[panic_with(123, foo_bad_err_code)]
#[allow(extern_outside_corelib)]
extern fn foo(a: felt252, b: other) -> Option<()> implicits(RangeCheck, GasBuiltin) nopanic;

#[panic_with(missing_args)]
#[allow(extern_outside_corelib)]
extern fn non_extern(_a: some_type) -> Option<(felt252, other)> nopanic;

#[panic_with(missing_args)]
#[allow(extern_outside_corelib)]
extern fn bad_ret_type(_a: some_type) -> felt252 nopanic;

#[panic_with('2', bar_changed)]
#[panic_with('3', bar_changed)]
#[allow(extern_outside_corelib)]
extern fn bar() -> Result<felt252, Err> nopanic;

//! > expanded_cairo_code
#[panic_with(123, foo_bad_err_code)]
#[allow(extern_outside_corelib)]
extern fn foo(a: felt252, b: other) -> Option<()> implicits(RangeCheck, GasBuiltin) nopanic;

#[panic_with(missing_args)]
#[allow(extern_outside_corelib)]
extern fn non_extern(_a: some_type) -> Option<(felt252, other)> nopanic;

#[panic_with(missing_args)]
#[allow(extern_outside_corelib)]
extern fn bad_ret_type(_a: some_type) -> felt252 nopanic;

#[panic_with('2', bar_changed)]
#[panic_with('3', bar_changed)]
#[allow(extern_outside_corelib)]
extern fn bar() -> Result<felt252, Err> nopanic;

//! > expected_diagnostics
error: Usage of deprecated macro `panic_with` with no `#[feature("deprecated-panic-with")]` attribute. Use simple calculations instead, as these are supported in const context.
 --> test_src/lib.cairo:1:1
#[panic_with(123, foo_bad_err_code)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


error: Failed to extract panic data attribute
 --> test_src/lib.cairo:1:1
#[panic_with(123, foo_bad_err_code)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


error: Usage of deprecated macro `panic_with` with no `#[feature("deprecated-panic-with")]` attribute. Use simple calculations instead, as these are supported in const context.
 --> test_src/lib.cairo:5:1
#[panic_with(missing_args)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^


error: Failed to extract panic data attribute
 --> test_src/lib.cairo:5:1
#[panic_with(missing_args)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^


error: Usage of deprecated macro `panic_with` with no `#[feature("deprecated-panic-with")]` attribute. Use simple calculations instead, as these are supported in const context.
 --> test_src/lib.cairo:9:1
#[panic_with(missing_args)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^


error: Currently only wrapping functions returning an Option<T> or Result<T, E>
 --> test_src/lib.cairo:11:39
extern fn bad_ret_type(_a: some_type) -> felt252 nopanic;
                                      ^^^^^^^^^^


error: Usage of deprecated macro `panic_with` with no `#[feature("deprecated-panic-with")]` attribute. Use simple calculations instead, as these are supported in const context.
 --> test_src/lib.cairo:13:1
#[panic_with('2', bar_changed)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


error: `#[panic_with]` cannot be applied multiple times to the same item.
 --> test_src/lib.cairo:14:1
#[panic_with('3', bar_changed)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
