diff --git a/Cargo.lock b/Cargo.lock index 59028fbc61bd679f4827e6132cc068b0e3d1e532..4954c736a6a0d17afee18ec07921ecc19ce9380e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1379,6 +1379,16 @@ dependencies = [ "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "indexmap" version = "1.0.2" @@ -3018,7 +3028,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3121,7 +3131,7 @@ name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3454,7 +3464,7 @@ name = "rustversion" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3822,6 +3832,7 @@ dependencies = [ name = "sr-primitives" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3934,6 +3945,7 @@ dependencies = [ name = "srml-authorship" version = "0.1.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4092,6 +4104,7 @@ dependencies = [ name = "srml-finality-tracker" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4228,6 +4241,7 @@ dependencies = [ name = "srml-session" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4286,6 +4300,7 @@ name = "srml-support" version = "2.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4351,6 +4366,7 @@ name = "srml-system" version = "2.0.0" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4366,6 +4382,7 @@ dependencies = [ name = "srml-timestamp" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -5497,7 +5514,7 @@ name = "syn" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6591,6 +6608,7 @@ dependencies = [ "checksum impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78c441b3d2b5e24b407161e76d482b7bbd29b5da357707839ac40d95152f031f" "checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" "checksum impl-serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d26be4b97d738552ea423f76c4f681012ff06c3fa36fa968656b3679f60b4a1" +"checksum impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a9213bd15aa3f974ed007e12e520c435af21e0bb9b016c0874f05eec30034cf" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" @@ -6721,7 +6739,7 @@ dependencies = [ "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "982a35d1194084ba319d65c4a68d24ca28f5fdb5b8bc20899e4eef8641ea5178" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" +"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8" "checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" "checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" "checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index d3510e6baa8340a5ed89d09534de7cfa43b61746..19db46e8a2ebbe5a6160aed3efc032cb50de0f73 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -16,6 +16,7 @@ runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } log = { version = "0.4", optional = true } paste = { version = "0.1"} rand = { version = "0.7.0", optional = true } +impl-trait-for-tuples = "0.1" [dev-dependencies] serde_json = "1.0" diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index bbcb46be3d52882d0f1176715a7673f0abeb54c8..080b7bc948e0d1f5ba16755223ef8bd7ee44b05b 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -19,8 +19,10 @@ use rstd::prelude::*; use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}}; use runtime_io; -#[cfg(feature = "std")] use std::fmt::{Debug, Display}; -#[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; +#[cfg(feature = "std")] +use std::fmt::{Debug, Display}; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize, de::DeserializeOwned}; use primitives::{self, Hasher, Blake2Hasher}; use crate::codec::{Codec, Encode, Decode, HasCompact}; use crate::transaction_validity::{ @@ -38,6 +40,7 @@ use rstd::ops::{ RemAssign, Shl, Shr }; use crate::AppKey; +use impl_trait_for_tuples::impl_for_tuples; /// A lazy value. pub trait Lazy<T: ?Sized> { @@ -404,22 +407,20 @@ impl<T: /// The block finalization trait. Implementing this lets you express what should happen /// for your module when the block is ending. +#[impl_for_tuples(30)] pub trait OnFinalize<BlockNumber> { /// The block is being finalized. Implement to have something happen. fn on_finalize(_n: BlockNumber) {} } -impl<N> OnFinalize<N> for () {} - /// The block initialization trait. Implementing this lets you express what should happen /// for your module when the block is beginning (right before the first extrinsic is executed). +#[impl_for_tuples(30)] pub trait OnInitialize<BlockNumber> { /// The block is being initialized. Implement to have something happen. fn on_initialize(_n: BlockNumber) {} } -impl<N> OnInitialize<N> for () {} - /// Off-chain computation trait. /// /// Implementing this trait on a module allows you to perform long-running tasks @@ -428,6 +429,7 @@ impl<N> OnInitialize<N> for () {} /// /// NOTE: This function runs off-chain, so it can access the block state, /// but cannot preform any alterations. +#[impl_for_tuples(30)] pub trait OffchainWorker<BlockNumber> { /// This function is being called on every block. /// @@ -436,47 +438,6 @@ pub trait OffchainWorker<BlockNumber> { fn generate_extrinsics(_n: BlockNumber) {} } -impl<N> OffchainWorker<N> for () {} - -macro_rules! tuple_impl { - ($first:ident, $($rest:ident,)+) => { - tuple_impl!([$first] [$first] [$($rest)+]); - }; - ([$($direct:ident)+] [$($reverse:ident)+] []) => { - impl< - Number: Copy, - $($direct: OnFinalize<Number>),+ - > OnFinalize<Number> for ($($direct),+,) { - fn on_finalize(n: Number) { - $($reverse::on_finalize(n);)+ - } - } - impl< - Number: Copy, - $($direct: OnInitialize<Number>),+ - > OnInitialize<Number> for ($($direct),+,) { - fn on_initialize(n: Number) { - $($direct::on_initialize(n);)+ - } - } - impl< - Number: Copy, - $($direct: OffchainWorker<Number>),+ - > OffchainWorker<Number> for ($($direct),+,) { - fn generate_extrinsics(n: Number) { - $($direct::generate_extrinsics(n);)+ - } - } - }; - ([$($direct:ident)+] [$($reverse:ident)+] [$first:ident $($rest:ident)*]) => { - tuple_impl!([$($direct)+] [$($reverse)+] []); - tuple_impl!([$($direct)+ $first] [$first $($reverse)+] [$($rest)*]); - }; -} - -#[allow(non_snake_case)] -tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,); - /// Abstraction around hashing pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived // traits must be fulfilled by all type parameters. @@ -930,96 +891,62 @@ pub trait ModuleDispatchError { fn as_str(&self) -> &'static str; } -macro_rules! tuple_impl_indexed { - ($first:ident, $($rest:ident,)+ ; $first_index:tt, $($rest_index:tt,)+) => { - tuple_impl_indexed!([$first] [$($rest)+] ; [$first_index,] [$($rest_index,)+]); - }; - ([$($direct:ident)+] ; [$($index:tt,)+]) => { - impl< - AccountId, - Call, - $($direct: SignedExtension<AccountId=AccountId, Call=Call>),+ - > SignedExtension for ($($direct),+,) { - type AccountId = AccountId; - type Call = Call; - type AdditionalSigned = ( $( $direct::AdditionalSigned, )+ ); - type Pre = ($($direct::Pre,)+); - fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> { - Ok(( $( self.$index.additional_signed()?, )+ )) - } - fn validate( - &self, - who: &Self::AccountId, - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> TransactionValidity { - let aggregator = vec![ - $( <$direct as SignedExtension>::validate(&self.$index, who, call, info, len)? ),+ - ]; - Ok( - aggregator.into_iter().fold( - ValidTransaction::default(), - |acc, a| acc.combine_with(a), - ) - ) - } - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> Result<Self::Pre, $crate::ApplyError> { - Ok(($(self.$index.pre_dispatch(who, call, info, len)?,)+)) - } - fn validate_unsigned( - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> TransactionValidity { - let aggregator = vec![ $( $direct::validate_unsigned(call, info, len)? ),+ ]; - - Ok( - aggregator.into_iter().fold( - ValidTransaction::default(), - |acc, a| acc.combine_with(a), - ) - ) - } - fn pre_dispatch_unsigned( - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> Result<Self::Pre, $crate::ApplyError> { - Ok(($($direct::pre_dispatch_unsigned(call, info, len)?,)+)) - } - fn post_dispatch( - pre: Self::Pre, - info: DispatchInfo, - len: usize, - ) { - $($direct::post_dispatch(pre.$index, info, len);)+ - } - } +#[impl_for_tuples(1, 12)] +impl<AccountId, Call> SignedExtension for Tuple { + for_tuples!( where #( Tuple: SignedExtension<AccountId=AccountId, Call=Call> )* ); + type AccountId = AccountId; + type Call = Call; + for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); ); + for_tuples!( type Pre = ( #( Tuple::Pre ),* ); ); - }; - ([$($direct:ident)+] [] ; [$($index:tt,)+] []) => { - tuple_impl_indexed!([$($direct)+] ; [$($index,)+]); - }; - ( - [$($direct:ident)+] [$first:ident $($rest:ident)*] - ; - [$($index:tt,)+] [$first_index:tt, $($rest_index:tt,)*] - ) => { - tuple_impl_indexed!([$($direct)+] ; [$($index,)+]); - tuple_impl_indexed!([$($direct)+ $first] [$($rest)*] ; [$($index,)+ $first_index,] [$($rest_index,)*]); - }; -} + fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> { + Ok(for_tuples!( ( #( Tuple.additional_signed()? ),* ) )) + } + + fn validate( + &self, + who: &Self::AccountId, + call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> TransactionValidity { + let valid = ValidTransaction::default(); + for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info, len)?); )* ); + Ok(valid) + } + + fn pre_dispatch(self, who: &Self::AccountId, call: &Self::Call, info: DispatchInfo, len: usize) + -> Result<Self::Pre, crate::ApplyError> + { + Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info, len)? ),* ) )) + } + + fn validate_unsigned( + call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> TransactionValidity { + let valid = ValidTransaction::default(); + for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info, len)?); )* ); + Ok(valid) + } -// TODO: merge this into `tuple_impl` once codec supports `trait Codec` for longer tuple lengths. #3152 -#[allow(non_snake_case)] -tuple_impl_indexed!(A, B, C, D, E, F, G, H, I, J, ; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,); + fn pre_dispatch_unsigned( + call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> Result<Self::Pre, crate::ApplyError> { + Ok(for_tuples!( ( #( Tuple::pre_dispatch_unsigned(call, info, len)? ),* ) )) + } + + fn post_dispatch( + pre: Self::Pre, + info: DispatchInfo, + len: usize, + ) { + for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, len); )* ) + } +} /// Only for bare bone testing when you don't care about signed extensions at all. #[cfg(feature = "std")] diff --git a/srml/authorship/Cargo.toml b/srml/authorship/Cargo.toml index db3cb133f46842ce003aef2a12d057d4cc9329c3..7bb2af26324dc6ae5ffbc45dfe2497569438a526 100644 --- a/srml/authorship/Cargo.toml +++ b/srml/authorship/Cargo.toml @@ -14,6 +14,7 @@ sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +impl-trait-for-tuples = "0.1" [features] default = ["std"] diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index e7055dddb87cd4046a311cf5f58d76397168048f..f8a2ad1ed1390bfe7b2211bedef656b7839e2be8 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -22,7 +22,7 @@ use rstd::{result, prelude::*}; use rstd::collections::btree_set::BTreeSet; -use support::{decl_module, decl_storage, for_each_tuple, StorageValue}; +use support::{decl_module, decl_storage, StorageValue}; use support::traits::{FindAuthor, VerifySeal, Get}; use support::dispatch::Result as DispatchResult; use codec::{Encode, Decode}; @@ -112,6 +112,7 @@ pub trait Trait: system::Trait { /// An event handler for the authorship module. There is a dummy implementation /// for `()`, which does nothing. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait EventHandler<Author, BlockNumber> { /// Note that the given account ID is the author of the current block. fn note_author(author: Author); @@ -121,30 +122,6 @@ pub trait EventHandler<Author, BlockNumber> { fn note_uncle(author: Author, age: BlockNumber); } -macro_rules! impl_event_handler { - () => ( - impl<A, B> EventHandler<A, B> for () { - fn note_author(_author: A) { } - fn note_uncle(_author: A, _age: B) { } - } - ); - - ( $($t:ident)* ) => { - impl<Author: Clone, BlockNumber: Clone, $($t: EventHandler<Author, BlockNumber>),*> - EventHandler<Author, BlockNumber> for ($($t,)*) - { - fn note_author(author: Author) { - $($t::note_author(author.clone());)* - } - fn note_uncle(author: Author, age: BlockNumber) { - $($t::note_uncle(author.clone(), age.clone());)* - } - } - } -} - -for_each_tuple!(impl_event_handler); - /// Additional filtering on uncles that pass preliminary ancestry checks. /// /// This should do work such as checking seals diff --git a/srml/finality-tracker/Cargo.toml b/srml/finality-tracker/Cargo.toml index 277c4039d22086be7ef1ae32b626af75e9a4f100..ba6c5b7c8fb3e5db732a6cdfe2fabede02407b4f 100644 --- a/srml/finality-tracker/Cargo.toml +++ b/srml/finality-tracker/Cargo.toml @@ -12,6 +12,7 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } srml-system = { path = "../system", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index 340af3e4d3e4c2fa1e9e9df60eafe6d28cb0cb86..1f90927f7d8e3795fcaf6b77c543e8b5a8c6f85a 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -26,7 +26,7 @@ use support::StorageValue; use sr_primitives::traits::{One, Zero, SaturatedConversion}; use rstd::{prelude::*, result, cmp, vec}; use codec::Decode; -use support::{decl_module, decl_storage, for_each_tuple}; +use support::{decl_module, decl_storage}; use support::traits::Get; use srml_system::{ensure_none, Trait as SystemTrait}; @@ -214,30 +214,13 @@ impl<T: Trait> Module<T> { } /// Called when finalization stalled at a given number. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnFinalizationStalled<N> { /// The parameter here is how many more blocks to wait before applying /// changes triggered by finality stalling. fn on_stalled(further_wait: N, median: N); } -macro_rules! impl_on_stalled { - () => ( - impl<N> OnFinalizationStalled<N> for () { - fn on_stalled(_: N, _: N) {} - } - ); - - ( $($t:ident)* ) => { - impl<NUM: Clone, $($t: OnFinalizationStalled<NUM>),*> OnFinalizationStalled<NUM> for ($($t,)*) { - fn on_stalled(further_wait: NUM, median: NUM) { - $($t::on_stalled(further_wait.clone(), median.clone());)* - } - } - } -} - -for_each_tuple!(impl_on_stalled); - impl<T: Trait> ProvideInherent for Module<T> { type Call = Call<T>; type Error = MakeFatalError<()>; diff --git a/srml/session/Cargo.toml b/srml/session/Cargo.toml index c2e0732ed7058f46e2fba2e46d261220350d1e5a..2e7f5eda805b0ea5c51dee63c5f02cba3604bb93 100644 --- a/srml/session/Cargo.toml +++ b/srml/session/Cargo.toml @@ -16,6 +16,7 @@ system = { package = "srml-system", path = "../system", default-features = false timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } substrate-trie = { path = "../../core/trie", default-features = false, optional = true } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index f7c9eee021045bd5ec2f5907ececa69964e238dd..63566fd8810e529824888d7017c7aea38e7d8b64 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -126,8 +126,8 @@ use sr_primitives::weights::SimpleDispatchInfo; use sr_primitives::traits::{Convert, Zero, Member, OpaqueKeys}; use sr_staking_primitives::SessionIndex; use support::{ - dispatch::Result, ConsensusEngineId, StorageValue, StorageDoubleMap, for_each_tuple, - decl_module, decl_event, decl_storage, + dispatch::Result, ConsensusEngineId, StorageValue, StorageDoubleMap, decl_module, decl_event, + decl_storage, }; use support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor}, Parameter}; use system::{self, ensure_signed}; @@ -251,62 +251,51 @@ pub trait OneSessionHandler<ValidatorId> { /// A validator got disabled. Act accordingly until a new session begins. fn on_disabled(_validator_index: usize); - } -macro_rules! impl_session_handlers { - () => ( - impl<AId> SessionHandler<AId> for () { - fn on_genesis_session<Ks: OpaqueKeys>(_: &[(AId, Ks)]) {} - fn on_new_session<Ks: OpaqueKeys>(_: bool, _: &[(AId, Ks)], _: &[(AId, Ks)]) {} - fn on_before_session_ending() {} - fn on_disabled(_: usize) {} - } - ); +#[impl_trait_for_tuples::impl_for_tuples(30)] +#[tuple_types_no_default_trait_bound] +impl<AId> SessionHandler<AId> for Tuple { + for_tuples!( where #( Tuple: OneSessionHandler<AId> )* ); - ( $($t:ident)* ) => { - impl<AId, $( $t: OneSessionHandler<AId> ),*> SessionHandler<AId> for ( $( $t , )* ) { - fn on_genesis_session<Ks: OpaqueKeys>(validators: &[(AId, Ks)]) { - $( - let our_keys: Box<dyn Iterator<Item=_>> = Box::new(validators.iter() - .map(|k| (&k.0, k.1.get::<$t::Key>(<$t::Key as AppKey>::ID) - .unwrap_or_default()))); + fn on_genesis_session<Ks: OpaqueKeys>(validators: &[(AId, Ks)]) { + for_tuples!( + #( + let our_keys: Box<dyn Iterator<Item=_>> = Box::new(validators.iter() + .map(|k| (&k.0, k.1.get::<Tuple::Key>(<Tuple::Key as AppKey>::ID) + .unwrap_or_default()))); - $t::on_genesis_session(our_keys); - )* - } - fn on_new_session<Ks: OpaqueKeys>( - changed: bool, - validators: &[(AId, Ks)], - queued_validators: &[(AId, Ks)], - ) { - $( - let our_keys: Box<dyn Iterator<Item=_>> = Box::new(validators.iter() - .map(|k| (&k.0, k.1.get::<$t::Key>(<$t::Key as AppKey>::ID) - .unwrap_or_default()))); - let queued_keys: Box<dyn Iterator<Item=_>> = Box::new(queued_validators.iter() - .map(|k| (&k.0, k.1.get::<$t::Key>(<$t::Key as AppKey>::ID) - .unwrap_or_default()))); - $t::on_new_session(changed, our_keys, queued_keys); - )* - } + Tuple::on_genesis_session(our_keys); + )* + ) + } - fn on_before_session_ending() { - $( - $t::on_before_session_ending(); - )* - } + fn on_new_session<Ks: OpaqueKeys>( + changed: bool, + validators: &[(AId, Ks)], + queued_validators: &[(AId, Ks)], + ) { + for_tuples!( + #( + let our_keys: Box<dyn Iterator<Item=_>> = Box::new(validators.iter() + .map(|k| (&k.0, k.1.get::<Tuple::Key>(<Tuple::Key as AppKey>::ID) + .unwrap_or_default()))); + let queued_keys: Box<dyn Iterator<Item=_>> = Box::new(queued_validators.iter() + .map(|k| (&k.0, k.1.get::<Tuple::Key>(<Tuple::Key as AppKey>::ID) + .unwrap_or_default()))); + Tuple::on_new_session(changed, our_keys, queued_keys); + )* + ) + } - fn on_disabled(i: usize) { - $( - $t::on_disabled(i); - )* - } - } + fn on_before_session_ending() { + for_tuples!( #( Tuple::on_before_session_ending(); )* ) } -} -for_each_tuple!(impl_session_handlers); + fn on_disabled(i: usize) { + for_tuples!( #( Tuple::on_disabled(i); )* ) + } +} /// Handler for selecting the genesis validator set. pub trait SelectInitialValidators<ValidatorId> { diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index f1cdb69a653fd1af36a5de06a0d8af02e89787b8..7a3e0d26e4cdbf0b0d77f358c6465d0cbcbc0c6b 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -17,6 +17,7 @@ srml-support-procedural = { package = "srml-support-procedural", path = "./proce paste = "0.1" once_cell = { version = "0.1.6", default-features = false, optional = true } bitmask = { version = "0.5", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] pretty_assertions = "0.6.1" diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index b815e00b9df23b2fdaa60635e6c76ce91e71fd26..13fb69990ef6132a3c56261b075317c6b3688225 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -266,21 +266,6 @@ pub enum Void {} #[doc(hidden)] pub use serde::{Serialize, Deserialize}; -/// Programatically create derivations for tuples of up to 19 elements. You provide a second macro -/// which is called once per tuple size, along with a number of identifiers, one for each element -/// of the tuple. -#[macro_export] -macro_rules! for_each_tuple { - ($m:ident) => { - for_each_tuple! { @IMPL $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, } - }; - (@IMPL $m:ident !!) => { $m! { } }; - (@IMPL $m:ident !! $h:ident, $($t:ident,)*) => { - $m! { $h $($t)* } - for_each_tuple! { @IMPL $m !! $($t,)* } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 4ce94bb341ac4f3376d9062b92f2a709b1e16aba..8eeb10c3747469e8e052e6a5f0e681fb6778cf68 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -24,8 +24,6 @@ use primitives::u32_trait::Value as U32; use crate::sr_primitives::traits::{MaybeSerializeDebug, SimpleArithmetic, Saturating}; use crate::sr_primitives::ConsensusEngineId; -use super::for_each_tuple; - /// Anything that can have a `::len()` method. pub trait Len { /// Return the length of data type. @@ -63,29 +61,12 @@ impl<V: PartialEq, T: Get<V>> Contains<V> for T { } /// The account with the given id was killed. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnFreeBalanceZero<AccountId> { /// The account was the given id was killed. fn on_free_balance_zero(who: &AccountId); } -macro_rules! impl_on_free_balance_zero { - () => ( - impl<AccountId> OnFreeBalanceZero<AccountId> for () { - fn on_free_balance_zero(_: &AccountId) {} - } - ); - - ( $($t:ident)* ) => { - impl<AccountId, $($t: OnFreeBalanceZero<AccountId>),*> OnFreeBalanceZero<AccountId> for ($($t,)*) { - fn on_free_balance_zero(who: &AccountId) { - $($t::on_free_balance_zero(who);)* - } - } - } -} - -for_each_tuple!(impl_on_free_balance_zero); - /// Trait for a hook to get called when some balance has been minted, causing dilution. pub trait OnDilution<Balance> { /// Some `portion` of the total balance just "grew" by `minted`. `portion` is the pre-growth diff --git a/srml/system/Cargo.toml b/srml/system/Cargo.toml index f6fd25c29fbcc37640dc92993e2f27d6818ee68d..fd8ae735a9371d958ac0dc5d0148b46084e5f439 100644 --- a/srml/system/Cargo.toml +++ b/srml/system/Cargo.toml @@ -14,6 +14,7 @@ runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = f sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-version = { path = "../../core/sr-version", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] criterion = "0.2" diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 2f1d0ab9e0e202ca1373e72fc810d86612e6f45b..02a70028060f3d5506a22b7ae59c76e51a39f512 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -112,7 +112,7 @@ use sr_primitives::{ use primitives::storage::well_known_keys; use support::{ storage, decl_module, decl_event, decl_storage, StorageDoubleMap, StorageValue, StorageMap, - Parameter, for_each_tuple, traits::{Contains, Get}, decl_error, + Parameter, traits::{Contains, Get}, decl_error, }; use safe_mix::TripletMix; use codec::{Encode, Decode}; @@ -126,29 +126,12 @@ use primitives::ChangesTrieConfiguration; pub mod offchain; /// Handler for when a new account has been created. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnNewAccount<AccountId> { /// A new account `who` has been registered. fn on_new_account(who: &AccountId); } -macro_rules! impl_on_new_account { - () => ( - impl<AccountId> OnNewAccount<AccountId> for () { - fn on_new_account(_: &AccountId) {} - } - ); - - ( $($t:ident)* ) => { - impl<AccountId, $($t: OnNewAccount<AccountId>),*> OnNewAccount<AccountId> for ($($t,)*) { - fn on_new_account(who: &AccountId) { - $($t::on_new_account(who);)* - } - } - } -} - -for_each_tuple!(impl_on_new_account); - /// Determiner to say whether a given account is unused. pub trait IsDeadAccount<AccountId> { /// Is the given account dead? diff --git a/srml/timestamp/Cargo.toml b/srml/timestamp/Cargo.toml index 022e478e57ea084397e07e09d1e10d7a01ed8508..00eaf7d7f8376de17a276ca1a443730c957ac678 100644 --- a/srml/timestamp/Cargo.toml +++ b/srml/timestamp/Cargo.toml @@ -12,6 +12,7 @@ sr-primitives = { path = "../../core/sr-primitives", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] runtime-io ={ package = "sr-io", path = "../../core/sr-io" } diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index cf7792eaa45a31ae775387918b4d9890c071bf79..919e2a75ab7ee6878877a060141263fefd6ffed7 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -96,7 +96,7 @@ use codec::Encode; use codec::Decode; #[cfg(feature = "std")] use inherents::ProvideInherentData; -use support::{StorageValue, Parameter, decl_storage, decl_module, for_each_tuple}; +use support::{StorageValue, Parameter, decl_storage, decl_module}; use support::traits::{Time, Get}; use sr_primitives::traits::{ SimpleArithmetic, Zero, SaturatedConversion, Scale @@ -183,28 +183,11 @@ impl ProvideInherentData for InherentDataProvider { } /// A trait which is called when the timestamp is set. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnTimestampSet<Moment> { fn on_timestamp_set(moment: Moment); } -macro_rules! impl_timestamp_set { - () => ( - impl<Moment> OnTimestampSet<Moment> for () { - fn on_timestamp_set(_: Moment) {} - } - ); - - ( $($t:ident)* ) => { - impl<Moment: Copy, $($t: OnTimestampSet<Moment>),*> OnTimestampSet<Moment> for ($($t,)*) { - fn on_timestamp_set(moment: Moment) { - $($t::on_timestamp_set(moment);)* - } - } - } -} - -for_each_tuple!(impl_timestamp_set); - /// The module configuration trait pub trait Trait: system::Trait { /// Type used for expressing timestamp.