//! > Call with coupon

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo(x: bar::Coupon) {
    bar(__coupon__: x);
}

//! > function_name
foo

//! > module_code
fn bar() nopanic {}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::bar::Coupon
blk0 (root):
Statements:
  () <- test::bar(__coupon__: v0)
End:
  Return()

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

//! > Call method with impl function coupon

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo(x: MyImpl::bar::Coupon) {
    5.bar(__coupon__: x);
}

//! > function_name
foo

//! > module_code
trait MyTrait<T> {
    fn bar(self: T);
}
impl MyImpl of MyTrait<felt252> {
    fn bar(self: felt252) {}
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::MyImpl::bar::Coupon
blk0 (root):
Statements:
  (v1: core::felt252) <- 5
  () <- test::MyImpl::bar(v1, __coupon__: v0)
End:
  Return()

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

//! > Call method with concrete trait function coupon

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo(x: MyTrait::<felt252>::bar::Coupon) {
    5.bar(__coupon__: x);
}

//! > function_name
foo

//! > module_code
trait MyTrait<T> {
    fn bar(self: T);
}
impl MyImpl of MyTrait<felt252> {
    fn bar(self: felt252) {}
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::MyImpl::bar::Coupon
blk0 (root):
Statements:
  (v1: core::felt252) <- 5
  () <- test::MyImpl::bar(v1, __coupon__: v0)
End:
  Return()

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

//! > Coupon moved

//! > test_runner_name
test_function_lowering(expect_diagnostics: true)

//! > function_code
fn foo(x: bar::Coupon) -> bar::Coupon {
    bar(__coupon__: x);
    x // Variable was previously moved.
}

//! > function_name
foo

//! > module_code
fn bar() nopanic {}

//! > semantic_diagnostics

//! > lowering_diagnostics
error[E3001]: Variable was previously moved.
 --> lib.cairo:4:5
    x // Variable was previously moved.
    ^
note: variable was previously used here:
  --> lib.cairo:3:21
    bar(__coupon__: x);
                    ^
note: Trait has no implementation in context: core::traits::Copy::<test::bar::Coupon>.

//! > lowering_flat
<Failed lowering function - run with RUST_LOG=warn (or less) to see diagnostics>

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

//! > Calling panicable function with coupon

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo(x: bar::Coupon) {
    bar(__coupon__: x);
}

//! > function_name
foo

//! > module_code
fn bar() {
    panic(array![])
}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::bar::Coupon
blk0 (root):
Statements:
  (v1: core::panics::PanicResult::<((),)>) <- test::bar(__coupon__: v0)
End:
  Return(v1)

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

//! > Inlining disabled when coupon is used.

//! > test_runner_name
test_function_lowering(expect_diagnostics: false)

//! > function_code
fn foo(x: bar::Coupon) {
    bar(__coupon__: x);
}

//! > function_name
foo

//! > module_code
#[inline(always)]
fn bar() {}

//! > semantic_diagnostics

//! > lowering_diagnostics

//! > lowering_flat
Parameters: v0: test::bar::Coupon
blk0 (root):
Statements:
  () <- test::bar(__coupon__: v0)
End:
  Return()
