frame_support_procedural/
lib.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Proc macro of Support code for the runtime.
19
20#![recursion_limit = "512"]
21#![deny(rustdoc::broken_intra_doc_links)]
22
23mod benchmark;
24mod construct_runtime;
25mod crate_version;
26mod deprecation;
27mod derive_impl;
28mod dummy_part_checker;
29mod dynamic_params;
30mod key_prefix;
31mod match_and_insert;
32mod no_bound;
33mod pallet;
34mod pallet_error;
35mod runtime;
36mod storage_alias;
37mod transactional;
38mod tt_macro;
39
40use frame_support_procedural_tools::generate_access_from_frame_or_crate;
41use macro_magic::{import_tokens_attr, import_tokens_attr_verbatim};
42use proc_macro::TokenStream;
43use quote::{quote, ToTokens};
44use std::{cell::RefCell, str::FromStr};
45use syn::{parse_macro_input, Error, ItemImpl, ItemMod, TraitItemType};
46
47pub(crate) const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance";
48
49thread_local! {
50	/// A global counter, can be used to generate a relatively unique identifier.
51	static COUNTER: RefCell<Counter> = RefCell::new(Counter(0));
52}
53
54/// Counter to generate a relatively unique identifier for macros. This is necessary because
55/// declarative macros gets hoisted to the crate root, which shares the namespace with other pallets
56/// containing the very same macros.
57struct Counter(u64);
58
59impl Counter {
60	fn inc(&mut self) -> u64 {
61		let ret = self.0;
62		self.0 += 1;
63		ret
64	}
65}
66
67/// Get the value from the given environment variable set by cargo.
68///
69/// The value is parsed into the requested destination type.
70fn get_cargo_env_var<T: FromStr>(version_env: &str) -> std::result::Result<T, ()> {
71	let version = std::env::var(version_env)
72		.unwrap_or_else(|_| panic!("`{}` is always set by cargo; qed", version_env));
73
74	T::from_str(&version).map_err(drop)
75}
76
77/// Generate the counter_prefix related to the storage.
78/// counter_prefix is used by counted storage map.
79fn counter_prefix(prefix: &str) -> String {
80	format!("CounterFor{}", prefix)
81}
82
83/// Construct a runtime, with the given name and the given pallets.
84///
85/// NOTE: A new version of this macro is available at `frame_support::runtime`. This macro will
86/// soon be deprecated. Please use the new macro instead.
87///
88/// The parameters here are specific types for `Block`, `NodeBlock`, and `UncheckedExtrinsic`
89/// and the pallets that are used by the runtime.
90/// `Block` is the block type that is used in the runtime and `NodeBlock` is the block type
91/// that is used in the node. For instance they can differ in the extrinsics type.
92///
93/// # Example:
94///
95/// ```ignore
96/// construct_runtime!(
97///     pub enum Runtime where
98///         Block = Block,
99///         NodeBlock = node::Block,
100///         UncheckedExtrinsic = UncheckedExtrinsic
101///     {
102///         System: frame_system::{Pallet, Call, Event<T>, Config<T>} = 0,
103///         Test: path::to::test::{Pallet, Call} = 1,
104///
105///         // Pallets with instances.
106///         Test2_Instance1: test2::<Instance1>::{Pallet, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>},
107///         Test2_DefaultInstance: test2::{Pallet, Call, Storage, Event<T>, Config<T>, Origin<T>} = 4,
108///
109///         // Pallets declared with `pallet` attribute macro: no need to define the parts
110///         Test3_Instance1: test3::<Instance1>,
111///         Test3_DefaultInstance: test3,
112///
113///         // with `exclude_parts` keyword some part can be excluded.
114///         Test4_Instance1: test4::<Instance1> exclude_parts { Call, Origin },
115///         Test4_DefaultInstance: test4 exclude_parts { Storage },
116///
117///         // with `use_parts` keyword, a subset of the pallet parts can be specified.
118///         Test4_Instance1: test4::<Instance1> use_parts { Pallet, Call},
119///         Test4_DefaultInstance: test4 use_parts { Pallet },
120///     }
121/// )
122/// ```
123///
124/// Each pallet is declared as such:
125/// * `Identifier`: name given to the pallet that uniquely identifies it.
126///
127/// * `:`: colon separator
128///
129/// * `path::to::pallet`: identifiers separated by colons which declare the path to a pallet
130///   definition.
131///
132/// * `::<InstanceN>` optional: specify the instance of the pallet to use. If not specified it will
133///   use the default instance (or the only instance in case of non-instantiable pallets).
134///
135/// * `::{ Part1, Part2<T>, .. }` optional if pallet declared with `frame_support::pallet`: Comma
136///   separated parts declared with their generic. If a pallet is declared with
137///   `frame_support::pallet` macro then the parts can be automatically derived if not explicitly
138///   provided. We provide support for the following module parts in a pallet:
139///
140///   - `Pallet` - Required for all pallets
141///   - `Call` - If the pallet has callable functions
142///   - `Storage` - If the pallet uses storage
143///   - `Event` or `Event<T>` (if the event is generic) - If the pallet emits events
144///   - `Origin` or `Origin<T>` (if the origin is generic) - If the pallet has instantiable origins
145///   - `Config` or `Config<T>` (if the config is generic) - If the pallet builds the genesis
146///     storage with `GenesisConfig`
147///   - `Inherent` - If the pallet provides/can check inherents.
148///   - `ValidateUnsigned` - If the pallet validates unsigned extrinsics.
149///
150///   It is important to list these parts here to export them correctly in the metadata or to make
151/// the pallet usable in the runtime.
152///
153/// * `exclude_parts { Part1, Part2 }` optional: comma separated parts without generics. I.e. one of
154///   `Pallet`, `Call`, `Storage`, `Event`, `Origin`, `Config`, `Inherent`, `ValidateUnsigned`. It
155///   is incompatible with `use_parts`. This specifies the part to exclude. In order to select
156///   subset of the pallet parts.
157///
158///   For example excluding the part `Call` can be useful if the runtime doesn't want to make the
159///   pallet calls available.
160///
161/// * `use_parts { Part1, Part2 }` optional: comma separated parts without generics. I.e. one of
162///   `Pallet`, `Call`, `Storage`, `Event`, `Origin`, `Config`, `Inherent`, `ValidateUnsigned`. It
163///   is incompatible with `exclude_parts`. This specifies the part to use. In order to select a
164///   subset of the pallet parts.
165///
166///   For example not using the part `Call` can be useful if the runtime doesn't want to make the
167///   pallet calls available.
168///
169/// * `= $n` optional: number to define at which index the pallet variants in `OriginCaller`, `Call`
170///   and `Event` are encoded, and to define the ModuleToIndex value.
171///
172///   if `= $n` is not given, then index is resolved in the same way as fieldless enum in Rust
173///   (i.e. incrementally from previous index):
174///   ```nocompile
175///   pallet1 .. = 2,
176///   pallet2 .., // Here pallet2 is given index 3
177///   pallet3 .. = 0,
178///   pallet4 .., // Here pallet4 is given index 1
179///   ```
180///
181/// # Note
182///
183/// The population of the genesis storage depends on the order of pallets. So, if one of your
184/// pallets depends on another pallet, the pallet that is depended upon needs to come before
185/// the pallet depending on it.
186///
187/// # Type definitions
188///
189/// * The macro generates a type alias for each pallet to their `Pallet`. E.g. `type System =
190///   frame_system::Pallet<Runtime>`
191#[proc_macro]
192pub fn construct_runtime(input: TokenStream) -> TokenStream {
193	construct_runtime::construct_runtime(input)
194}
195
196///
197/// ---
198///
199/// Documentation for this macro can be found at `frame_support::pallet`.
200#[proc_macro_attribute]
201pub fn pallet(attr: TokenStream, item: TokenStream) -> TokenStream {
202	pallet::pallet(attr, item)
203}
204
205/// An attribute macro that can be attached to a (non-empty) module declaration. Doing so will
206/// designate that module as a benchmarking module.
207///
208/// See `frame_benchmarking::v2` for more info.
209#[proc_macro_attribute]
210pub fn benchmarks(attr: TokenStream, tokens: TokenStream) -> TokenStream {
211	match benchmark::benchmarks(attr, tokens, false) {
212		Ok(tokens) => tokens,
213		Err(err) => err.to_compile_error().into(),
214	}
215}
216
217/// An attribute macro that can be attached to a (non-empty) module declaration. Doing so will
218/// designate that module as an instance benchmarking module.
219///
220/// See `frame_benchmarking::v2` for more info.
221#[proc_macro_attribute]
222pub fn instance_benchmarks(attr: TokenStream, tokens: TokenStream) -> TokenStream {
223	match benchmark::benchmarks(attr, tokens, true) {
224		Ok(tokens) => tokens,
225		Err(err) => err.to_compile_error().into(),
226	}
227}
228
229/// An attribute macro used to declare a benchmark within a benchmarking module. Must be
230/// attached to a function definition containing an `#[extrinsic_call]` or `#[block]`
231/// attribute.
232///
233/// See `frame_benchmarking::v2` for more info.
234#[proc_macro_attribute]
235pub fn benchmark(_attrs: TokenStream, _tokens: TokenStream) -> TokenStream {
236	quote!(compile_error!(
237		"`#[benchmark]` must be in a module labeled with #[benchmarks] or #[instance_benchmarks]."
238	))
239	.into()
240}
241
242/// An attribute macro used to specify the extrinsic call inside a benchmark function, and also
243/// used as a boundary designating where the benchmark setup code ends, and the benchmark
244/// verification code begins.
245///
246/// See `frame_benchmarking::v2` for more info.
247#[proc_macro_attribute]
248pub fn extrinsic_call(_attrs: TokenStream, _tokens: TokenStream) -> TokenStream {
249	quote!(compile_error!(
250		"`#[extrinsic_call]` must be in a benchmark function definition labeled with `#[benchmark]`."
251	);)
252	.into()
253}
254
255/// An attribute macro used to specify that a block should be the measured portion of the
256/// enclosing benchmark function, This attribute is also used as a boundary designating where
257/// the benchmark setup code ends, and the benchmark verification code begins.
258///
259/// See `frame_benchmarking::v2` for more info.
260#[proc_macro_attribute]
261pub fn block(_attrs: TokenStream, _tokens: TokenStream) -> TokenStream {
262	quote!(compile_error!(
263		"`#[block]` must be in a benchmark function definition labeled with `#[benchmark]`."
264	))
265	.into()
266}
267
268/// Execute the annotated function in a new storage transaction.
269///
270/// The return type of the annotated function must be `Result`. All changes to storage performed
271/// by the annotated function are discarded if it returns `Err`, or committed if `Ok`.
272///
273/// # Example
274///
275/// ```nocompile
276/// #[transactional]
277/// fn value_commits(v: u32) -> result::Result<u32, &'static str> {
278/// 	Value::set(v);
279/// 	Ok(v)
280/// }
281///
282/// #[transactional]
283/// fn value_rollbacks(v: u32) -> result::Result<u32, &'static str> {
284/// 	Value::set(v);
285/// 	Err("nah")
286/// }
287/// ```
288#[proc_macro_attribute]
289pub fn transactional(attr: TokenStream, input: TokenStream) -> TokenStream {
290	transactional::transactional(attr, input).unwrap_or_else(|e| e.to_compile_error().into())
291}
292
293///
294/// ---
295///
296/// Documentation for this macro can be found at `frame_support::require_transactional`.
297#[proc_macro_attribute]
298pub fn require_transactional(attr: TokenStream, input: TokenStream) -> TokenStream {
299	transactional::require_transactional(attr, input)
300		.unwrap_or_else(|e| e.to_compile_error().into())
301}
302
303/// Derive [`Clone`] but do not bound any generic.
304///
305/// Docs at `frame_support::CloneNoBound`.
306#[proc_macro_derive(CloneNoBound)]
307pub fn derive_clone_no_bound(input: TokenStream) -> TokenStream {
308	no_bound::clone::derive_clone_no_bound(input)
309}
310
311/// Derive [`Debug`] but do not bound any generics.
312///
313/// Docs at `frame_support::DebugNoBound`.
314#[proc_macro_derive(DebugNoBound)]
315pub fn derive_debug_no_bound(input: TokenStream) -> TokenStream {
316	no_bound::debug::derive_debug_no_bound(input)
317}
318
319/// Derive [`Debug`], if `std` is enabled it uses `frame_support::DebugNoBound`, if `std` is not
320/// enabled it just returns `"<wasm:stripped>"`.
321/// This behaviour is useful to prevent bloating the runtime WASM blob from unneeded code.
322#[proc_macro_derive(RuntimeDebugNoBound)]
323pub fn derive_runtime_debug_no_bound(input: TokenStream) -> TokenStream {
324	let try_runtime_or_std_impl: proc_macro2::TokenStream =
325		no_bound::debug::derive_debug_no_bound(input.clone()).into();
326
327	let stripped_impl = {
328		let input = syn::parse_macro_input!(input as syn::DeriveInput);
329
330		let name = &input.ident;
331		let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
332
333		quote::quote!(
334			const _: () = {
335				impl #impl_generics ::core::fmt::Debug for #name #ty_generics #where_clause {
336					fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> core::fmt::Result {
337						fmt.write_str("<wasm:stripped>")
338					}
339				}
340			};
341		)
342	};
343
344	let frame_support = match generate_access_from_frame_or_crate("frame-support") {
345		Ok(frame_support) => frame_support,
346		Err(e) => return e.to_compile_error().into(),
347	};
348
349	quote::quote!(
350		#frame_support::try_runtime_or_std_enabled! {
351			#try_runtime_or_std_impl
352		}
353		#frame_support::try_runtime_and_std_not_enabled! {
354			#stripped_impl
355		}
356	)
357	.into()
358}
359
360/// Derive [`PartialEq`] but do not bound any generic.
361///
362/// Docs at `frame_support::PartialEqNoBound`.
363#[proc_macro_derive(PartialEqNoBound)]
364pub fn derive_partial_eq_no_bound(input: TokenStream) -> TokenStream {
365	no_bound::partial_eq::derive_partial_eq_no_bound(input)
366}
367
368/// DeriveEq but do no bound any generic.
369///
370/// Docs at `frame_support::EqNoBound`.
371#[proc_macro_derive(EqNoBound)]
372pub fn derive_eq_no_bound(input: TokenStream) -> TokenStream {
373	let input = syn::parse_macro_input!(input as syn::DeriveInput);
374
375	let name = &input.ident;
376	let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
377
378	quote::quote_spanned!(name.span() =>
379		const _: () = {
380			impl #impl_generics ::core::cmp::Eq for #name #ty_generics #where_clause {}
381		};
382	)
383	.into()
384}
385
386/// Derive [`PartialOrd`] but do not bound any generic. Docs are at
387/// `frame_support::PartialOrdNoBound`.
388#[proc_macro_derive(PartialOrdNoBound)]
389pub fn derive_partial_ord_no_bound(input: TokenStream) -> TokenStream {
390	no_bound::partial_ord::derive_partial_ord_no_bound(input)
391}
392
393/// Derive [`Ord`] but do no bound any generic. Docs are at `frame_support::OrdNoBound`.
394#[proc_macro_derive(OrdNoBound)]
395pub fn derive_ord_no_bound(input: TokenStream) -> TokenStream {
396	no_bound::ord::derive_ord_no_bound(input)
397}
398
399/// derive `Default` but do no bound any generic. Docs are at `frame_support::DefaultNoBound`.
400#[proc_macro_derive(DefaultNoBound, attributes(default))]
401pub fn derive_default_no_bound(input: TokenStream) -> TokenStream {
402	no_bound::default::derive_default_no_bound(input)
403}
404
405/// Macro used internally in FRAME to generate the crate version for a pallet.
406#[proc_macro]
407pub fn crate_to_crate_version(input: TokenStream) -> TokenStream {
408	crate_version::crate_to_crate_version(input)
409		.unwrap_or_else(|e| e.to_compile_error())
410		.into()
411}
412
413/// The number of module instances supported by the runtime, starting at index 1,
414/// and up to `NUMBER_OF_INSTANCE`.
415pub(crate) const NUMBER_OF_INSTANCE: u8 = 16;
416
417/// This macro is meant to be used by frame-support only.
418/// It implements the trait `HasKeyPrefix` and `HasReversibleKeyPrefix` for tuple of `Key`.
419#[proc_macro]
420pub fn impl_key_prefix_for_tuples(input: TokenStream) -> TokenStream {
421	key_prefix::impl_key_prefix_for_tuples(input)
422		.unwrap_or_else(syn::Error::into_compile_error)
423		.into()
424}
425
426/// Internal macro use by frame_support to generate dummy part checker for old pallet declaration
427#[proc_macro]
428pub fn __generate_dummy_part_checker(input: TokenStream) -> TokenStream {
429	dummy_part_checker::generate_dummy_part_checker(input)
430}
431
432/// Macro that inserts some tokens after the first match of some pattern.
433///
434/// # Example:
435///
436/// ```nocompile
437/// match_and_insert!(
438///     target = [{ Some content with { at some point match pattern } other match pattern are ignored }]
439///     pattern = [{ match pattern }] // the match pattern cannot contain any group: `[]`, `()`, `{}`
440/// 								  // can relax this constraint, but will require modifying the match logic in code
441///     tokens = [{ expansion tokens }] // content inside braces can be anything including groups
442/// );
443/// ```
444///
445/// will generate:
446///
447/// ```nocompile
448///     Some content with { at some point match pattern expansion tokens } other match patterns are
449///     ignored
450/// ```
451#[proc_macro]
452pub fn match_and_insert(input: TokenStream) -> TokenStream {
453	match_and_insert::match_and_insert(input)
454}
455
456#[proc_macro_derive(PalletError, attributes(codec))]
457pub fn derive_pallet_error(input: TokenStream) -> TokenStream {
458	pallet_error::derive_pallet_error(input)
459}
460
461/// Internal macro used by `frame_support` to create tt-call-compliant macros
462#[proc_macro]
463pub fn __create_tt_macro(input: TokenStream) -> TokenStream {
464	tt_macro::create_tt_return_macro(input)
465}
466
467///
468/// ---
469///
470/// Documentation for this macro can be found at `frame_support::pallet_macros::storage_alias`.
471#[proc_macro_attribute]
472pub fn storage_alias(attributes: TokenStream, input: TokenStream) -> TokenStream {
473	storage_alias::storage_alias(attributes.into(), input.into())
474		.unwrap_or_else(|r| r.into_compile_error())
475		.into()
476}
477
478/// This attribute can be used to derive a full implementation of a trait based on a local partial
479/// impl and an external impl containing defaults that can be overridden in the local impl.
480///
481/// For a full end-to-end example, see [below](#use-case-auto-derive-test-pallet-config-traits).
482///
483/// # Usage
484///
485/// The attribute should be attached to an impl block (strictly speaking a `syn::ItemImpl`) for
486/// which we want to inject defaults in the event of missing trait items in the block.
487///
488/// The attribute minimally takes a single `default_impl_path` argument, which should be the module
489/// path to an impl registered via [`#[register_default_impl]`](`macro@register_default_impl`) that
490/// contains the default trait items we want to potentially inject, with the general form:
491///
492/// ```ignore
493/// #[derive_impl(default_impl_path)]
494/// impl SomeTrait for SomeStruct {
495///     ...
496/// }
497/// ```
498///
499/// Optionally, a `disambiguation_path` can be specified as follows by providing `as path::here`
500/// after the `default_impl_path`:
501///
502/// ```ignore
503/// #[derive_impl(default_impl_path as disambiguation_path)]
504/// impl SomeTrait for SomeStruct {
505///     ...
506/// }
507/// ```
508///
509/// The `disambiguation_path`, if specified, should be the path to a trait that will be used to
510/// qualify all default entries that are injected into the local impl. For example if your
511/// `default_impl_path` is `some::path::TestTraitImpl` and your `disambiguation_path` is
512/// `another::path::DefaultTrait`, any items injected into the local impl will be qualified as
513/// `<some::path::TestTraitImpl as another::path::DefaultTrait>::specific_trait_item`.
514///
515/// If you omit the `as disambiguation_path` portion, the `disambiguation_path` will internally
516/// default to `A` from the `impl A for B` part of the default impl. This is useful for scenarios
517/// where all of the relevant types are already in scope via `use` statements.
518///
519/// In case the `default_impl_path` is scoped to a different module such as
520/// `some::path::TestTraitImpl`, the same scope is assumed for the `disambiguation_path`, i.e.
521/// `some::A`. This enables the use of `derive_impl` attribute without having to specify the
522/// `disambiguation_path` in most (if not all) uses within FRAME's context.
523///
524/// Conversely, the `default_impl_path` argument is required and cannot be omitted.
525///
526/// Optionally, `no_aggregated_types` can be specified as follows:
527///
528/// ```ignore
529/// #[derive_impl(default_impl_path as disambiguation_path, no_aggregated_types)]
530/// impl SomeTrait for SomeStruct {
531///     ...
532/// }
533/// ```
534///
535/// If specified, this indicates that the aggregated types (as denoted by impl items
536/// attached with [`#[inject_runtime_type]`]) should not be injected with the respective concrete
537/// types. By default, all such types are injected.
538///
539/// You can also make use of `#[pallet::no_default]` on specific items in your default impl that you
540/// want to ensure will not be copied over but that you nonetheless want to use locally in the
541/// context of the foreign impl and the pallet (or context) in which it is defined.
542///
543/// ## Use-Case Example: Auto-Derive Test Pallet Config Traits
544///
545/// The `#[derive_imp(..)]` attribute can be used to derive a test pallet `Config` based on an
546/// existing pallet `Config` that has been marked with
547/// [`#[pallet::config(with_default)]`](`macro@config`) (which under the hood, generates a
548/// `DefaultConfig` trait in the pallet in which the macro was invoked).
549///
550/// In this case, the `#[derive_impl(..)]` attribute should be attached to an `impl` block that
551/// implements a compatible `Config` such as `frame_system::Config` for a test/mock runtime, and
552/// should receive as its first argument the path to a `DefaultConfig` impl that has been registered
553/// via [`#[register_default_impl]`](`macro@register_default_impl`), and as its second argument, the
554/// path to the auto-generated `DefaultConfig` for the existing pallet `Config` we want to base our
555/// test config off of.
556///
557/// The following is what the `basic` example pallet would look like with a default testing config:
558///
559/// ```ignore
560/// #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::pallet::DefaultConfig)]
561/// impl frame_system::Config for Test {
562///     // These are all defined by system as mandatory.
563///     type BaseCallFilter = frame_support::traits::Everything;
564///     type RuntimeEvent = RuntimeEvent;
565///     type RuntimeCall = RuntimeCall;
566///     type RuntimeOrigin = RuntimeOrigin;
567///     type OnSetCode = ();
568///     type PalletInfo = PalletInfo;
569///     type Block = Block;
570///     // We decide to override this one.
571///     type AccountData = pallet_balances::AccountData<u64>;
572/// }
573/// ```
574///
575/// where `TestDefaultConfig` was defined and registered as follows:
576/// ```ignore
577/// pub struct TestDefaultConfig;
578///
579/// #[register_default_impl(TestDefaultConfig)]
580/// impl DefaultConfig for TestDefaultConfig {
581///     type Version = ();
582///     type BlockWeights = ();
583///     type BlockLength = ();
584///     type DbWeight = ();
585///     type Nonce = u64;
586///     type BlockNumber = u64;
587///     type Hash = sp_core::hash::H256;
588///     type Hashing = sp_runtime::traits::BlakeTwo256;
589///     type AccountId = AccountId;
590///     type Lookup = IdentityLookup<AccountId>;
591///     type BlockHashCount = frame_support::traits::ConstU64<10>;
592///     type AccountData = u32;
593///     type OnNewAccount = ();
594///     type OnKilledAccount = ();
595///     type SystemWeightInfo = ();
596///     type SS58Prefix = ();
597///     type MaxConsumers = frame_support::traits::ConstU32<16>;
598/// }
599/// ```
600///
601/// The above call to `derive_impl` would expand to roughly the following:
602/// ```ignore
603/// impl frame_system::Config for Test {
604///     use frame_system::config_preludes::TestDefaultConfig;
605///     use frame_system::pallet::DefaultConfig;
606///
607///     type BaseCallFilter = frame_support::traits::Everything;
608///     type RuntimeEvent = RuntimeEvent;
609///     type RuntimeCall = RuntimeCall;
610///     type RuntimeOrigin = RuntimeOrigin;
611///     type OnSetCode = ();
612///     type PalletInfo = PalletInfo;
613///     type Block = Block;
614///     type AccountData = pallet_balances::AccountData<u64>;
615///     type Version = <TestDefaultConfig as DefaultConfig>::Version;
616///     type BlockWeights = <TestDefaultConfig as DefaultConfig>::BlockWeights;
617///     type BlockLength = <TestDefaultConfig as DefaultConfig>::BlockLength;
618///     type DbWeight = <TestDefaultConfig as DefaultConfig>::DbWeight;
619///     type Nonce = <TestDefaultConfig as DefaultConfig>::Nonce;
620///     type BlockNumber = <TestDefaultConfig as DefaultConfig>::BlockNumber;
621///     type Hash = <TestDefaultConfig as DefaultConfig>::Hash;
622///     type Hashing = <TestDefaultConfig as DefaultConfig>::Hashing;
623///     type AccountId = <TestDefaultConfig as DefaultConfig>::AccountId;
624///     type Lookup = <TestDefaultConfig as DefaultConfig>::Lookup;
625///     type BlockHashCount = <TestDefaultConfig as DefaultConfig>::BlockHashCount;
626///     type OnNewAccount = <TestDefaultConfig as DefaultConfig>::OnNewAccount;
627///     type OnKilledAccount = <TestDefaultConfig as DefaultConfig>::OnKilledAccount;
628///     type SystemWeightInfo = <TestDefaultConfig as DefaultConfig>::SystemWeightInfo;
629///     type SS58Prefix = <TestDefaultConfig as DefaultConfig>::SS58Prefix;
630///     type MaxConsumers = <TestDefaultConfig as DefaultConfig>::MaxConsumers;
631/// }
632/// ```
633///
634/// You can then use the resulting `Test` config in test scenarios.
635///
636/// Note that items that are _not_ present in our local `DefaultConfig` are automatically copied
637/// from the foreign trait (in this case `TestDefaultConfig`) into the local trait impl (in this
638/// case `Test`), unless the trait item in the local trait impl is marked with
639/// [`#[pallet::no_default]`](`macro@no_default`), in which case it cannot be overridden, and any
640/// attempts to do so will result in a compiler error.
641///
642/// See `frame/examples/default-config/tests.rs` for a runnable end-to-end example pallet that makes
643/// use of `derive_impl` to derive its testing config.
644///
645/// See [here](`macro@config`) for more information and caveats about the auto-generated
646/// `DefaultConfig` trait.
647///
648/// ## Optional Conventions
649///
650/// Note that as an optional convention, we encourage creating a `config_preludes` module inside of
651/// your pallet. This is the convention we follow for `frame_system`'s `TestDefaultConfig` which, as
652/// shown above, is located at `frame_system::config_preludes::TestDefaultConfig`. This is just a
653/// suggested convention -- there is nothing in the code that expects modules with these names to be
654/// in place, so there is no imperative to follow this pattern unless desired.
655///
656/// In `config_preludes`, you can place types named like:
657///
658/// * `TestDefaultConfig`
659/// * `ParachainDefaultConfig`
660/// * `SolochainDefaultConfig`
661///
662/// Signifying in which context they can be used.
663///
664/// # Advanced Usage
665///
666/// ## Expansion
667///
668/// The `#[derive_impl(default_impl_path as disambiguation_path)]` attribute will expand to the
669/// local impl, with any extra items from the foreign impl that aren't present in the local impl
670/// also included. In the case of a colliding trait item, the version of the item that exists in the
671/// local impl will be retained. All imported items are qualified by the `disambiguation_path`, as
672/// discussed above.
673///
674/// ## Handling of Unnamed Trait Items
675///
676/// Items that lack a `syn::Ident` for whatever reason are first checked to see if they exist,
677/// verbatim, in the local/destination trait before they are copied over, so you should not need to
678/// worry about collisions between identical unnamed items.
679#[import_tokens_attr_verbatim {
680    format!(
681        "{}::macro_magic",
682        match generate_access_from_frame_or_crate("frame-support") {
683            Ok(path) => Ok(path),
684            Err(_) => generate_access_from_frame_or_crate("polkadot-sdk-frame"),
685        }
686        .expect("Failed to find either `frame-support` or `polkadot-sdk-frame` in `Cargo.toml` dependencies.")
687        .to_token_stream()
688        .to_string()
689    )
690}]
691#[with_custom_parsing(derive_impl::DeriveImplAttrArgs)]
692#[proc_macro_attribute]
693pub fn derive_impl(attrs: TokenStream, input: TokenStream) -> TokenStream {
694	let custom_attrs = parse_macro_input!(__custom_tokens as derive_impl::DeriveImplAttrArgs);
695	derive_impl::derive_impl(
696		__source_path.into(),
697		attrs.into(),
698		input.into(),
699		custom_attrs.disambiguation_path,
700		custom_attrs.no_aggregated_types,
701		custom_attrs.generics,
702	)
703	.unwrap_or_else(|r| r.into_compile_error())
704	.into()
705}
706
707///
708/// ---
709///
710/// Documentation for this macro can be found at `frame_support::pallet_macros::no_default`.
711#[proc_macro_attribute]
712pub fn no_default(_: TokenStream, _: TokenStream) -> TokenStream {
713	pallet_macro_stub()
714}
715
716///
717/// ---
718///
719/// Documentation for this macro can be found at `frame_support::pallet_macros::no_default_bounds`.
720#[proc_macro_attribute]
721pub fn no_default_bounds(_: TokenStream, _: TokenStream) -> TokenStream {
722	pallet_macro_stub()
723}
724
725/// Attach this attribute to an impl statement that you want to use with
726/// [`#[derive_impl(..)]`](`macro@derive_impl`).
727///
728/// You must also provide an identifier/name as the attribute's argument. This is the name you
729/// must provide to [`#[derive_impl(..)]`](`macro@derive_impl`) when you import this impl via
730/// the `default_impl_path` argument. This name should be unique at the crate-level.
731///
732/// ## Example
733///
734/// ```ignore
735/// pub struct ExampleTestDefaultConfig;
736///
737/// #[register_default_impl(ExampleTestDefaultConfig)]
738/// impl DefaultConfig for ExampleTestDefaultConfig {
739/// 	type Version = ();
740/// 	type BlockWeights = ();
741/// 	type BlockLength = ();
742/// 	...
743/// 	type SS58Prefix = ();
744/// 	type MaxConsumers = frame_support::traits::ConstU32<16>;
745/// }
746/// ```
747///
748/// ## Advanced Usage
749///
750/// This macro acts as a thin wrapper around macro_magic's `#[export_tokens]`. See the docs
751/// [here](https://docs.rs/macro_magic/latest/macro_magic/attr.export_tokens.html) for more
752/// info.
753///
754/// There are some caveats when applying a `use` statement to bring a
755/// `#[register_default_impl]` item into scope. If you have a `#[register_default_impl]`
756/// defined in `my_crate::submodule::MyItem`, it is currently not sufficient to do something
757/// like:
758///
759/// ```ignore
760/// use my_crate::submodule::MyItem;
761/// #[derive_impl(MyItem as Whatever)]
762/// ```
763///
764/// This will fail with a mysterious message about `__export_tokens_tt_my_item` not being
765/// defined.
766///
767/// You can, however, do any of the following:
768/// ```ignore
769/// // partial path works
770/// use my_crate::submodule;
771/// #[derive_impl(submodule::MyItem as Whatever)]
772/// ```
773/// ```ignore
774/// // full path works
775/// #[derive_impl(my_crate::submodule::MyItem as Whatever)]
776/// ```
777/// ```ignore
778/// // wild-cards work
779/// use my_crate::submodule::*;
780/// #[derive_impl(MyItem as Whatever)]
781/// ```
782#[proc_macro_attribute]
783pub fn register_default_impl(attrs: TokenStream, tokens: TokenStream) -> TokenStream {
784	// ensure this is a impl statement
785	let item_impl = syn::parse_macro_input!(tokens as ItemImpl);
786
787	// internally wrap macro_magic's `#[export_tokens]` macro
788	match macro_magic::mm_core::export_tokens_internal(
789		attrs,
790		item_impl.to_token_stream(),
791		true,
792		false,
793	) {
794		Ok(tokens) => tokens.into(),
795		Err(err) => err.to_compile_error().into(),
796	}
797}
798
799/// The optional attribute `#[inject_runtime_type]` can be attached to `RuntimeCall`,
800/// `RuntimeEvent`, `RuntimeOrigin` or `PalletInfo` in an impl statement that has
801/// `#[register_default_impl]` attached to indicate that this item is generated by
802/// `construct_runtime`.
803///
804/// Attaching this attribute to such an item ensures that the combined impl generated via
805/// [`#[derive_impl(..)]`](macro@derive_impl) will use the correct type auto-generated by
806/// `construct_runtime!`.
807#[doc = docify::embed!("examples/proc_main/inject_runtime_type.rs", derive_impl_works_with_runtime_type_injection)]
808///
809/// However, if `no_aggregated_types` is specified while using
810/// [`#[derive_impl(..)]`](macro@derive_impl), then these items are attached verbatim to the
811/// combined impl.
812#[doc = docify::embed!("examples/proc_main/inject_runtime_type.rs", derive_impl_works_with_no_aggregated_types)]
813#[proc_macro_attribute]
814pub fn inject_runtime_type(_: TokenStream, tokens: TokenStream) -> TokenStream {
815	let item = tokens.clone();
816	let item = syn::parse_macro_input!(item as TraitItemType);
817	if item.ident != "RuntimeCall" &&
818		item.ident != "RuntimeEvent" &&
819		item.ident != "RuntimeTask" &&
820		item.ident != "RuntimeViewFunction" &&
821		item.ident != "RuntimeOrigin" &&
822		item.ident != "RuntimeHoldReason" &&
823		item.ident != "RuntimeFreezeReason" &&
824		item.ident != "RuntimeParameters" &&
825		item.ident != "PalletInfo"
826	{
827		return syn::Error::new_spanned(
828			item,
829			"`#[inject_runtime_type]` can only be attached to `RuntimeCall`, `RuntimeEvent`, \
830			`RuntimeTask`, `RuntimeViewFunction`, `RuntimeOrigin`, `RuntimeParameters` or `PalletInfo`",
831		)
832		.to_compile_error()
833		.into();
834	}
835	tokens
836}
837
838/// Used internally to decorate pallet attribute macro stubs when they are erroneously used
839/// outside of a pallet module
840fn pallet_macro_stub() -> TokenStream {
841	quote!(compile_error!(
842		"This attribute can only be used from within a pallet module marked with `#[frame_support::pallet]`"
843	))
844	.into()
845}
846
847///
848/// ---
849///
850/// Documentation for this macro can be found at `frame_support::pallet_macros::config`.
851#[proc_macro_attribute]
852pub fn config(_: TokenStream, _: TokenStream) -> TokenStream {
853	pallet_macro_stub()
854}
855
856///
857/// ---
858///
859/// Documentation for this macro can be found at `frame_support::pallet_macros::constant`.
860#[proc_macro_attribute]
861pub fn constant(_: TokenStream, _: TokenStream) -> TokenStream {
862	pallet_macro_stub()
863}
864
865///
866/// ---
867///
868/// Documentation for this macro can be found at `frame_support::pallet_macros::constant_name`.
869#[proc_macro_attribute]
870pub fn constant_name(_: TokenStream, _: TokenStream) -> TokenStream {
871	pallet_macro_stub()
872}
873
874///
875/// ---
876///
877/// Documentation for this macro can be found at
878/// `frame_support::pallet_macros::disable_frame_system_supertrait_check`.
879#[proc_macro_attribute]
880pub fn disable_frame_system_supertrait_check(_: TokenStream, _: TokenStream) -> TokenStream {
881	pallet_macro_stub()
882}
883
884///
885/// ---
886///
887/// Documentation for this macro can be found at `frame_support::pallet_macros::storage_version`.
888#[proc_macro_attribute]
889pub fn storage_version(_: TokenStream, _: TokenStream) -> TokenStream {
890	pallet_macro_stub()
891}
892
893///
894/// ---
895///
896/// Documentation for this macro can be found at `frame_support::pallet_macros::hooks`.
897#[proc_macro_attribute]
898pub fn hooks(_: TokenStream, _: TokenStream) -> TokenStream {
899	pallet_macro_stub()
900}
901
902///
903/// ---
904///
905/// Documentation for this macro can be found at `frame_support::pallet_macros::weight`.
906#[proc_macro_attribute]
907pub fn weight(_: TokenStream, _: TokenStream) -> TokenStream {
908	pallet_macro_stub()
909}
910
911///
912/// ---
913///
914/// Documentation for this macro can be found at `frame_support::pallet_macros::compact`.
915#[proc_macro_attribute]
916pub fn compact(_: TokenStream, _: TokenStream) -> TokenStream {
917	pallet_macro_stub()
918}
919
920///
921/// ---
922///
923/// Documentation for this macro can be found at `frame_support::pallet_macros::call`.
924#[proc_macro_attribute]
925pub fn call(_: TokenStream, _: TokenStream) -> TokenStream {
926	pallet_macro_stub()
927}
928
929/// Each dispatchable may also be annotated with the `#[pallet::call_index($idx)]` attribute,
930/// which explicitly defines the codec index for the dispatchable function in the `Call` enum.
931///
932/// ---
933///
934/// Documentation for this macro can be found at `frame_support::pallet_macros::call_index`.
935#[proc_macro_attribute]
936pub fn call_index(_: TokenStream, _: TokenStream) -> TokenStream {
937	pallet_macro_stub()
938}
939
940///
941/// ---
942///
943/// Documentation for this macro can be found at `frame_support::pallet_macros::feeless_if`.
944#[proc_macro_attribute]
945pub fn feeless_if(_: TokenStream, _: TokenStream) -> TokenStream {
946	pallet_macro_stub()
947}
948
949///
950/// ---
951///
952/// Documentation for this macro can be found at `frame_support::pallet_macros::extra_constants`.
953#[proc_macro_attribute]
954pub fn extra_constants(_: TokenStream, _: TokenStream) -> TokenStream {
955	pallet_macro_stub()
956}
957
958///
959/// ---
960///
961/// Documentation for this macro can be found at `frame_support::pallet_macros::error`.
962#[proc_macro_attribute]
963pub fn error(_: TokenStream, _: TokenStream) -> TokenStream {
964	pallet_macro_stub()
965}
966
967///
968/// ---
969///
970/// Documentation for this macro can be found at `frame_support::pallet_macros::event`.
971#[proc_macro_attribute]
972pub fn event(_: TokenStream, _: TokenStream) -> TokenStream {
973	pallet_macro_stub()
974}
975
976///
977/// ---
978///
979/// Documentation for this macro can be found at `frame_support::pallet_macros::include_metadata`.
980#[proc_macro_attribute]
981pub fn include_metadata(_: TokenStream, _: TokenStream) -> TokenStream {
982	pallet_macro_stub()
983}
984
985///
986/// ---
987///
988/// Documentation for this macro can be found at `frame_support::pallet_macros::generate_deposit`.
989#[proc_macro_attribute]
990pub fn generate_deposit(_: TokenStream, _: TokenStream) -> TokenStream {
991	pallet_macro_stub()
992}
993
994///
995/// ---
996///
997/// Documentation for this macro can be found at `frame_support::pallet_macros::storage`.
998#[proc_macro_attribute]
999pub fn storage(_: TokenStream, _: TokenStream) -> TokenStream {
1000	pallet_macro_stub()
1001}
1002
1003///
1004/// ---
1005///
1006/// Documentation for this macro can be found at `frame_support::pallet_macros::getter`.
1007#[proc_macro_attribute]
1008pub fn getter(_: TokenStream, _: TokenStream) -> TokenStream {
1009	pallet_macro_stub()
1010}
1011
1012///
1013/// ---
1014///
1015/// Documentation for this macro can be found at `frame_support::pallet_macros::storage_prefix`.
1016#[proc_macro_attribute]
1017pub fn storage_prefix(_: TokenStream, _: TokenStream) -> TokenStream {
1018	pallet_macro_stub()
1019}
1020
1021///
1022/// ---
1023///
1024/// Documentation for this macro can be found at `frame_support::pallet_macros::unbounded`.
1025#[proc_macro_attribute]
1026pub fn unbounded(_: TokenStream, _: TokenStream) -> TokenStream {
1027	pallet_macro_stub()
1028}
1029
1030///
1031/// ---
1032///
1033/// Documentation for this macro can be found at `frame_support::pallet_macros::whitelist_storage`.
1034#[proc_macro_attribute]
1035pub fn whitelist_storage(_: TokenStream, _: TokenStream) -> TokenStream {
1036	pallet_macro_stub()
1037}
1038
1039///
1040/// ---
1041///
1042/// Documentation for this macro can be found at
1043/// `frame_support::pallet_macros::disable_try_decode_storage`.
1044#[proc_macro_attribute]
1045pub fn disable_try_decode_storage(_: TokenStream, _: TokenStream) -> TokenStream {
1046	pallet_macro_stub()
1047}
1048
1049///
1050/// ---
1051///
1052/// Documentation for this macro can be found at `frame_support::pallet_macros::type_value`.
1053#[proc_macro_attribute]
1054pub fn type_value(_: TokenStream, _: TokenStream) -> TokenStream {
1055	pallet_macro_stub()
1056}
1057
1058///
1059/// ---
1060///
1061/// Documentation for this macro can be found at `frame_support::pallet_macros::genesis_config`.
1062#[proc_macro_attribute]
1063pub fn genesis_config(_: TokenStream, _: TokenStream) -> TokenStream {
1064	pallet_macro_stub()
1065}
1066
1067///
1068/// ---
1069///
1070/// Documentation for this macro can be found at `frame_support::pallet_macros::genesis_build`.
1071#[proc_macro_attribute]
1072pub fn genesis_build(_: TokenStream, _: TokenStream) -> TokenStream {
1073	pallet_macro_stub()
1074}
1075
1076///
1077/// ---
1078///
1079/// Documentation for this macro can be found at `frame_support::pallet_macros::inherent`.
1080#[proc_macro_attribute]
1081pub fn inherent(_: TokenStream, _: TokenStream) -> TokenStream {
1082	pallet_macro_stub()
1083}
1084
1085///
1086/// ---
1087///
1088/// Documentation for this macro can be found at `frame_support::pallet_macros::validate_unsigned`.
1089#[proc_macro_attribute]
1090pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream {
1091	pallet_macro_stub()
1092}
1093
1094///
1095/// ---
1096///
1097/// Documentation for this macro can be found at
1098/// `frame_support::pallet_macros::view_functions_experimental`.
1099#[proc_macro_attribute]
1100pub fn view_functions_experimental(_: TokenStream, _: TokenStream) -> TokenStream {
1101	pallet_macro_stub()
1102}
1103
1104///
1105/// ---
1106///
1107/// Documentation for this macro can be found at `frame_support::pallet_macros::origin`.
1108#[proc_macro_attribute]
1109pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream {
1110	pallet_macro_stub()
1111}
1112
1113///
1114/// ---
1115///
1116/// Documentation for this macro can be found at `frame_support::pallet_macros::composite_enum`.
1117#[proc_macro_attribute]
1118pub fn composite_enum(_: TokenStream, _: TokenStream) -> TokenStream {
1119	pallet_macro_stub()
1120}
1121
1122/// Allows you to define some service work that can be recognized by a script or an
1123/// off-chain worker.
1124///
1125/// Such a script can then create and submit all such work items at any given time.
1126///
1127/// These work items are defined as instances of the `Task` trait (found at
1128/// `frame_support::traits::Task`). [`pallet:tasks_experimental`](macro@tasks_experimental) when
1129/// attached to an `impl` block inside a pallet, will generate an enum `Task<T>` whose variants
1130/// are mapped to functions inside this `impl` block.
1131///
1132/// Each such function must have the following set of attributes:
1133///
1134/// * [`pallet::task_list`](macro@task_list)
1135/// * [`pallet::task_condition`](macro@task_condition)
1136/// * [`pallet::task_weight`](macro@task_weight)
1137/// * [`pallet::task_index`](macro@task_index)
1138///
1139/// All of such Tasks are then aggregated into a `RuntimeTask` by
1140/// [`construct_runtime`](macro@construct_runtime).
1141///
1142/// Finally, the `RuntimeTask` can then used by a script or off-chain worker to create and
1143/// submit such tasks via an extrinsic defined in `frame_system` called `do_task`.
1144///
1145/// When submitted as unsigned transactions (for example via an off-chain workder), note
1146/// that the tasks will be executed in a random order.
1147///
1148/// ## Example
1149#[doc = docify::embed!("examples/proc_main/tasks.rs", tasks_example)]
1150/// Now, this can be executed as follows:
1151#[doc = docify::embed!("examples/proc_main/tasks.rs", tasks_work)]
1152#[proc_macro_attribute]
1153pub fn tasks_experimental(_: TokenStream, _: TokenStream) -> TokenStream {
1154	pallet_macro_stub()
1155}
1156
1157/// Allows defining an iterator over available work items for a task.
1158///
1159/// This attribute is attached to a function inside an `impl` block annotated with
1160/// [`pallet::tasks_experimental`](macro@tasks_experimental).
1161///
1162/// It takes an iterator as input that yields a tuple with same types as the function
1163/// arguments.
1164#[proc_macro_attribute]
1165pub fn task_list(_: TokenStream, _: TokenStream) -> TokenStream {
1166	pallet_macro_stub()
1167}
1168
1169/// Allows defining conditions for a task to run.
1170///
1171/// This attribute is attached to a function inside an `impl` block annotated with
1172/// [`pallet::tasks_experimental`](macro@tasks_experimental) to define the conditions for a
1173/// given work item to be valid.
1174///
1175/// It takes a closure as input, which is then used to define the condition. The closure
1176/// should have the same signature as the function it is attached to, except that it should
1177/// return a `bool` instead.
1178#[proc_macro_attribute]
1179pub fn task_condition(_: TokenStream, _: TokenStream) -> TokenStream {
1180	pallet_macro_stub()
1181}
1182
1183/// Allows defining the weight of a task.
1184///
1185/// This attribute is attached to a function inside an `impl` block annotated with
1186/// [`pallet::tasks_experimental`](macro@tasks_experimental) define the weight of a given work
1187/// item.
1188///
1189/// It takes a closure as input, which should return a `Weight` value.
1190#[proc_macro_attribute]
1191pub fn task_weight(_: TokenStream, _: TokenStream) -> TokenStream {
1192	pallet_macro_stub()
1193}
1194
1195/// Allows defining an index for a task.
1196///
1197/// This attribute is attached to a function inside an `impl` block annotated with
1198/// [`pallet::tasks_experimental`](macro@tasks_experimental) to define the index of a given
1199/// work item.
1200///
1201/// It takes an integer literal as input, which is then used to define the index. This
1202/// index should be unique for each function in the `impl` block.
1203#[proc_macro_attribute]
1204pub fn task_index(_: TokenStream, _: TokenStream) -> TokenStream {
1205	pallet_macro_stub()
1206}
1207
1208///
1209/// ---
1210///
1211/// **Rust-Analyzer users**: See the documentation of the Rust item in
1212/// `frame_support::pallet_macros::pallet_section`.
1213#[proc_macro_attribute]
1214pub fn pallet_section(attr: TokenStream, tokens: TokenStream) -> TokenStream {
1215	let tokens_clone = tokens.clone();
1216	// ensure this can only be attached to a module
1217	let _mod = parse_macro_input!(tokens_clone as ItemMod);
1218
1219	// use macro_magic's export_tokens as the internal implementation otherwise
1220	match macro_magic::mm_core::export_tokens_internal(attr, tokens, false, true) {
1221		Ok(tokens) => tokens.into(),
1222		Err(err) => err.to_compile_error().into(),
1223	}
1224}
1225
1226///
1227/// ---
1228///
1229/// **Rust-Analyzer users**: See the documentation of the Rust item in
1230/// `frame_support::pallet_macros::import_section`.
1231#[import_tokens_attr {
1232    format!(
1233        "{}::macro_magic",
1234        match generate_access_from_frame_or_crate("frame-support") {
1235            Ok(path) => Ok(path),
1236            Err(_) => generate_access_from_frame_or_crate("polkadot-sdk-frame"),
1237        }
1238        .expect("Failed to find either `frame-support` or `polkadot-sdk-frame` in `Cargo.toml` dependencies.")
1239        .to_token_stream()
1240        .to_string()
1241    )
1242}]
1243#[proc_macro_attribute]
1244pub fn import_section(attr: TokenStream, tokens: TokenStream) -> TokenStream {
1245	let foreign_mod = parse_macro_input!(attr as ItemMod);
1246	let mut internal_mod = parse_macro_input!(tokens as ItemMod);
1247
1248	// check that internal_mod is a pallet module
1249	if !internal_mod.attrs.iter().any(|attr| {
1250		if let Some(last_seg) = attr.path().segments.last() {
1251			last_seg.ident == "pallet"
1252		} else {
1253			false
1254		}
1255	}) {
1256		return Error::new(
1257			internal_mod.ident.span(),
1258			"`#[import_section]` can only be applied to a valid pallet module",
1259		)
1260		.to_compile_error()
1261		.into();
1262	}
1263
1264	if let Some(ref mut content) = internal_mod.content {
1265		if let Some(foreign_content) = foreign_mod.content {
1266			content.1.extend(foreign_content.1);
1267		}
1268	}
1269
1270	quote! {
1271		#internal_mod
1272	}
1273	.into()
1274}
1275
1276/// Construct a runtime, with the given name and the given pallets.
1277///
1278/// # Example:
1279#[doc = docify::embed!("examples/proc_main/runtime.rs", runtime_macro)]
1280///
1281/// # Supported Attributes:
1282///
1283/// ## Legacy Ordering
1284///
1285/// An optional attribute can be defined as #[frame_support::runtime(legacy_ordering)] to
1286/// ensure that the order of hooks is same as the order of pallets (and not based on the
1287/// pallet_index). This is to support legacy runtimes and should be avoided for new ones.
1288///
1289/// # Note
1290///
1291/// The population of the genesis storage depends on the order of pallets. So, if one of your
1292/// pallets depends on another pallet, the pallet that is depended upon needs to come before
1293/// the pallet depending on it.
1294///
1295/// # Type definitions
1296///
1297/// * The macro generates a type alias for each pallet to their `Pallet`. E.g. `type System =
1298///   frame_system::Pallet<Runtime>`
1299#[proc_macro_attribute]
1300pub fn runtime(attr: TokenStream, item: TokenStream) -> TokenStream {
1301	runtime::runtime(attr, item)
1302}
1303
1304/// Mark a module that contains dynamic parameters.
1305///
1306/// See the `pallet_parameters` for a full example.
1307///
1308/// # Arguments
1309///
1310/// The macro accepts two positional arguments, of which the second is optional.
1311///
1312/// ## Aggregated Enum Name
1313///
1314/// This sets the name that the aggregated Key-Value enum will be named after. Common names would be
1315/// `RuntimeParameters`, akin to `RuntimeCall`, `RuntimeOrigin` etc. There is no default value for
1316/// this argument.
1317///
1318/// ## Parameter Storage Backend
1319///
1320/// The second argument provides access to the storage of the parameters. It can either be set on
1321/// on this attribute, or on the inner ones. If set on both, the inner one takes precedence.
1322#[proc_macro_attribute]
1323pub fn dynamic_params(attrs: TokenStream, input: TokenStream) -> TokenStream {
1324	dynamic_params::dynamic_params(attrs.into(), input.into())
1325		.unwrap_or_else(|r| r.into_compile_error())
1326		.into()
1327}
1328
1329/// Define a module inside a [`macro@dynamic_params`] module that contains dynamic parameters.
1330///
1331/// See the `pallet_parameters` for a full example.
1332///
1333/// # Argument
1334///
1335/// This attribute takes one optional argument. The argument can either be put here or on the
1336/// surrounding `#[dynamic_params]` attribute. If set on both, the inner one takes precedence.
1337#[proc_macro_attribute]
1338pub fn dynamic_pallet_params(attrs: TokenStream, input: TokenStream) -> TokenStream {
1339	dynamic_params::dynamic_pallet_params(attrs.into(), input.into())
1340		.unwrap_or_else(|r| r.into_compile_error())
1341		.into()
1342}
1343
1344/// Used internally by [`dynamic_params`].
1345#[doc(hidden)]
1346#[proc_macro_attribute]
1347pub fn dynamic_aggregated_params_internal(attrs: TokenStream, input: TokenStream) -> TokenStream {
1348	dynamic_params::dynamic_aggregated_params_internal(attrs.into(), input.into())
1349		.unwrap_or_else(|r| r.into_compile_error())
1350		.into()
1351}