ink
ink copied to clipboard
Importing another contract into the scope prohibits emitting event
Description
Putting another contract struct into context creates a situation where there isn't enough (type) information to use emit_event
:
error[E0284]: type annotations needed
--> lib.rs:36:24
|
36 | self.env().emit_event(ContractACalled { caller });
| ^^^^^^^^^^ cannot infer type for type parameter `C` declared on the trait `EmitEvent`
|
= note: cannot satisfy `<_ as ink_lang::reflect::ContractEventBase>::Type == _`
error[E0283]: type annotations needed
--> lib.rs:36:24
|
36 | self.env().emit_event(ContractACalled { caller });
| ^^^^^^^^^^ cannot infer type for type parameter `C` declared on the trait `EmitEvent`
|
note: multiple `impl`s satisfying `ink_lang::EnvAccess<'_, ink_env::DefaultEnvironment>: ink_lang::codegen::EmitEvent<_>` found
--> lib.rs:5:1
|
5 | #[ink::contract]
| ^^^^^^^^^^^^^^^^
= note: and another `impl` found in the `contract_b` crate: `impl<'a> ink_lang::codegen::EmitEvent<contract_b::ContractB> for ink_lang::EnvAccess<'a, <contract_b::ContractB as ink_lang::reflect::ContractEnv>::Env>;`
= note: this error originates in the attribute macro `ink::contract` (in Nightly builds, run with -Z macro-backtrace for more info)
Casting <ContractA as ContractEventBase>::Type
could potentially be used to hint the compiler but all the events are behind a (macro-generated) public enum:
pub enum __ink_EventBase {
ContractACalled(ContractACalled),
}
and Rust won't take __
as an identifier (not a valid syntax).
self.env() is ink_lang::codegen::EmitEvent<ContractA>
so some solution is to wrap event emitting in a function such as:
fn emit_event<EE: EmitEvent<Self>>(e: EE) {
e.emit_event(ContractACalled {});
}
but that is not the most ergonomic.
Additional context Here's a reproducible example: https://github.com/fbielejec/emit_event
Duplicate of https://github.com/paritytech/ink/issues/1000