diff --git a/crates/lang/codegen/src/generator/dispatch.rs b/crates/lang/codegen/src/generator/dispatch.rs index acfcc174ea..fee922033e 100644 --- a/crates/lang/codegen/src/generator/dispatch.rs +++ b/crates/lang/codegen/src/generator/dispatch.rs @@ -154,48 +154,37 @@ impl Dispatch<'_> { ) -> TokenStream2 { let span = self.contract.module().storage().span(); let storage_ident = self.contract.module().storage().ident(); - let inherent_ids = self + let message_ids = self .contract .module() .impls() - .filter(|item_impl| item_impl.trait_path().is_none()) - .flat_map(|item_impl| item_impl.iter_messages()) - .map(|message| { - let span = message.span(); - message_spans.push(span); - let id = message - .composed_selector() - .into_be_u32() - .hex_padded_suffixed(); - quote_spanned!(span=> #id) + .flat_map(|item_impl| { + iter::repeat(item_impl.trait_path()).zip(item_impl.iter_messages()) }) - .collect::>(); - let trait_ids = self - .contract - .module() - .impls() - .filter_map(|item_impl| { - item_impl - .trait_path() - .map(|trait_path| { - iter::repeat(trait_path).zip(item_impl.iter_messages()) - }) - }) - .flatten() .map(|(trait_path, message)| { - let local_id = message.local_id().hex_padded_suffixed(); let span = message.span(); message_spans.push(span); - quote_spanned!(span=> - { - ::core::primitive::u32::from_be_bytes( - <<::ink_lang::reflect::TraitDefinitionRegistry<<#storage_ident as ::ink_lang::reflect::ContractEnv>::Env> - as #trait_path>::__ink_TraitInfo - as ::ink_lang::reflect::TraitMessageInfo<#local_id>>::SELECTOR - ) - } - ) - }); + + if let Some(trait_path) = trait_path { + let local_id = message.local_id().hex_padded_suffixed(); + quote_spanned!(span=> + { + ::core::primitive::u32::from_be_bytes( + <<::ink_lang::reflect::TraitDefinitionRegistry<<#storage_ident as ::ink_lang::reflect::ContractEnv>::Env> + as #trait_path>::__ink_TraitInfo + as ::ink_lang::reflect::TraitMessageInfo<#local_id>>::SELECTOR + ) + } + ) + } else { + let id = message + .composed_selector() + .into_be_u32() + .hex_padded_suffixed(); + quote_spanned!(span=> #id) + } + }) + .collect::>(); quote_spanned!(span=> impl ::ink_lang::reflect::ContractDispatchableMessages<{ <#storage_ident as ::ink_lang::reflect::ContractAmountDispatchables>::MESSAGES @@ -204,8 +193,7 @@ impl Dispatch<'_> { ::core::primitive::u32; <#storage_ident as ::ink_lang::reflect::ContractAmountDispatchables>::MESSAGES ] = [ - #( #inherent_ids , )* - #( #trait_ids ),* + #( #message_ids , )* ]; } ) diff --git a/crates/lang/tests/ui/contract/pass/message-selector.rs b/crates/lang/tests/ui/contract/pass/message-selector.rs index 303c699076..9f883d6f6d 100644 --- a/crates/lang/tests/ui/contract/pass/message-selector.rs +++ b/crates/lang/tests/ui/contract/pass/message-selector.rs @@ -6,20 +6,45 @@ mod contract { #[ink(storage)] pub struct Contract {} + #[ink_lang::trait_definition] + pub trait Messages { + #[ink(message)] + fn message_0(&self); + + #[ink(message, selector = 1)] + fn message_1(&self); + } + + impl Messages for Contract { + #[ink(message)] + fn message_0(&self) {} + + #[ink(message, selector = 1)] + fn message_1(&self) {} + } + impl Contract { #[ink(constructor)] pub fn constructor() -> Self { Self {} } - #[ink(message)] - pub fn message_0(&self) {} - - #[ink(message, selector = 1)] - pub fn message_1(&self) {} - #[ink(message, selector = 0xC0DE_CAFE)] pub fn message_2(&self) {} + + #[ink(message, selector = _)] + pub fn message_3(&self) {} + } + + #[ink_lang::trait_definition] + pub trait Messages2 { + #[ink(message, selector = 0x12345678)] + fn message_4(&self); + } + + impl Messages2 for Contract { + #[ink(message, selector = 0x12345678)] + fn message_4(&self) {} } } @@ -34,7 +59,7 @@ fn main() { >>::IDS[0] }, >>::SELECTOR, - [0x5A, 0x6A, 0xC1, 0x5D], + [0xFB, 0xAB, 0x03, 0xCE], ); assert_eq!( >::SELECTOR, 0xC0DE_CAFE_u32.to_be_bytes(), ); + assert_eq!( + ::MESSAGES + }, + >>::IDS[3] + }, + >>::SELECTOR, + [0xB6, 0xC3, 0x27, 0x49], + ); + assert_eq!( + ::MESSAGES + }, + >>::IDS[4] + }, + >>::SELECTOR, + 0x12345678_u32.to_be_bytes(), + ); }