Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 254bc43

Browse files
KiChjanggui1117
andauthored
Emit error when Config part is imported but without the std feature (#9225)
* Emit error when Config part is imported but without the std feature * Add UI test for missing std feature on GenesisConfig * Update frame/support/test/Cargo.toml Co-authored-by: Guillaume Thiolliere <[email protected]> * Remove unused imports * Unify all dummy party checker macros * Fix * Dispaly pallet_path::GenesisConfig instead of PalletConfig in error message * Revert changes to construct_runtime_ui.rs * Add additional parameter for dummy part checker macro * Apply suggestions from code review * fix master merge: update version * update Cargo.lock Co-authored-by: Guillaume Thiolliere <[email protected]>
1 parent fe663ed commit 254bc43

File tree

9 files changed

+269
-90
lines changed

9 files changed

+269
-90
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frame/support/procedural/src/construct_runtime/expand/config.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
use crate::construct_runtime::Pallet;
1919
use inflector::Inflector;
2020
use proc_macro2::TokenStream;
21-
use quote::{format_ident, quote};
21+
use quote::{ToTokens, format_ident, quote};
2222
use syn::Ident;
2323

2424
pub fn expand_outer_config(
@@ -35,6 +35,7 @@ pub fn expand_outer_config(
3535
if let Some(pallet_entry) = decl.find_part("Config") {
3636
let path = &decl.path;
3737
let pallet_name = &decl.name;
38+
let path_str = path.into_token_stream().to_string();
3839
let config = format_ident!("{}Config", pallet_name);
3940
let field_name = &Ident::new(
4041
&pallet_name.to_string().to_snake_case(),
@@ -47,6 +48,8 @@ pub fn expand_outer_config(
4748
build_storage_calls.extend(expand_config_build_storage_call(scrate, runtime, decl, &field_name));
4849
query_genesis_config_part_macros.push(quote! {
4950
#path::__substrate_genesis_config_check::is_genesis_config_defined!(#pallet_name);
51+
#[cfg(feature = "std")]
52+
#path::__substrate_genesis_config_check::is_std_enabled_for_genesis!(#pallet_name, #path_str);
5053
});
5154
}
5255
}

frame/support/procedural/src/dummy_part_checker.rs

Lines changed: 15 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,96 +9,54 @@ pub fn generate_dummy_part_checker(input: TokenStream) -> TokenStream {
99

1010
let count = COUNTER.with(|counter| counter.borrow_mut().inc());
1111

12-
let genesis_config_macro_ident = syn::Ident::new(
13-
&format!("__is_genesis_config_defined_{}", count),
14-
proc_macro2::Span::call_site(),
15-
);
16-
let event_macro_ident = syn::Ident::new(
17-
&format!("__is_event_part_defined_{}", count),
18-
proc_macro2::Span::call_site(),
19-
);
20-
let inherent_macro_ident = syn::Ident::new(
21-
&format!("__is_inherent_part_defined_{}", count),
22-
proc_macro2::Span::call_site(),
23-
);
24-
let validate_unsigned_macro_ident = syn::Ident::new(
25-
&format!("__is_validate_unsigned_part_defined_{}", count),
26-
proc_macro2::Span::call_site(),
27-
);
28-
let call_macro_ident = syn::Ident::new(
29-
&format!("__is_call_part_defined_{}", count),
30-
proc_macro2::Span::call_site(),
31-
);
32-
let origin_macro_ident = syn::Ident::new(
33-
&format!("__is_origin_part_defined_{}", count),
12+
let no_op_macro_ident = syn::Ident::new(
13+
&format!("__dummy_part_checker_{}", count),
3414
proc_macro2::Span::call_site(),
3515
);
3616

3717
quote::quote!(
18+
#[macro_export]
19+
#[doc(hidden)]
20+
macro_rules! #no_op_macro_ident {
21+
( $( $tt:tt )* ) => {};
22+
}
23+
3824
#[doc(hidden)]
3925
pub mod __substrate_genesis_config_check {
40-
#[macro_export]
4126
#[doc(hidden)]
42-
macro_rules! #genesis_config_macro_ident {
43-
($pallet_name:ident) => {};
44-
}
27+
pub use #no_op_macro_ident as is_genesis_config_defined;
4528
#[doc(hidden)]
46-
pub use #genesis_config_macro_ident as is_genesis_config_defined;
29+
pub use #no_op_macro_ident as is_std_enabled_for_genesis;
4730
}
4831

4932
#[doc(hidden)]
5033
pub mod __substrate_event_check {
51-
#[macro_export]
52-
#[doc(hidden)]
53-
macro_rules! #event_macro_ident {
54-
($pallet_name:ident) => {};
55-
}
5634
#[doc(hidden)]
57-
pub use #event_macro_ident as is_event_part_defined;
35+
pub use #no_op_macro_ident as is_event_part_defined;
5836
}
5937

6038
#[doc(hidden)]
6139
pub mod __substrate_inherent_check {
62-
#[macro_export]
6340
#[doc(hidden)]
64-
macro_rules! #inherent_macro_ident {
65-
($pallet_name:ident) => {};
66-
}
67-
#[doc(hidden)]
68-
pub use #inherent_macro_ident as is_inherent_part_defined;
41+
pub use #no_op_macro_ident as is_inherent_part_defined;
6942
}
7043

7144
#[doc(hidden)]
7245
pub mod __substrate_validate_unsigned_check {
73-
#[macro_export]
74-
#[doc(hidden)]
75-
macro_rules! #validate_unsigned_macro_ident {
76-
($pallet_name:ident) => {};
77-
}
7846
#[doc(hidden)]
79-
pub use #validate_unsigned_macro_ident as is_validate_unsigned_part_defined;
47+
pub use #no_op_macro_ident as is_validate_unsigned_part_defined;
8048
}
8149

8250
#[doc(hidden)]
8351
pub mod __substrate_call_check {
84-
#[macro_export]
8552
#[doc(hidden)]
86-
macro_rules! #call_macro_ident {
87-
($pallet_name:ident) => {};
88-
}
89-
#[doc(hidden)]
90-
pub use #call_macro_ident as is_call_part_defined;
53+
pub use #no_op_macro_ident as is_call_part_defined;
9154
}
9255

9356
#[doc(hidden)]
9457
pub mod __substrate_origin_check {
95-
#[macro_export]
96-
#[doc(hidden)]
97-
macro_rules! #origin_macro_ident {
98-
($pallet_name:ident) => {};
99-
}
10058
#[doc(hidden)]
101-
pub use #origin_macro_ident as is_origin_part_defined;
59+
pub use #no_op_macro_ident as is_origin_part_defined;
10260
}
10361
).into()
10462
}

