//! > Test `embeddable_as` attribute with no arguments.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
error: Plugin diagnostic: `embeddable_as` attribute must have a single unnamed argument for the generated impl name, e.g.: #[embeddable_as(MyImpl)].
 --> lib.cairo:8:5
    #[embeddable_as]
    ^^^^^^^^^^^^^^^^

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

//! > Test `embeddable_as` attribute with too many arguments.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(X, Y)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(X, Y)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
error: Plugin diagnostic: `embeddable_as` attribute must have a single unnamed argument for the generated impl name, e.g.: #[embeddable_as(MyImpl)].
 --> lib.cairo:8:5
    #[embeddable_as(X, Y)]
    ^^^^^^^^^^^^^^^^^^^^^^

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

//! > Test `embeddable_as` attribute with named argument.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(name: MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(name: MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
error: Plugin diagnostic: `embeddable_as` attribute must have a single unnamed argument for the generated impl name, e.g.: #[embeddable_as(MyImpl)].
 --> lib.cairo:8:5
    #[embeddable_as(name: MyImpl)]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

//! > Test `embeddable_as` with no generic parameters.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl of MyTrait<ComponentState<usize>> {
        fn do_nothing() {}
    }
}
trait MyTrait<T> {
    fn do_nothing();
}

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl of MyTrait<ComponentState<usize>> {
        fn do_nothing() {}
    }
}
trait MyTrait<T> {
    fn do_nothing();
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
error: Plugin diagnostic: The first generic parameter of an impl with #[embeddable_as] should be `TContractState`.
 --> lib.cairo:9:10
    impl MyInnerImpl of MyTrait<ComponentState<usize>> {
         ^^^^^^^^^^^

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

//! > Test `embeddable_as` with empty generic parameters list.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<> of MyTrait<ComponentState<usize>> {
        fn do_nothing() {}
    }
}
trait MyTrait<T> {
    fn do_nothing();
}

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<> of MyTrait<ComponentState<usize>> {
        fn do_nothing() {}
    }
}
trait MyTrait<T> {
    fn do_nothing();
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
error: Plugin diagnostic: The first generic parameter of an impl with #[embeddable_as] should be `TContractState`.
 --> lib.cairo:9:21
    impl MyInnerImpl<> of MyTrait<ComponentState<usize>> {
                    ^^

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

//! > Test `embeddable_as` with wrong first generic parameter.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        impl X: HasComponent<TContractState>, TContractState,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing() {}
    }
}
trait MyTrait<T> {
    fn do_nothing();
}

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        impl X: HasComponent<TContractState>, TContractState,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing() {}
    }
}
trait MyTrait<T> {
    fn do_nothing();
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
error: Plugin diagnostic: The first generic parameter of an impl with #[embeddable_as] should be `TContractState`.
 --> lib.cairo:9:21-11:5
      impl MyInnerImpl<
 _____________________^
|         impl X: HasComponent<TContractState>, TContractState,
|     > of MyTrait<ComponentState<TContractState>> {
|_____^

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

//! > Test `embeddable_as` with no generic parameter that is an impl of HasComponent<TContractState>.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<TContractState> of MyTrait<ComponentState<TContractState>> {
        fn do_nothing() {}
    }
}
trait MyTrait<T> {
    fn do_nothing();
}

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<TContractState> of MyTrait<ComponentState<TContractState>> {
        fn do_nothing() {}
    }
}
trait MyTrait<T> {
    fn do_nothing();
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
error: Plugin diagnostic: An impl with #[embeddable_as] should have a generic parameter which is an impl of `HasComponent<TContractState>`.
 --> lib.cairo:9:21
    impl MyInnerImpl<TContractState> of MyTrait<ComponentState<TContractState>> {
                    ^^^^^^^^^^^^^^^^

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

//! > Test `embeddable_as` impl with empty body.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>>;
}
trait MyTrait<T>;

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>>;
}
trait MyTrait<T>;

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
error: Plugin diagnostic: `embeddable_as` attribute is not supported for empty impls.
 --> lib.cairo:11:49
    > of MyTrait<ComponentState<TContractState>>;
                                                ^

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

//! > Test `embeddable_as` with function with no/wrong `self` parameter.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn no_self() {}
        fn self_of_wrong_type(self: ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn no_self();
    fn self_of_wrong_type(self: T);
}

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn no_self() {}
        fn self_of_wrong_type(self: ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn no_self();
    fn self_of_wrong_type(self: T);
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}

#[starknet::embeddable]
pub impl MyImpl<
            TContractState, impl X: HasComponent<TContractState>,
