diff --git a/substrate/frame/support/procedural/src/key_prefix.rs b/substrate/frame/support/procedural/src/key_prefix.rs new file mode 100644 index 0000000000..17c310c2bc --- /dev/null +++ b/substrate/frame/support/procedural/src/key_prefix.rs @@ -0,0 +1,95 @@ +// This file is part of Substrate. + +// Copyright (C) 2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use proc_macro2::{Span, TokenStream}; +use quote::{ToTokens, format_ident, quote}; +use syn::{Ident, Result}; + +const MAX_IDENTS: usize = 18; + +pub fn impl_key_prefix_for_tuples(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")); + } + + let mut all_trait_impls = TokenStream::new(); + + for i in 2..=MAX_IDENTS { + let current_tuple = (0..i) + .map(|n| Ident::new(&format!("Tuple{}", n), Span::call_site())) + .collect::>(); + + for prefix_count in 1..i { + let (prefixes, suffixes) = current_tuple.split_at(prefix_count); + + let hashers = current_tuple.iter().map(|ident| format_ident!("Hasher{}", ident)).collect::>(); + let kargs = prefixes.iter().map(|ident| format_ident!("KArg{}", ident)).collect::>(); + let partial_keygen = generate_keygen(prefixes); + let suffix_keygen = generate_keygen(suffixes); + let suffix_tuple = generate_tuple(suffixes); + + let trait_impls = quote!{ + impl< + #(#current_tuple: FullCodec,)* + #(#hashers: StorageHasher,)* + #(#kargs: EncodeLike<#prefixes>),* + > HasKeyPrefix<( #( #kargs, )* )> for ( #( Key<#hashers, #current_tuple>, )* ) { + type Suffix = #suffix_tuple; + + fn partial_key(prefix: ( #( #kargs, )* )) -> Vec { + <#partial_keygen>::final_key(prefix) + } + } + + impl< + #(#current_tuple: FullCodec,)* + #(#hashers: ReversibleStorageHasher,)* + #(#kargs: EncodeLike<#prefixes>),* + > HasReversibleKeyPrefix<( #( #kargs, )* )> for ( #( Key<#hashers, #current_tuple>, )* ) { + fn decode_partial_key(key_material: &[u8]) -> Result { + <#suffix_keygen>::decode_final_key(key_material).map(|k| k.0) + } + } + }; + + all_trait_impls.extend(trait_impls); + } + } + + Ok(all_trait_impls) +} + +fn generate_tuple(idents: &[Ident]) -> TokenStream { + if idents.len() == 1 { + idents[0].to_token_stream() + } else { + quote!((#(#idents),*)) + } +} + +fn generate_keygen(idents: &[Ident]) -> TokenStream { + if idents.len() == 1 { + let key = &idents[0]; + let hasher = format_ident!("Hasher{}", key); + + quote!(Key<#hasher, #key>) + } else { + let hashers = idents.iter().map(|ident| format_ident!("Hasher{}", ident)); + + quote!((#(Key<#hashers, #idents>),*)) + } +} diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 6b163ed5d7..13b3f317e1 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -29,6 +29,7 @@ mod clone_no_bound; mod partial_eq_no_bound; mod default_no_bound; mod max_encoded_len; +mod key_prefix; pub(crate) use storage::INHERENT_INSTANCE_NAME; use proc_macro::TokenStream; @@ -451,3 +452,10 @@ pub(crate) const NUMBER_OF_INSTANCE: u8 = 16; pub fn derive_max_encoded_len(input: TokenStream) -> TokenStream { max_encoded_len::derive_max_encoded_len(input) } + +/// This macro is meant to be used by frame-support only. +/// It implements the trait `HasKeyPrefix` and `HasReversibleKeyPrefix` for tuple of `Key`. +#[proc_macro] +pub fn impl_key_prefix_for_tuples(input: TokenStream) -> TokenStream { + key_prefix::impl_key_prefix_for_tuples(input).unwrap_or_else(syn::Error::into_compile_error).into() +} diff --git a/substrate/frame/support/src/storage/types/key.rs b/substrate/frame/support/src/storage/types/key.rs index 79fc33a24e..a770d1b0fc 100755 --- a/substrate/frame/support/src/storage/types/key.rs +++ b/substrate/frame/support/src/storage/types/key.rs @@ -246,7 +246,7 @@ impl ReversibleKeyGenerator for Tuple { fn decode_final_key(key_material: &[u8]) -> Result<(Self::Key, &[u8]), codec::Error> { let mut current_key_material = key_material; Ok(( - (for_tuples! { + (for_tuples!{ #({ let (key, material) = Tuple::decode_final_key(current_key_material)?; current_key_material = material; @@ -270,735 +270,4 @@ pub trait HasReversibleKeyPrefix

