From 6f03f7a10182cf43e49623c4312000921856a033 Mon Sep 17 00:00:00 2001 From: Julian Eager Date: Tue, 15 Oct 2024 05:00:57 +0800 Subject: [PATCH] Fix `feeless_if` in pallet section (#6032) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes #5981 Could confirm the issue with the added tests: ``` test tests/split_ui/pass/split_call.rs [should pass] ... error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ error[E0423]: expected value, found attribute macro `origin` --> tests/split_ui/pass/split_call.rs:23:1 | 23 | #[frame_support::pallet(dev_mode)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a value | = note: this error originates in the attribute macro `frame_support::pallet` (in Nightly builds, run with -Z macro-backtrace for more info) ``` # Description `origin` unexpectedly resolved to a macro, which is available at the span of invocation. The solution here is to use the expansion as a function instead of a call and pass in the desired values to avoid ambiguities. --- prdoc/pr_6032.prdoc | 11 ++++ .../procedural/src/pallet/expand/call.rs | 15 ++--- .../test/tests/split_ui/pass/call/mod.rs | 63 +++++++++++++++++++ .../test/tests/split_ui/pass/split_call.rs | 36 +++++++++++ 4 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 prdoc/pr_6032.prdoc create mode 100644 substrate/frame/support/test/tests/split_ui/pass/call/mod.rs create mode 100644 substrate/frame/support/test/tests/split_ui/pass/split_call.rs diff --git a/prdoc/pr_6032.prdoc b/prdoc/pr_6032.prdoc new file mode 100644 index 000000000000..ed47750f8fd7 --- /dev/null +++ b/prdoc/pr_6032.prdoc @@ -0,0 +1,11 @@ +title: Fix `feeless_if` in pallet section + +doc: + - audience: Runtime Dev + description: | + Fix compilation with `pallet::feeless_if` in a pallet section: a local binding unexpectely + resolved to a macro definition. + +crates: + - name: frame-support-procedural + bump: patch diff --git a/substrate/frame/support/procedural/src/pallet/expand/call.rs b/substrate/frame/support/procedural/src/pallet/expand/call.rs index 8b333d19087d..206ffc1159f7 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/call.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/call.rs @@ -253,13 +253,13 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { }) .collect::>(); - let feeless_check = methods.iter().map(|method| &method.feeless_check).collect::>(); - let feeless_check_result = - feeless_check.iter().zip(args_name.iter()).map(|(feeless_check, arg_name)| { - if let Some(feeless_check) = feeless_check { - quote::quote!(#feeless_check(origin, #( #arg_name, )*)) + let feeless_checks = methods.iter().map(|method| &method.feeless_check).collect::>(); + let feeless_check = + feeless_checks.iter().zip(args_name.iter()).map(|(feeless_check, arg_name)| { + if let Some(check) = feeless_check { + quote::quote_spanned!(span => #check) } else { - quote::quote!(false) + quote::quote_spanned!(span => |_origin, #( #arg_name, )*| { false }) } }); @@ -393,7 +393,8 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { #( #cfg_attrs Self::#fn_name { #( #args_name_pattern_ref, )* } => { - #feeless_check_result + let feeless_check = #feeless_check; + feeless_check(origin, #( #args_name, )*) }, )* Self::__Ignore(_, _) => unreachable!("__Ignore cannot be used"), diff --git a/substrate/frame/support/test/tests/split_ui/pass/call/mod.rs b/substrate/frame/support/test/tests/split_ui/pass/call/mod.rs new file mode 100644 index 000000000000..27b3ec31b835 --- /dev/null +++ b/substrate/frame/support/test/tests/split_ui/pass/call/mod.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use frame_support::pallet_macros::pallet_section; + +#[pallet_section] +mod call { + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + pub fn noop0(origin: OriginFor) -> DispatchResult { + ensure_signed(origin)?; + Ok(()) + } + + #[pallet::call_index(1)] + pub fn noop1(origin: OriginFor, _x: u64) -> DispatchResult { + ensure_signed(origin)?; + Ok(()) + } + + #[pallet::call_index(2)] + pub fn noop2(origin: OriginFor, _x: u64, _y: u64) -> DispatchResult { + ensure_signed(origin)?; + Ok(()) + } + + #[pallet::call_index(3)] + #[pallet::feeless_if(|_origin: &OriginFor| -> bool { true })] + pub fn noop_feeless0(origin: OriginFor) -> DispatchResult { + ensure_signed(origin)?; + Ok(()) + } + + #[pallet::call_index(4)] + #[pallet::feeless_if(|_origin: &OriginFor, x: &u64| -> bool { *x == 1 })] + pub fn noop_feeless1(origin: OriginFor, _x: u64) -> DispatchResult { + ensure_signed(origin)?; + Ok(()) + } + + #[pallet::call_index(5)] + #[pallet::feeless_if(|_origin: &OriginFor, x: &u64, y: &u64| -> bool { *x == *y })] + pub fn noop_feeless2(origin: OriginFor, _x: u64, _y: u64) -> DispatchResult { + ensure_signed(origin)?; + Ok(()) + } + } +} diff --git a/substrate/frame/support/test/tests/split_ui/pass/split_call.rs b/substrate/frame/support/test/tests/split_ui/pass/split_call.rs new file mode 100644 index 000000000000..09dbe6e3992d --- /dev/null +++ b/substrate/frame/support/test/tests/split_ui/pass/split_call.rs @@ -0,0 +1,36 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use frame_support::pallet_macros::import_section; + +mod call; + +#[import_section(call::call)] +#[frame_support::pallet(dev_mode)] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config {} +} + +fn main() { +}