impl TContractStateDrop: Drop<TContractState>
> of MyTrait<TContractState> {
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;


lib.cairo:8:5
    #[embeddable_as(MyImpl)]
    ^^^^^^^^^^^^^^^^^^^^^^^^
embeddable:

pub trait UnsafeNewContractStateTraitForMyImpl<
    TContractState
> {
    fn unsafe_new_contract_state() -> TContractState;
}



pub mod __external_MyImpl {
}

pub mod __l1_handler_MyImpl {
}

pub mod __constructor_MyImpl {
}

//! > expected_diagnostics
error: Plugin diagnostic: A function in an #[embeddable_as] impl in a component must have a first `self` parameter.
 --> lib.cairo:12:20
        fn no_self() {}
                   ^

error: Plugin diagnostic: The first parameter of a function in an #[embeddable_as] impl in a component must be either `self: @ComponentState<TContractState>` (for view functions) or `ref self: ComponentState<TContractState>` (for external functions).
 --> lib.cairo:13:31
        fn self_of_wrong_type(self: ComponentState<TContractState>) {}
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: Plugin diagnostic: Impls with the embeddable attribute must implement a starknet interface trait.
 --> lib.cairo:8:5
    #[embeddable_as(MyImpl)]
    ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0004]: Not all trait items are implemented. Missing: 'no_self', 'self_of_wrong_type'.
 --> lib.cairo:8:21
    #[embeddable_as(MyImpl)]
                    ^^^^^^

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

//! > Test `embeddable_as` with Destruct<TContractState>.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>, +Destruct<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

//! > expected_diagnostics
error: Plugin diagnostic: `embeddable_as` impls can't have impl generic parameters of `Destruct<TContractState>` or `PanicDestruct<TContractState>`.
 --> lib.cairo:10:63
        TContractState, impl X: HasComponent<TContractState>, +Destruct<TContractState>,
                                                              ^^^^^^^^^^^^^^^^^^^^^^^^^

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>, +Destruct<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;

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

//! > Test `embeddable_as` with PanicDestruct<TContractState>.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>, +PanicDestruct<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

//! > expected_diagnostics
error: Plugin diagnostic: `embeddable_as` impls can't have impl generic parameters of `Destruct<TContractState>` or `PanicDestruct<TContractState>`.
 --> lib.cairo:10:63
        TContractState, impl X: HasComponent<TContractState>, +PanicDestruct<TContractState>,
                                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//! > generated_cairo_code
lib.cairo:

#[starknet::component]
mod component {
    use super::MyTrait;

    #[storage]
    struct Storage {}

    #[embeddable_as(MyImpl)]
    impl MyInnerImpl<
        TContractState, impl X: HasComponent<TContractState>, +PanicDestruct<TContractState>,
    > of MyTrait<ComponentState<TContractState>> {
        fn do_nothing(self: @ComponentState<TContractState>) {}
    }
}
trait MyTrait<T> {
    fn do_nothing(self: @T);
}

lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
component:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBase {
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        StorageStorageBase {
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
pub struct StorageStorageBaseMut {
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        StorageStorageBaseMut {
        }
    }
}

pub struct ComponentState<TContractState> {
}

impl ComponentStateDrop<TContractState> of Drop<ComponentState<TContractState>> {}

impl ComponentStateDeref<TContractState> of core::ops::Deref<@ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn deref(self: @ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ComponentStateDerefMut<TContractState> of core::ops::DerefMut<ComponentState<TContractState>> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ComponentState<TContractState>) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_component_state<TContractState>() -> ComponentState<TContractState> {
    ComponentState::<TContractState> {
    }
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn component_state_for_testing<TContractState>() -> ComponentState<TContractState> {
    unsafe_new_component_state::<TContractState>()
}


// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
pub trait HasComponent<TContractState> {
    fn get_component(self: @TContractState) -> @ComponentState<TContractState>;
    fn get_component_mut(ref self: TContractState) -> ComponentState<TContractState>;
    fn get_contract(self: @ComponentState<TContractState>) -> @TContractState;
    fn get_contract_mut(ref self: ComponentState<TContractState>) -> TContractState;
    fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(ref self: ComponentState<TContractState>, event: S);
}



lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
impls:

impl EventDrop<> of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::component]
^^^^^^^^^^^^^^^^^^^^^^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        Option::None
    }
}



lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseDrop<> of core::traits::Drop::<StorageStorageBase>;
#[doc(hidden)]
impl StorageStorageBaseCopy<> of core::traits::Copy::<StorageStorageBase>;


lib.cairo:5:5
    #[storage]
    ^^^^^^^^^^
impls:

#[doc(hidden)]
impl StorageStorageBaseMutDrop<> of core::traits::Drop::<StorageStorageBaseMut>;
#[doc(hidden)]
impl StorageStorageBaseMutCopy<> of core::traits::Copy::<StorageStorageBaseMut>;