frame/support/procedural/src/pallet/expand/genesis_config.rs

Lines changed: 77 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,60 @@ use syn::{Ident, spanned::Spanned};
2323
pub fn expand_genesis_config(def: &mut Def) -> proc_macro2::TokenStream {
2424
let count = COUNTER.with(|counter| counter.borrow_mut().inc());
2525

26-
let (genesis_config, macro_ident) = if let Some(genesis_config) = &def.genesis_config {
27-
let ident = Ident::new(
28-
&format!("__is_genesis_config_defined_{}", count),
29-
genesis_config.genesis_config.span(),
30-
);
31-
(genesis_config, ident)
32-
} else {
33-
let macro_ident = Ident::new(
34-
&format!("__is_genesis_config_defined_{}", count),
35-
def.item.span(),
36-
);
37-
38-
return quote::quote! {
39-
#[doc(hidden)]
40-
pub mod __substrate_genesis_config_check {
41-
#[macro_export]
26+
let (genesis_config, def_macro_ident, std_macro_ident) =
27+
if let Some(genesis_config) = &def.genesis_config {
28+
let def_macro_ident = Ident::new(
29+
&format!("__is_genesis_config_defined_{}", count),
30+
genesis_config.genesis_config.span(),
31+
);
32+
33+
let std_macro_ident = Ident::new(
34+
&format!("__is_std_macro_defined_for_genesis_{}", count),
35+
genesis_config.genesis_config.span(),
36+
);
37+
38+
(genesis_config, def_macro_ident, std_macro_ident)
39+
} else {
40+
let def_macro_ident = Ident::new(
41+
&format!("__is_genesis_config_defined_{}", count),
42+
def.item.span(),
43+
);
44+
45+
let std_macro_ident = Ident::new(
46+
&format!("__is_std_enabled_for_genesis_{}", count),
47+
def.item.span(),
48+
);
49+
50+
return quote::quote! {
4251
#[doc(hidden)]
43-
macro_rules! #macro_ident {
44-
($pallet_name:ident) => {
45-
compile_error!(concat!(
46-
"`",
47-
stringify!($pallet_name),
48-
"` does not have #[pallet::genesis_config] defined, perhaps you should \
49-
remove `Config` from construct_runtime?",
50-
));
52+
pub mod __substrate_genesis_config_check {
53+
#[macro_export]
54+
#[doc(hidden)]
55+
macro_rules! #def_macro_ident {
56+
($pallet_name:ident) => {
57+
compile_error!(concat!(
58+
"`",
59+
stringify!($pallet_name),
60+
"` does not have #[pallet::genesis_config] defined, perhaps you should \
61+
remove `Config` from construct_runtime?",
62+
));
63+
}
5164
}
65+
66+
#[macro_export]
67+
#[doc(hidden)]
68+
macro_rules! #std_macro_ident {
69+
($pallet_name:ident, $pallet_path:expr) => {};
70+
}
71+
72+
#[doc(hidden)]
73+
pub use #def_macro_ident as is_genesis_config_defined;
74+
#[doc(hidden)]
75+
pub use #std_macro_ident as is_std_enabled_for_genesis;
5276
}
53-
54-
#[doc(hidden)]
55-
pub use #macro_ident as is_genesis_config_defined;
56-
}
77+
};
5778
};
58-
};
79+
5980
let frame_support = &def.frame_support;
6081

6182
let genesis_config_item = &mut def.item.content.as_mut()
@@ -94,12 +115,36 @@ pub fn expand_genesis_config(def: &mut Def) -> proc_macro2::TokenStream {
94115
pub mod __substrate_genesis_config_check {
95116
#[macro_export]
96117
#[doc(hidden)]
97-
macro_rules! #macro_ident {
118+
macro_rules! #def_macro_ident {
98119
($pallet_name:ident) => {};
99120
}
100-
121+
122+
#[cfg(not(feature = "std"))]
123+
#[macro_export]
124+
#[doc(hidden)]
125+
macro_rules! #std_macro_ident {
126+
($pallet_name:ident, $pallet_path:expr) => {
127+
compile_error!(concat!(
128+
"`",
129+
stringify!($pallet_name),
130+
"` does not have the std feature enabled, this will cause the `",
131+
$pallet_path,
132+
"::GenesisConfig` type to be undefined."
133+
));
134+
};
135+
}
136+
137+
#[cfg(feature = "std")]
138+
#[macro_export]
139+
#[doc(hidden)]
140+
macro_rules! #std_macro_ident {
141+
($pallet_name:ident, $pallet_path:expr) => {};
142+
}
143+
144+
#[doc(hidden)]
145+
pub use #def_macro_ident as is_genesis_config_defined;
101146
#[doc(hidden)]
102-
pub use #macro_ident as is_genesis_config_defined;
147+
pub use #std_macro_ident as is_std_enabled_for_genesis;
103148
}
104149
}
105150
}

