diff --git a/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs b/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs index a3fe514bd638a..dbe697e7e2569 100644 --- a/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs +++ b/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs @@ -18,7 +18,7 @@ use srml_support_procedural_tools::syn_ext as ext; use proc_macro2::TokenStream; -use syn::parse_quote; +use syn::{spanned::Spanned, parse_quote}; use quote::quote; use super::super::{DeclStorageDefExt, StorageLineTypeDef}; @@ -43,8 +43,8 @@ pub struct GenesisConfigDef { } impl GenesisConfigDef { - pub fn from_def(def: &DeclStorageDefExt) -> Self { - let fields = Self::get_genesis_config_field_defs(def); + pub fn from_def(def: &DeclStorageDefExt) -> syn::Result { + let fields = Self::get_genesis_config_field_defs(def)?; let is_generic = fields.iter() .any(|field| ext::type_contains_ident(&field.typ, &def.module_runtime_generic)); @@ -71,17 +71,19 @@ impl GenesisConfigDef { (quote!(), quote!(), quote!(), None) }; - Self { + Ok(Self { is_generic, fields, genesis_struct_decl, genesis_struct, genesis_impl, genesis_where_clause, - } + }) } - fn get_genesis_config_field_defs(def: &DeclStorageDefExt) -> Vec { + fn get_genesis_config_field_defs(def: &DeclStorageDefExt) + -> syn::Result> + { let mut config_field_defs = Vec::new(); for (config_field, line) in def.storage_lines.iter() @@ -123,9 +125,18 @@ impl GenesisConfigDef { for line in &def.extra_genesis_config_lines { let attrs = line.attrs.iter() - .filter_map(|a| a.parse_meta().ok()) - .filter(|m| m.path().is_ident("doc") || m.path().is_ident("serde")) - .collect(); + .map(|attr| { + let meta = attr.parse_meta()?; + if meta.path().is_ident("doc") || meta.path().is_ident("serde") { + Ok(meta) + } else { + Err(syn::Error::new( + meta.span(), + "extra genesis config item only supports `doc` and `serde` attributes" + )) + } + }) + .collect::>()?; let default = line.default.as_ref().map(|e| quote!( #e )) .unwrap_or_else(|| quote!( Default::default() )); @@ -139,6 +150,6 @@ impl GenesisConfigDef { }); } - config_field_defs + Ok(config_field_defs) } } diff --git a/srml/support/procedural/src/storage/genesis_config/mod.rs b/srml/support/procedural/src/storage/genesis_config/mod.rs index c17eb5dfe030b..109957926a775 100644 --- a/srml/support/procedural/src/storage/genesis_config/mod.rs +++ b/srml/support/procedural/src/storage/genesis_config/mod.rs @@ -188,10 +188,13 @@ pub fn genesis_config_and_build_storage( ) -> TokenStream { let builders = BuilderDef::from_def(scrate, def); if !builders.blocks.is_empty() { - let genesis_config = &GenesisConfigDef::from_def(def); + let genesis_config = match GenesisConfigDef::from_def(def) { + Ok(genesis_config) => genesis_config, + Err(err) => return err.to_compile_error(), + }; let decl_genesis_config_and_impl_default = - decl_genesis_config_and_impl_default(scrate, genesis_config); - let impl_build_storage = impl_build_storage(scrate, def, genesis_config, &builders); + decl_genesis_config_and_impl_default(scrate, &genesis_config); + let impl_build_storage = impl_build_storage(scrate, def, &genesis_config, &builders); quote!{ #decl_genesis_config_and_impl_default