Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion frame/support/procedural/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,8 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream {
/// storage types. This is equivalent to specifying `#[pallet::unbounded]` on all storage type
/// definitions.
/// * Storage hashers no longer need to be specified and can be replaced by `_`. In dev mode, these
/// will be replaced by `Blake2_128Concat`.
/// will be replaced by `Blake2_128Concat`. In case of explicit key-binding, `Hasher` can simply
/// be ignored when in `dev_mode`.
///
/// Note that the `dev_mode` argument can only be supplied to the `#[pallet]` or
/// `#[frame_support::pallet]` attribute macro that encloses your pallet module. This argument
Expand Down
38 changes: 27 additions & 11 deletions frame/support/procedural/src/pallet/parse/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ fn process_named_generics(
storage: &StorageKind,
args_span: proc_macro2::Span,
args: &[syn::AssocType],
dev_mode: bool,
) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>, bool)> {
let mut parsed = HashMap::<String, syn::AssocType>::new();

Expand All @@ -346,6 +347,14 @@ fn process_named_generics(
parsed.insert(arg.ident.to_string(), arg.clone());
}

let mut map_mandatory_generics = vec!["Key", "Value"];
let mut map_optional_generics = vec!["QueryKind", "OnEmpty", "MaxValues"];
if dev_mode {
map_optional_generics.push("Hasher");
} else {
map_mandatory_generics.push("Hasher");
}

let generics = match storage {
StorageKind::Value => {
check_generics(
Expand All @@ -368,8 +377,8 @@ fn process_named_generics(
StorageKind::Map => {
check_generics(
&parsed,
&["Hasher", "Key", "Value"],
&["QueryKind", "OnEmpty", "MaxValues"],
&map_mandatory_generics,
&map_optional_generics,
"StorageMap",
args_span,
)?;
Expand All @@ -378,7 +387,7 @@ fn process_named_generics(
hasher: parsed
.remove("Hasher")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
.unwrap_or(syn::parse_quote!(Blake2_128Concat)),
key: parsed
.remove("Key")
.map(|binding| binding.ty)
Expand All @@ -395,8 +404,8 @@ fn process_named_generics(
StorageKind::CountedMap => {
check_generics(
&parsed,
&["Hasher", "Key", "Value"],
&["QueryKind", "OnEmpty", "MaxValues"],
&map_mandatory_generics,
&map_optional_generics,
"CountedStorageMap",
args_span,
)?;
Expand All @@ -405,7 +414,7 @@ fn process_named_generics(
hasher: parsed
.remove("Hasher")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
.unwrap_or(syn::Type::Verbatim(quote::quote! { Blake2_128Concat })),
key: parsed
.remove("Key")
.map(|binding| binding.ty)
Expand All @@ -420,10 +429,17 @@ fn process_named_generics(
}
},
StorageKind::DoubleMap => {
let mut double_map_mandatory_generics = vec!["Key1", "Key2", "Value"];
if dev_mode {
map_optional_generics.extend(["Hasher1", "Hasher2"]);
} else {
double_map_mandatory_generics.extend(["Hasher1", "Hasher2"]);
}

check_generics(
&parsed,
&["Hasher1", "Key1", "Hasher2", "Key2", "Value"],
&["QueryKind", "OnEmpty", "MaxValues"],
&double_map_mandatory_generics,
&map_optional_generics,
"StorageDoubleMap",
args_span,
)?;
Expand All @@ -432,15 +448,15 @@ fn process_named_generics(
hasher1: parsed
.remove("Hasher1")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
.unwrap_or(syn::parse_quote!(Blake2_128Concat)),
key1: parsed
.remove("Key1")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
hasher2: parsed
.remove("Hasher2")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
.unwrap_or(syn::parse_quote!(Blake2_128Concat)),
key2: parsed
.remove("Key2")
.map(|binding| binding.ty)
Expand Down Expand Up @@ -619,7 +635,7 @@ fn process_generics(
_ => unreachable!("It is asserted above that all generics are bindings"),
})
.collect::<Vec<_>>();
process_named_generics(&storage_kind, args_span, &args)
process_named_generics(&storage_kind, args_span, &args, dev_mode)
} else {
let msg = "Invalid pallet::storage, invalid generic declaration for storage. Expect only \
type generics or binding generics, e.g. `<Name1 = Gen1, Name2 = Gen2, ..>` or \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;

// The struct on which we build all of our Pallet logic.
#[pallet::pallet]
pub struct Pallet<T>(_);

// Your Pallet's configuration trait, representing custom external types and interfaces.
#[pallet::config]
pub trait Config: frame_system::Config {}

#[pallet::storage]
type MyStorage<T: Config> = StorageValue<_, Vec<u8>>;

#[pallet::storage]
type MyStorageMap<T: Config> = StorageMap<Key = u32, Value = u64>;

#[pallet::storage]
type MyStorageDoubleMap<T: Config> = StorageDoubleMap<Key1 = u32, Key2 = u64, Value = u64>;

#[pallet::storage]
type MyCountedStorageMap<T: Config> = CountedStorageMap<Key = u32, Value = u64>;

// Your Pallet's internal functions.
impl<T: Config> Pallet<T> {}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: Invalid pallet::storage, cannot find `Hasher` generic, required for `StorageMap`.
--> tests/pallet_ui/non_dev_mode_storage_map_explicit_key_default_hasher.rs:21:43
|
21 | type MyStorageMap<T: Config> = StorageMap<Key = u32, Value = u64>;
| ^

error[E0432]: unresolved import `pallet`
--> tests/pallet_ui/non_dev_mode_storage_map_explicit_key_default_hasher.rs:3:9
|
3 | pub use pallet::*;
| ^^^^^^ help: a similar path exists: `test_pallet::pallet`
9 changes: 9 additions & 0 deletions frame/support/test/tests/pallet_ui/pass/dev_mode_valid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ pub mod pallet {
#[pallet::storage]
type MyCountedStorageMap<T: Config> = CountedStorageMap<_, _, u32, u64>;

#[pallet::storage]
pub type MyStorageMap2<T: Config> = StorageMap<Key = u32, Value = u64>;

#[pallet::storage]
type MyStorageDoubleMap2<T: Config> = StorageDoubleMap<Key1 = u32, Key2 = u64, Value = u64>;

#[pallet::storage]
type MyCountedStorageMap2<T: Config> = CountedStorageMap<Key = u32, Value = u64>;

// Your Pallet's callable functions.
#[pallet::call]
impl<T: Config> Pallet<T> {
Expand Down