: ReversibleKeyGenerator + HasKeyPrefix

{ fn decode_partial_key(key_material: &[u8]) -> Result; } -macro_rules! impl_key_prefix_for { - (($($keygen:ident),+), ($($prefix:ident),+), ($($suffix:ident),+)) => { - paste! { - impl< - $($keygen: FullCodec,)+ - $( [<$keygen $keygen>]: StorageHasher,)+ - $( []: EncodeLike<$prefix> ),+ - > HasKeyPrefix<($( [] ),+)> for ($(Key<[<$keygen $keygen>], $keygen>),+) { - type Suffix = ($($suffix),+); - - fn partial_key(prefix: ($( [] ),+)) -> Vec { - <($(Key<[<$prefix $prefix>], $prefix>),+)>::final_key(prefix) - } - } - - impl< - $($keygen: FullCodec,)+ - $( [<$keygen $keygen>]: ReversibleStorageHasher,)+ - $( []: EncodeLike<$prefix> ),+ - > HasReversibleKeyPrefix<($( [] ),+)> for - ($(Key<[<$keygen $keygen>], $keygen>),+) - { - fn decode_partial_key(key_material: &[u8]) -> Result { - <($(Key<[<$suffix $suffix>], $suffix>),+)>::decode_final_key(key_material).map(|k| k.0) - } - } - } - }; - (($($keygen:ident),+), $prefix:ident, ($($suffix:ident),+)) => { - paste! { - impl< - $($keygen: FullCodec,)+ - $( [<$keygen $keygen>]: StorageHasher,)+ - []: EncodeLike<$prefix> - > HasKeyPrefix<( [] ,)> for ($(Key<[<$keygen $keygen>], $keygen>),+) { - type Suffix = ($($suffix),+); - - fn partial_key(prefix: ( [] ,)) -> Vec { - ], $prefix>>::final_key(prefix) - } - } - - impl< - $($keygen: FullCodec,)+ - $( [<$keygen $keygen>]: ReversibleStorageHasher,)+ - []: EncodeLike<$prefix> - > HasReversibleKeyPrefix<( [] ,)> for - ($(Key<[<$keygen $keygen>], $keygen>),+) - { - fn decode_partial_key(key_material: &[u8]) -> Result { - <($(Key<[<$suffix $suffix>], $suffix>),+)>::decode_final_key(key_material).map(|k| k.0) - } - } - } - }; - (($($keygen:ident),+), ($($prefix:ident),+), $suffix:ident) => { - paste! { - impl< - $($keygen: FullCodec,)+ - $( [<$keygen $keygen>]: StorageHasher,)+ - $( []: EncodeLike<$prefix>),+ - > HasKeyPrefix<($( [] ),+)> for ($(Key<[<$keygen $keygen>], $keygen>),+) { - type Suffix = $suffix; - - fn partial_key(prefix: ($( [] ),+)) -> Vec { - <($(Key<[<$prefix $prefix>], $prefix>),+)>::final_key(prefix) - } - } - - impl< - $($keygen: FullCodec,)+ - $( [<$keygen $keygen>]: ReversibleStorageHasher,)+ - $( []: EncodeLike<$prefix> ),+ - > HasReversibleKeyPrefix<($( [] ),+)> for - ($(Key<[<$keygen $keygen>], $keygen>),+) - { - fn decode_partial_key(key_material: &[u8]) -> Result { - ], $suffix>>::decode_final_key(key_material).map(|k| k.0) - } - } - } - }; -} - -impl HasKeyPrefix<(KArg,)> for (Key, Key) -where - A: FullCodec, - B: FullCodec, - X: StorageHasher, - Y: StorageHasher, - KArg: EncodeLike, -{ - type Suffix = B; - - fn partial_key(prefix: (KArg,)) -> Vec { - >::final_key(prefix) - } -} - -impl HasReversibleKeyPrefix<(KArg,)> for (Key, Key) -where - A: FullCodec, - B: FullCodec, - X: ReversibleStorageHasher, - Y: ReversibleStorageHasher, - KArg: EncodeLike, -{ - fn decode_partial_key(key_material: &[u8]) -> Result { - >::decode_final_key(key_material).map(|k| k.0) - } -} - -impl_key_prefix_for!((A, B, C), (A, B), C); -impl_key_prefix_for!((A, B, C), A, (B, C)); -impl_key_prefix_for!((A, B, C, D), (A, B, C), D); -impl_key_prefix_for!((A, B, C, D), (A, B), (C, D)); -impl_key_prefix_for!((A, B, C, D), A, (B, C, D)); -impl_key_prefix_for!((A, B, C, D, E), (A, B, C, D), E); -impl_key_prefix_for!((A, B, C, D, E), (A, B, C), (D, E)); -impl_key_prefix_for!((A, B, C, D, E), (A, B), (C, D, E)); -impl_key_prefix_for!((A, B, C, D, E), A, (B, C, D, E)); -impl_key_prefix_for!((A, B, C, D, E, F), (A, B, C, D, E), F); -impl_key_prefix_for!((A, B, C, D, E, F), (A, B, C, D), (E, F)); -impl_key_prefix_for!((A, B, C, D, E, F), (A, B, C), (D, E, F)); -impl_key_prefix_for!((A, B, C, D, E, F), (A, B), (C, D, E, F)); -impl_key_prefix_for!((A, B, C, D, E, F), A, (B, C, D, E, F)); -impl_key_prefix_for!((A, B, C, D, E, F, G), (A, B, C, D, E, F), G); -impl_key_prefix_for!((A, B, C, D, E, F, G), (A, B, C, D, E), (F, G)); -impl_key_prefix_for!((A, B, C, D, E, F, G), (A, B, C, D), (E, F, G)); -impl_key_prefix_for!((A, B, C, D, E, F, G), (A, B, C), (D, E, F, G)); -impl_key_prefix_for!((A, B, C, D, E, F, G), (A, B), (C, D, E, F, G)); -impl_key_prefix_for!((A, B, C, D, E, F, G), A, (B, C, D, E, F, G)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H), (A, B, C, D, E, F, G), H); -impl_key_prefix_for!((A, B, C, D, E, F, G, H), (A, B, C, D, E, F), (G, H)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H), (A, B, C, D, E), (F, G, H)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H), (A, B, C, D), (E, F, G, H)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H), (A, B, C), (D, E, F, G, H)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H), (A, B), (C, D, E, F, G, H)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H), A, (B, C, D, E, F, G, H)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H, I), (A, B, C, D, E, F, G, H), I); -impl_key_prefix_for!((A, B, C, D, E, F, G, H, I), (A, B, C, D, E, F, G), (H, I)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H, I), (A, B, C, D, E, F), (G, H, I)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H, I), (A, B, C, D, E), (F, G, H, I)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H, I), (A, B, C, D), (E, F, G, H, I)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H, I), (A, B, C), (D, E, F, G, H, I)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H, I), (A, B), (C, D, E, F, G, H, I)); -impl_key_prefix_for!((A, B, C, D, E, F, G, H, I), A, (B, C, D, E, F, G, H, I)); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J), - (A, B, C, D, E, F, G, H, I), - J -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J), - (A, B, C, D, E, F, G, H), - (I, J) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J), - (A, B, C, D, E, F, G), - (H, I, J) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J), - (A, B, C, D, E, F), - (G, H, I, J) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J), - (A, B, C, D, E), - (F, G, H, I, J) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J), - (A, B, C, D), - (E, F, G, H, I, J) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J), - (A, B, C), - (D, E, F, G, H, I, J) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J), - (A, B), - (C, D, E, F, G, H, I, J) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J), - A, - (B, C, D, E, F, G, H, I, J) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - (A, B, C, D, E, F, G, H, I, J), - K -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - (A, B, C, D, E, F, G, H, I), - (J, K) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - (A, B, C, D, E, F, G, H), - (I, J, K) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - (A, B, C, D, E, F, G), - (H, I, J, K) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - (A, B, C, D, E, F), - (G, H, I, J, K) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - (A, B, C, D, E), - (F, G, H, I, J, K) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - (A, B, C, D), - (E, F, G, H, I, J, K) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - (A, B, C), - (D, E, F, G, H, I, J, K) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - (A, B), - (C, D, E, F, G, H, I, J, K) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K), - A, - (B, C, D, E, F, G, H, I, J, K) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B, C, D, E, F, G, H, I, J, K), - L -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B, C, D, E, F, G, H, I, J), - (K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B, C, D, E, F, G, H, I), - (J, K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B, C, D, E, F, G, H), - (I, J, K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B, C, D, E, F, G), - (H, I, J, K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B, C, D, E, F), - (G, H, I, J, K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B, C, D, E), - (F, G, H, I, J, K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B, C, D), - (E, F, G, H, I, J, K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B, C), - (D, E, F, G, H, I, J, K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - (A, B), - (C, D, E, F, G, H, I, J, K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L), - A, - (B, C, D, E, F, G, H, I, J, K, L) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C, D, E, F, G, H, I, J, K, L), - M -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C, D, E, F, G, H, I, J, K), - (L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C, D, E, F, G, H, I, J), - (K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C, D, E, F, G, H, I), - (J, K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C, D, E, F, G, H), - (I, J, K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C, D, E, F, G), - (H, I, J, K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C, D, E, F), - (G, H, I, J, K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C, D, E), - (F, G, H, I, J, K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C, D), - (E, F, G, H, I, J, K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B, C), - (D, E, F, G, H, I, J, K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (A, B), - (C, D, E, F, G, H, I, J, K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M), - A, - (B, C, D, E, F, G, H, I, J, K, L, M) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D, E, F, G, H, I, J, K, L, M), - N -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D, E, F, G, H, I, J, K, L), - (M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D, E, F, G, H, I, J, K), - (L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D, E, F, G, H, I, J), - (K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D, E, F, G, H, I), - (J, K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D, E, F, G, H), - (I, J, K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D, E, F, G), - (H, I, J, K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D, E, F), - (G, H, I, J, K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D, E), - (F, G, H, I, J, K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C, D), - (E, F, G, H, I, J, K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B, C), - (D, E, F, G, H, I, J, K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (A, B), - (C, D, E, F, G, H, I, J, K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - A, - (B, C, D, E, F, G, H, I, J, K, L, M, N) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - O -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E, F, G, H, I, J, K, L), - (M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E, F, G, H, I, J, K), - (L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E, F, G, H, I, J), - (K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E, F, G, H, I), - (J, K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E, F, G, H), - (I, J, K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E, F, G), - (H, I, J, K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E, F), - (G, H, I, J, K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D, E), - (F, G, H, I, J, K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C, D), - (E, F, G, H, I, J, K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B, C), - (D, E, F, G, H, I, J, K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (A, B), - (C, D, E, F, G, H, I, J, K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - A, - (B, C, D, E, F, G, H, I, J, K, L, M, N, O) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - P -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F, G, H, I, J, K, L), - (M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F, G, H, I, J, K), - (L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F, G, H, I, J), - (K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F, G, H, I), - (J, K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F, G, H), - (I, J, K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F, G), - (H, I, J, K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E, F), - (G, H, I, J, K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D, E), - (F, G, H, I, J, K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C, D), - (E, F, G, H, I, J, K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B, C), - (D, E, F, G, H, I, J, K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (A, B), - (C, D, E, F, G, H, I, J, K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - A, - (B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - Q -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G, H, I, J, K, L), - (M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G, H, I, J, K), - (L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G, H, I, J), - (K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G, H, I), - (J, K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G, H), - (I, J, K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F, G), - (H, I, J, K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E, F), - (G, H, I, J, K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D, E), - (F, G, H, I, J, K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C, D), - (E, F, G, H, I, J, K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B, C), - (D, E, F, G, H, I, J, K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - (A, B), - (C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - A, - (B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q), - R -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P), - (Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O), - (P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H, I, J, K, L, M, N), - (O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H, I, J, K, L, M), - (N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H, I, J, K, L), - (M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H, I, J, K), - (L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H, I, J), - (K, L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H, I), - (J, K, L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G, H), - (I, J, K, L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F, G), - (H, I, J, K, L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E, F), - (G, H, I, J, K, L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D, E), - (F, G, H, I, J, K, L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C, D), - (E, F, G, H, I, J, K, L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B, C), - (D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - (A, B), - (C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) -); -impl_key_prefix_for!( - (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R), - A, - (B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) -); +frame_support_procedural::impl_key_prefix_for_tuples!();