Repository: paritytech/substrate
File: frame/support/procedural/src/pallet/parse/mod.rs (Rust)

Code before:
				},
				Some(PalletAttr::Hooks(span)) if hooks.is_none() => {
					let m = hooks::HooksDef::try_from(span, index, item)?;
					hooks = Some(m);
				},
				Some(PalletAttr::Call(span)) if call.is_none() =>
					call = Some(call::CallDef::try_from(span, index, item)?),
				Some(PalletAttr::Error(span)) if error.is_none() =>
					error = Some(error::ErrorDef::try_from(span, index, item)?),
				Some(PalletAttr::Event(span)) if event.is_none() =>
					event = Some(event::EventDef::try_from(span, index, item)?),
				Some(PalletAttr::GenesisConfig(_)) if genesis_config.is_none() => {
					let g = genesis_config::GenesisConfigDef::try_from(index, item)?;
					genesis_config = Some(g);
				},
				Some(PalletAttr::GenesisBuild(span)) if genesis_build.is_none() => {
					let g = genesis_build::GenesisBuildDef::try_from(span, index, item)?;
					genesis_build = Some(g);
				},
				Some(PalletAttr::Origin(_)) if origin.is_none() =>
					origin = Some(origin::OriginDef::try_from(index, item)?),
				Some(PalletAttr::Inherent(_)) if inherent.is_none() =>
					inherent = Some(inherent::InherentDef::try_from(index, item)?),
				Some(PalletAttr::Storage(span)) => {
					let mut storage_def = storage::StorageDef::try_from(span, index, item)?;
					Self::mark_benchmarking_cached_calls(&mut storage_def, item);
					storages.push(storage_def);
				},
				Some(PalletAttr::ValidateUnsigned(_)) if validate_unsigned.is_none() => {
					let v = validate_unsigned::ValidateUnsignedDef::try_from(index, item)?;
					validate_unsigned = Some(v);
				},
				Some(PalletAttr::TypeValue(span)) =>
					type_values.push(type_value::TypeValueDef::try_from(span, index, item)?),
				Some(PalletAttr::ExtraConstants(_)) =>
					extra_constants =
						Some(extra_constants::ExtraConstantsDef::try_from(index, item)?),
				Some(attr) => {
					let msg = "Invalid duplicated attribute";
					return Err(syn::Error::new(attr.span(), msg))
				},
				None => (),
			}
		}

		if genesis_config.is_some() != genesis_build.is_some() {
			let msg = format!(
				"`#[pallet::genesis_config]` and `#[pallet::genesis_build]` attributes must be \
				either both used or both not used, instead genesis_config is {} and genesis_build \
				is {}",
				genesis_config.as_ref().map_or("unused", |_| "used"),

Review comment (suggestion):
This still doesn't make any sense to me. `try_from` is already parsing the other attributes and we should parse the benchmarking attribute there as well. No need to scatter all the code around.

Code after:
				Some(PalletAttr::Storage(span)) =>
					storages.push(storage::StorageDef::try_from(span, index, item)?),
				Some(PalletAttr::ValidateUnsigned(_)) if validate_unsigned.is_none() => {
					let v = validate_unsigned::ValidateUnsignedDef::try_from(index, item)?;
					validate_unsigned = Some(v);
				},
				Some(PalletAttr::TypeValue(span)) =>
					type_values.push(type_value::TypeValueDef::try_from(span, index, item)?),
				Some(PalletAttr::ExtraConstants(_)) =>
					extra_constants =
						Some(extra_constants::ExtraConstantsDef::try_from(index, item)?),
				Some(attr) => {
					let msg = "Invalid duplicated attribute";
					return Err(syn::Error::new(attr.span(), msg))
				},
				None => (),
			}
		}

		if genesis_config.is_some() != genesis_build.is_some() {
			let msg = format!(
				"`#[pallet::genesis_config]` and `#[pallet::genesis_build]` attributes must be \
				either both used or both not used, instead genesis_config is {} and genesis_build \
				is {}",
				genesis_config.as_ref().map_or("unused", |_| "used"),
				genesis_build.as_ref().map_or("unused", |_| "used"),
			);
			return Err(syn::Error::new(item_span, msg))
		}

		let def = Def {
			item,
			config: config
				.ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::config]`"))?,
			pallet_struct: pallet_struct
				.ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::pallet]`"))?,
			hooks,
			call,
			extra_constants,
			genesis_config,
			genesis_build,
			validate_unsigned,
			error,
			event,
			origin,
			inherent,
			storages,
			type_values,
			frame_system,
			frame_support,
		};