frame/support/test/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pretty_assertions = "0.6.1"
2525
rustversion = "1.0.0"
2626
frame-metadata = { version = "14.0.0-dev", default-features = false, path = "../../metadata" }
2727
frame-system = { version = "4.0.0-dev", default-features = false, path = "../../system" }
28+
# The "std" feature for this pallet is never activated on purpose, in order to test construct_runtime error message
29+
test-pallet = { package = "frame-support-test-pallet", default-features = false, path = "pallet" }
2830

2931
[features]
3032
default = ["std"]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
name = "frame-support-test-pallet"
3+
version = "4.0.0-dev"
4+
authors = ["Parity Technologies <[email protected]>"]
5+
edition = "2018"
6+
license = "Apache-2.0"
7+
publish = false
8+
homepage = "https://substrate.dev"
9+
repository = "https://github.com/paritytech/substrate/"
10+
11+
[package.metadata.docs.rs]
12+
targets = ["x86_64-unknown-linux-gnu"]
13+
14+
[dependencies]
15+
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
16+
frame-support = { version = "4.0.0-dev", default-features = false, path = "../../" }
17+
frame-system = { version = "4.0.0-dev", default-features = false, path = "../../../system" }
18+
19+
[features]
20+
default = ["std"]
21+
std = [
22+
"codec/std",
23+
"frame-support/std",
24+
"frame-system/std",
25+
]
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) 2021 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+
pub use pallet::*;
18+
19+
#[frame_support::pallet]
20+
pub mod pallet {
21+
#[allow(unused_imports)]
22+
use frame_support::pallet_prelude::*;
23+
#[allow(unused_imports)]
24+
use frame_system::pallet_prelude::*;
25+
26+
#[pallet::pallet]
27+
pub struct Pallet<T>(_);
28+
29+
#[pallet::config]
30+
pub trait Config: frame_system::Config {}
31+
32+
#[pallet::genesis_config]
33+
pub struct GenesisConfig {}
34+
35+
#[cfg(feature = "std")]
36+
impl Default for GenesisConfig {
37+
fn default() -> Self {
38+
Self {}
39+
}
40+
}
41+
42+
#[pallet::genesis_build]
43+
impl<T: Config> GenesisBuild<T> for GenesisConfig {
44+
fn build(&self) {}
45+
}
46+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use frame_support::construct_runtime;
2+
use sp_runtime::{generic, traits::BlakeTwo256};
3+
use sp_core::sr25519;
4+
5+
pub type Signature = sr25519::Signature;
6+
pub type BlockNumber = u64;
7+
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
8+
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
9+
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<u32, Call, Signature, ()>;
10+
11+
impl test_pallet::Config for Runtime {}
12+
13+
construct_runtime! {
14+
pub enum Runtime where
15+
Block = Block,
16+
NodeBlock = Block,
17+
UncheckedExtrinsic = UncheckedExtrinsic
18+
{
19+
System: system::{Pallet, Call, Storage, Config, Event<T>},
20+
Pallet: test_pallet::{Pallet, Config},
21+
}
22+
}
23+
24+
fn main() {}

0 commit comments

Comments
 (0)