From 919b866c0fd14af12e3a6f7b19699a7129a3573c Mon Sep 17 00:00:00 2001 From: James Wilson Date: Thu, 5 Oct 2023 15:16:15 +0200 Subject: [PATCH] fix for when runtime API field name is _ (#1191) * fix for when runtime API field name is _ * add a test * formatting --------- Co-authored-by: Tadeo hepperle --- codegen/src/api/runtime_apis.rs | 10 +++++++-- testing/ui-tests/src/dispatch_errors.rs | 6 ++--- testing/ui-tests/src/lib.rs | 8 +++++++ testing/ui-tests/src/runtime_apis.rs | 29 +++++++++++++++++++++++++ testing/ui-tests/src/utils/mod.rs | 18 +++++++++++---- 5 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 testing/ui-tests/src/runtime_apis.rs diff --git a/codegen/src/api/runtime_apis.rs b/codegen/src/api/runtime_apis.rs index 9c3e548736..bc363a2cf2 100644 --- a/codegen/src/api/runtime_apis.rs +++ b/codegen/src/api/runtime_apis.rs @@ -36,8 +36,14 @@ fn generate_runtime_api( .then_some(quote! { #( #[doc = #docs ] )* }) .unwrap_or_default(); - let inputs: Vec<_> = method.inputs().map(|input| { - let name = format_ident!("{}", &input.name); + let inputs: Vec<_> = method.inputs().enumerate().map(|(idx, input)| { + // These are method names, which can just be '_', but struct field names can't + // just be an underscore, so fix any such names we find to work in structs. + let name = if input.name == "_" { + format_ident!("_{}", idx) + } else { + format_ident!("{}", &input.name) + }; let ty = type_gen.resolve_type_path(input.ty); let param = quote!(#name: #ty); diff --git a/testing/ui-tests/src/dispatch_errors.rs b/testing/ui-tests/src/dispatch_errors.rs index 81ac746d6f..fea8699402 100644 --- a/testing/ui-tests/src/dispatch_errors.rs +++ b/testing/ui-tests/src/dispatch_errors.rs @@ -11,13 +11,13 @@ use generate_custom_metadata::dispatch_error::{ use frame_metadata::RuntimeMetadataPrefixed; pub fn metadata_array_dispatch_error() -> RuntimeMetadataPrefixed { - generate_metadata_from_pallets_custom_dispatch_error::(vec![]) + generate_metadata_from_pallets_custom_dispatch_error::(vec![], vec![]) } pub fn metadata_legacy_dispatch_error() -> RuntimeMetadataPrefixed { - generate_metadata_from_pallets_custom_dispatch_error::(vec![]) + generate_metadata_from_pallets_custom_dispatch_error::(vec![], vec![]) } pub fn metadata_named_field_dispatch_error() -> RuntimeMetadataPrefixed { - generate_metadata_from_pallets_custom_dispatch_error::(vec![]) + generate_metadata_from_pallets_custom_dispatch_error::(vec![], vec![]) } diff --git a/testing/ui-tests/src/lib.rs b/testing/ui-tests/src/lib.rs index 9476e78a35..06522ff9b0 100644 --- a/testing/ui-tests/src/lib.rs +++ b/testing/ui-tests/src/lib.rs @@ -12,6 +12,7 @@ //! to automatically regenerate `stderr` files, but don't forget to check that new files make sense. mod dispatch_errors; +mod runtime_apis; mod storage; mod utils; @@ -34,6 +35,13 @@ fn ui_tests() { .build(storage::metadata_storage_map_no_keys()), ); + // Check runtime APIs with _ in method names work + t.pass( + m.new_test_case() + .name("runtime_api_underscore_method_name") + .build(runtime_apis::metadata_runtime_api_underscore_method_name()), + ); + // Test that the codegen can handle the different types of DispatchError. t.pass( m.new_test_case() diff --git a/testing/ui-tests/src/runtime_apis.rs b/testing/ui-tests/src/runtime_apis.rs new file mode 100644 index 0000000000..fc16d9e14c --- /dev/null +++ b/testing/ui-tests/src/runtime_apis.rs @@ -0,0 +1,29 @@ +// Copyright 2019-2023 Parity Technologies (UK) Ltd. +// This file is dual-licensed as Apache-2.0 or GPL-3.0. +// see LICENSE for license details. + +use frame_metadata::{ + v15::{RuntimeApiMetadata, RuntimeApiMethodMetadata, RuntimeApiMethodParamMetadata}, + RuntimeMetadataPrefixed, +}; + +use crate::utils::generate_metadata_from_runtime_apis; + +/// Generate metadata which contains a `Map` storage entry with no hashers/values. +/// This is a bit of an odd case, but it was raised in https://github.com/paritytech/subxt/issues/552, +/// and this test will fail before the fix and should pass once the fix is applied. +pub fn metadata_runtime_api_underscore_method_name() -> RuntimeMetadataPrefixed { + generate_metadata_from_runtime_apis(vec![RuntimeApiMetadata { + name: "MyApi".to_owned(), + docs: vec![], + methods: vec![RuntimeApiMethodMetadata { + name: "my_method".to_owned(), + inputs: vec![RuntimeApiMethodParamMetadata { + name: "_".to_owned(), // The important bit we're testing. + ty: 0.into(), // we don't care what type this is. + }], + output: 0.into(), // we don't care what type this is. + docs: vec![], + }], + }]) +} diff --git a/testing/ui-tests/src/utils/mod.rs b/testing/ui-tests/src/utils/mod.rs index e59b48d2d3..4bf0fa65c2 100644 --- a/testing/ui-tests/src/utils/mod.rs +++ b/testing/ui-tests/src/utils/mod.rs @@ -7,12 +7,12 @@ mod metadata_test_runner; use frame_metadata::{ v15::{ CustomMetadata, ExtrinsicMetadata, OuterEnums, PalletMetadata, PalletStorageMetadata, - RuntimeMetadataV15, StorageEntryMetadata, + RuntimeApiMetadata, RuntimeMetadataV15, StorageEntryMetadata, }, RuntimeMetadataPrefixed, }; use generate_custom_metadata::dispatch_error::ArrayDispatchError; -use scale_info::{meta_type, IntoPortable, TypeInfo}; +use scale_info::{form::PortableForm, meta_type, IntoPortable, TypeInfo}; pub use metadata_test_runner::MetadataTestRunner; @@ -21,6 +21,7 @@ pub use metadata_test_runner::MetadataTestRunner; /// type matching the generic type param provided. pub fn generate_metadata_from_pallets_custom_dispatch_error( pallets: Vec, + runtime_apis: Vec>, ) -> RuntimeMetadataPrefixed { // We don't care about the extrinsic type. let extrinsic = ExtrinsicMetadata { @@ -60,7 +61,7 @@ pub fn generate_metadata_from_pallets_custom_dispatch_error) -> RuntimeMetadataPrefixed { - generate_metadata_from_pallets_custom_dispatch_error::(pallets) + generate_metadata_from_pallets_custom_dispatch_error::(pallets, vec![]) +} + +/// Given some runtime API metadata, generate a [`RuntimeMetadataPrefixed`] struct. +/// We default to a useless extrinsic type, and register a fake `DispatchError` +/// type so that codegen is happy with the metadata generated. +pub fn generate_metadata_from_runtime_apis( + runtime_apis: Vec>, +) -> RuntimeMetadataPrefixed { + generate_metadata_from_pallets_custom_dispatch_error::(vec![], runtime_apis) } /// Given some storage entries, generate a [`RuntimeMetadataPrefixed`] struct.