From 5dc8792d8f5ac3f9c9580986819e368e2191014e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 3 Jul 2019 20:05:48 +0200 Subject: [PATCH] Implement `From` module `Call` for outer `Call` (#3006) * Implement `From` module `Call` for outer `Call` * Fixes compilation and add test --- substrate/srml/democracy/src/lib.rs | 2 +- substrate/srml/support/src/dispatch.rs | 43 +++++++++++++++++--------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/substrate/srml/democracy/src/lib.rs b/substrate/srml/democracy/src/lib.rs index 71375055ab..411c859802 100644 --- a/substrate/srml/democracy/src/lib.rs +++ b/substrate/srml/democracy/src/lib.rs @@ -173,7 +173,7 @@ pub const DEFAULT_EMERGENCY_VOTING_PERIOD: u32 = 0; pub const DEFAULT_COOLOFF_PERIOD: u32 = 0; pub trait Trait: system::Trait + Sized { - type Proposal: Parameter + Dispatchable + IsSubType>; + type Proposal: Parameter + Dispatchable + IsSubType, Self>; type Event: From> + Into<::Event>; /// Currency type for this module. diff --git a/substrate/srml/support/src/dispatch.rs b/substrate/srml/support/src/dispatch.rs index 264942a278..0795cfeec1 100644 --- a/substrate/srml/support/src/dispatch.rs +++ b/substrate/srml/support/src/dispatch.rs @@ -47,13 +47,13 @@ pub trait Dispatchable { /// Serializable version of Dispatchable. /// This value can be used as a "function" in an extrinsic. -pub trait Callable { +pub trait Callable { type Call: Dispatchable + Codec + Clone + PartialEq + Eq; } // dirty hack to work around serde_derive issue // https://github.com/rust-lang/rust/issues/51331 -pub type CallableCallFor = ::Call; +pub type CallableCallFor = >::Call; #[cfg(feature = "std")] pub trait Parameter: Codec + Clone + Eq + fmt::Debug {} @@ -1175,7 +1175,7 @@ macro_rules! decl_module { } } } - impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $crate::dispatch::Callable + impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $crate::dispatch::Callable<$trait_instance> for $mod_type<$trait_instance $(, $instance)?> { type Call = $call_type<$trait_instance $(, $instance)?>; @@ -1201,8 +1201,8 @@ macro_rules! decl_module { } } -pub trait IsSubType { - fn is_aux_sub_type(&self) -> Option<&::Call>; +pub trait IsSubType, R> { + fn is_aux_sub_type(&self) -> Option<&CallableCallFor>; } /// Implement a meta-dispatch module to dispatch to other dispatchers. @@ -1221,7 +1221,7 @@ macro_rules! impl_outer_dispatch { #[cfg_attr(feature = "std", derive(Debug))] pub enum $call_type { $( - $camelcase ( $crate::dispatch::CallableCallFor<$camelcase> ) + $camelcase ( $crate::dispatch::CallableCallFor<$camelcase, $runtime> ) ,)* } impl $crate::dispatch::Weighable for $call_type { @@ -1241,15 +1241,20 @@ macro_rules! impl_outer_dispatch { } } $( - impl $crate::dispatch::IsSubType<$camelcase> for $call_type { - fn is_aux_sub_type(&self) -> Option<&<$camelcase as $crate::dispatch::Callable>::Call> { - if let $call_type::$camelcase ( ref r ) = *self { - Some(r) - } else { - None + impl $crate::dispatch::IsSubType<$camelcase, $runtime> for $call_type { + fn is_aux_sub_type(&self) -> Option<&$crate::dispatch::CallableCallFor<$camelcase, $runtime>> { + match *self { + $call_type::$camelcase(ref r) => Some(r), + _ => None, } } } + + impl From<$crate::dispatch::CallableCallFor<$camelcase, $runtime>> for $call_type { + fn from(call: $crate::dispatch::CallableCallFor<$camelcase, $runtime>) -> Self { + $call_type::$camelcase(call) + } + } )* } } @@ -1518,9 +1523,10 @@ mod tests { use super::*; use crate::runtime_primitives::traits::{OnInitialize, OnFinalize}; - pub trait Trait { + pub trait Trait: Sized { type Origin; type BlockNumber: Into; + type Call: From>; } pub mod system { @@ -1619,11 +1625,20 @@ mod tests { }, ]; - struct TraitImpl {} + pub struct TraitImpl {} impl Trait for TraitImpl { type Origin = u32; type BlockNumber = u32; + type Call = OuterCall; + } + + type Test = Module; + + impl_outer_dispatch! { + pub enum OuterCall for TraitImpl where origin: u32 { + self::Test, + } } #[test]