From 4a675335a7526d9edcbd5e6b0940c0480119be40 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 2 Feb 2021 15:53:22 +0000 Subject: [PATCH 1/9] Add crate imports with known names --- derive/Cargo.toml | 1 + derive/src/impl_wrapper.rs | 26 ++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 6530b86e..12d9dc66 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -18,3 +18,4 @@ proc-macro = true quote = "1.0" syn = { version = "1.0", features = ["derive", "visit", "visit-mut"] } proc-macro2 = "1.0" +proc-macro-crate = "0.1.5" diff --git a/derive/src/impl_wrapper.rs b/derive/src/impl_wrapper.rs index 4acf1360..21e3444a 100644 --- a/derive/src/impl_wrapper.rs +++ b/derive/src/impl_wrapper.rs @@ -30,14 +30,32 @@ pub fn wrap( trait_name: &'static str, impl_quote: TokenStream2, ) -> TokenStream2 { - let mut renamed = format!("_IMPL_{}_FOR_", trait_name); - renamed.push_str(ident.to_string().trim_start_matches("r#")); - let dummy_const = Ident::new(&renamed, Span::call_site()); + let include_scale_info = include_crate("scale-info", "_scale_info"); + let include_parity_scale_codec = include_crate("parity_scale_codec", "_scale"); quote! { #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const #dummy_const: () = { + const _: () = { + #include_scale_info + #include_parity_scale_codec + #impl_quote; }; } } + +/// Include a crate under a known alias, to be robust against renamed dependencies. +fn include_crate(name: &str, alias: &str) -> proc_macro2::TokenStream { + // This "hack" is required for the tests. + if Some(std::env::var("CARGO_PKG_NAME")) == name { + quote!( extern crate #name as #alias; ) + } else { + match proc_macro_crate::crate_name(name) { + Ok(crate_name) => { + let ident = Ident::new(&crate_name, Span::call_site()); + quote!( extern crate #ident as #alias; ) + }, + Err(e) => syn::Error::new(Span::call_site(), &e).to_compile_error(), + } + } +} From 531dd5d1dc52a42cd8a4613c4c99b538b981296b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 2 Feb 2021 15:54:47 +0000 Subject: [PATCH 2/9] Use known crate name aliases --- derive/src/lib.rs | 22 +++++++++++----------- derive/src/trait_bounds.rs | 8 ++++---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 016d892b..2c89e3d1 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -85,7 +85,7 @@ fn generate_type(input: TokenStream2) -> Result { let generic_type_ids = ast.generics.type_params().map(|ty| { let ty_ident = &ty.ident; quote! { - ::scale_info::meta_type::<#ty_ident>() + _scale_info::meta_type::<#ty_ident>() } }); @@ -97,12 +97,12 @@ fn generate_type(input: TokenStream2) -> Result { }; let generic_types = ast.generics.type_params(); let type_info_impl = quote! { - impl <#( #generic_types ),*> ::scale_info::TypeInfo for #ident #ty_generics #where_clause { + impl <#( #generic_types ),*> _scale_info::TypeInfo for #ident #ty_generics #where_clause { type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path(::scale_info::Path::new(stringify!(#ident), module_path!())) - .type_params(::scale_info::prelude::vec![ #( #generic_type_ids ),* ]) + fn type_info() -> _scale_info::Type { + _scale_info::Type::builder() + .path(_scale_info::Path::new(stringify!(#ident), module_path!())) + .type_params(_scale_info::prelude::vec![ #( #generic_type_ids ),* ]) .#build_type } } @@ -198,7 +198,7 @@ fn generate_composite_type(data_struct: &DataStruct) -> TokenStream2 { } }; quote! { - composite(::scale_info::build::Fields::#fields) + composite(_scale_info::build::Fields::#fields) } } @@ -228,7 +228,7 @@ fn generate_c_like_enum_def(variants: &VariantList) -> TokenStream2 { }); quote! { variant( - ::scale_info::build::Variants::fieldless() + _scale_info::build::Variants::fieldless() #( #variants )* ) } @@ -257,7 +257,7 @@ fn generate_variant_type(data_enum: &DataEnum) -> TokenStream2 { quote! { .variant( #v_name, - ::scale_info::build::Fields::named() + _scale_info::build::Fields::named() #( #fields)* ) } @@ -267,7 +267,7 @@ fn generate_variant_type(data_enum: &DataEnum) -> TokenStream2 { quote! { .variant( #v_name, - ::scale_info::build::Fields::unnamed() + _scale_info::build::Fields::unnamed() #( #fields)* ) } @@ -281,7 +281,7 @@ fn generate_variant_type(data_enum: &DataEnum) -> TokenStream2 { }); quote! { variant( - ::scale_info::build::Variants::with_fields() + _scale_info::build::Variants::with_fields() #( #variants)* ) } diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index 34228ed3..70d57010 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -57,21 +57,21 @@ pub fn make_where_clause<'a>( if is_compact { where_clause .predicates - .push(parse_quote!(#ty : ::scale::HasCompact)); + .push(parse_quote!(#ty : _scale::HasCompact)); where_clause .predicates - .push(parse_quote!(<#ty as ::scale::HasCompact>::Type : ::scale_info::TypeInfo + 'static)); + .push(parse_quote!(<#ty as _scale::HasCompact>::Type : _scale_info::TypeInfo + 'static)); } else { where_clause .predicates - .push(parse_quote!(#ty : ::scale_info::TypeInfo + 'static)); + .push(parse_quote!(#ty : _scale_info::TypeInfo + 'static)); } }); generics.type_params().into_iter().for_each(|type_param| { let ident = type_param.ident.clone(); let mut bounds = type_param.bounds.clone(); - bounds.push(parse_quote!(::scale_info::TypeInfo)); + bounds.push(parse_quote!(_scale_info::TypeInfo)); bounds.push(parse_quote!('static)); where_clause .predicates From 459e29b2a785a54e173d5cbcba1abea5551afa08 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 2 Feb 2021 16:02:20 +0000 Subject: [PATCH 3/9] Remove hack for tests, it doesn't apply to all crates --- derive/src/impl_wrapper.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/derive/src/impl_wrapper.rs b/derive/src/impl_wrapper.rs index 21e3444a..2bd3133b 100644 --- a/derive/src/impl_wrapper.rs +++ b/derive/src/impl_wrapper.rs @@ -46,16 +46,11 @@ pub fn wrap( /// Include a crate under a known alias, to be robust against renamed dependencies. fn include_crate(name: &str, alias: &str) -> proc_macro2::TokenStream { - // This "hack" is required for the tests. - if Some(std::env::var("CARGO_PKG_NAME")) == name { - quote!( extern crate #name as #alias; ) - } else { - match proc_macro_crate::crate_name(name) { - Ok(crate_name) => { - let ident = Ident::new(&crate_name, Span::call_site()); - quote!( extern crate #ident as #alias; ) - }, - Err(e) => syn::Error::new(Span::call_site(), &e).to_compile_error(), - } + match proc_macro_crate::crate_name(name) { + Ok(crate_name) => { + let ident = Ident::new(&crate_name, Span::call_site()); + quote!( extern crate #ident as #alias; ) + }, + Err(e) => syn::Error::new(Span::call_site(), &e).to_compile_error(), } } From 63f8f494337bf19dea8be836a895600a14a3fd7d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 2 Feb 2021 16:05:56 +0000 Subject: [PATCH 4/9] Use alias ident --- derive/src/impl_wrapper.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/derive/src/impl_wrapper.rs b/derive/src/impl_wrapper.rs index 2bd3133b..117d377b 100644 --- a/derive/src/impl_wrapper.rs +++ b/derive/src/impl_wrapper.rs @@ -48,8 +48,9 @@ pub fn wrap( fn include_crate(name: &str, alias: &str) -> proc_macro2::TokenStream { match proc_macro_crate::crate_name(name) { Ok(crate_name) => { - let ident = Ident::new(&crate_name, Span::call_site()); - quote!( extern crate #ident as #alias; ) + let crate_name_ident = Ident::new(&crate_name, Span::call_site()); + let crate_alias_ident = Ident::new(&alias, Span::call_site()); + quote!( extern crate #crate_name_ident as #crate_alias_ident; ) }, Err(e) => syn::Error::new(Span::call_site(), &e).to_compile_error(), } From 159f626b3ef53a384dd191d864c1e60dab220940 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 2 Feb 2021 16:35:39 +0000 Subject: [PATCH 5/9] Fix parity_scale_codec crate alias, remove unused imports and args --- derive/src/impl_wrapper.rs | 10 +--------- derive/src/lib.rs | 2 +- test_suite/tests/derive.rs | 5 +---- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/derive/src/impl_wrapper.rs b/derive/src/impl_wrapper.rs index 117d377b..b7bbbe61 100644 --- a/derive/src/impl_wrapper.rs +++ b/derive/src/impl_wrapper.rs @@ -12,12 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[cfg(not(feature = "std"))] -use alloc::{ - format, - string::ToString, -}; - use proc_macro2::{ Span, TokenStream as TokenStream2, @@ -26,12 +20,10 @@ use quote::quote; use syn::Ident; pub fn wrap( - ident: &Ident, - trait_name: &'static str, impl_quote: TokenStream2, ) -> TokenStream2 { let include_scale_info = include_crate("scale-info", "_scale_info"); - let include_parity_scale_codec = include_crate("parity_scale_codec", "_scale"); + let include_parity_scale_codec = include_crate("parity-scale-codec", "_scale"); quote! { #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 2c89e3d1..54e40c65 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -108,7 +108,7 @@ fn generate_type(input: TokenStream2) -> Result { } }; - Ok(impl_wrapper::wrap(ident, "TYPE_INFO", type_info_impl)) + Ok(impl_wrapper::wrap(type_info_impl)) } type FieldsList = Punctuated; diff --git a/test_suite/tests/derive.rs b/test_suite/tests/derive.rs index 4e5016ed..41be707c 100644 --- a/test_suite/tests/derive.rs +++ b/test_suite/tests/derive.rs @@ -15,10 +15,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use pretty_assertions::assert_eq; -use scale::{ - Compact, - Encode, -}; +use scale::Encode; use scale_info::{ build::*, prelude::{ From c3cadc6994b297b703e7586430f97920afcf5279 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 2 Feb 2021 16:41:39 +0000 Subject: [PATCH 6/9] Fmt --- derive/src/impl_wrapper.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/derive/src/impl_wrapper.rs b/derive/src/impl_wrapper.rs index b7bbbe61..05123ea1 100644 --- a/derive/src/impl_wrapper.rs +++ b/derive/src/impl_wrapper.rs @@ -19,9 +19,7 @@ use proc_macro2::{ use quote::quote; use syn::Ident; -pub fn wrap( - impl_quote: TokenStream2, -) -> TokenStream2 { +pub fn wrap(impl_quote: TokenStream2) -> TokenStream2 { let include_scale_info = include_crate("scale-info", "_scale_info"); let include_parity_scale_codec = include_crate("parity-scale-codec", "_scale"); @@ -43,7 +41,7 @@ fn include_crate(name: &str, alias: &str) -> proc_macro2::TokenStream { let crate_name_ident = Ident::new(&crate_name, Span::call_site()); let crate_alias_ident = Ident::new(&alias, Span::call_site()); quote!( extern crate #crate_name_ident as #crate_alias_ident; ) - }, + } Err(e) => syn::Error::new(Span::call_site(), &e).to_compile_error(), } } From 38ef7df910a50e52dfe93951a46cb29282db4a40 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 2 Feb 2021 16:42:02 +0000 Subject: [PATCH 7/9] Add PR to "Unreleased" section --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bff563db..c2b015c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +### Changed + +### Fixed +- Derive: use known crate name aliases [(#61)](https://github.com/paritytech/scale-info/pull/61) ## [0.5.0] - 2021-01-27 ### Added From 9ab7c5174fba978cd350fc73d4c9cf2146143e3b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 2 Feb 2021 16:54:12 +0000 Subject: [PATCH 8/9] Update rustfmt config --- .rustfmt.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rustfmt.toml b/.rustfmt.toml index da09889f..60f56501 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -19,7 +19,7 @@ fn_single_line = false where_single_line = false imports_indent = "Block" imports_layout = "Vertical" # changed -merge_imports = true # changed +imports_granularity = "Crate" # changed reorder_imports = true reorder_modules = true reorder_impl_items = false From b292cc90c2af38984e2af9e8c09b87aa9ddc575a Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 2 Feb 2021 17:29:44 +0000 Subject: [PATCH 9/9] review: use absolute paths with crate names --- derive/src/impl_wrapper.rs | 47 --------------------------- derive/src/lib.rs | 66 ++++++++++++++++++++++++++------------ derive/src/trait_bounds.rs | 10 +++--- 3 files changed, 51 insertions(+), 72 deletions(-) delete mode 100644 derive/src/impl_wrapper.rs diff --git a/derive/src/impl_wrapper.rs b/derive/src/impl_wrapper.rs deleted file mode 100644 index 05123ea1..00000000 --- a/derive/src/impl_wrapper.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// -// 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 proc_macro2::{ - Span, - TokenStream as TokenStream2, -}; -use quote::quote; -use syn::Ident; - -pub fn wrap(impl_quote: TokenStream2) -> TokenStream2 { - let include_scale_info = include_crate("scale-info", "_scale_info"); - let include_parity_scale_codec = include_crate("parity-scale-codec", "_scale"); - - quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #include_scale_info - #include_parity_scale_codec - - #impl_quote; - }; - } -} - -/// Include a crate under a known alias, to be robust against renamed dependencies. -fn include_crate(name: &str, alias: &str) -> proc_macro2::TokenStream { - match proc_macro_crate::crate_name(name) { - Ok(crate_name) => { - let crate_name_ident = Ident::new(&crate_name, Span::call_site()); - let crate_alias_ident = Ident::new(&alias, Span::call_site()); - quote!( extern crate #crate_name_ident as #crate_alias_ident; ) - } - Err(e) => syn::Error::new(Span::call_site(), &e).to_compile_error(), - } -} diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 54e40c65..7ba60a7e 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -17,7 +17,6 @@ extern crate alloc; extern crate proc_macro; -mod impl_wrapper; mod trait_bounds; use alloc::{ @@ -28,7 +27,10 @@ use alloc::{ vec::Vec, }; use proc_macro::TokenStream; -use proc_macro2::TokenStream as TokenStream2; +use proc_macro2::{ + Span, + TokenStream as TokenStream2, +}; use quote::quote; use syn::{ parse::{ @@ -48,6 +50,7 @@ use syn::{ ExprLit, Field, Fields, + Ident, Lifetime, Lit, Meta, @@ -73,6 +76,9 @@ fn generate(input: TokenStream2) -> Result { fn generate_type(input: TokenStream2) -> Result { let mut ast: DeriveInput = syn::parse2(input.clone())?; + let scale_info = crate_name_ident("scale-info")?; + let parity_scale_codec = crate_name_ident("parity-scale-codec")?; + let ident = &ast.ident; ast.generics @@ -80,35 +86,53 @@ fn generate_type(input: TokenStream2) -> Result { .for_each(|l| *l = parse_quote!('static)); let (_, ty_generics, _) = ast.generics.split_for_impl(); - let where_clause = trait_bounds::make_where_clause(ident, &ast.generics, &ast.data)?; + let where_clause = trait_bounds::make_where_clause( + ident, + &ast.generics, + &ast.data, + &scale_info, + &parity_scale_codec, + )?; let generic_type_ids = ast.generics.type_params().map(|ty| { let ty_ident = &ty.ident; quote! { - _scale_info::meta_type::<#ty_ident>() + :: #scale_info ::meta_type::<#ty_ident>() } }); let ast: DeriveInput = syn::parse2(input.clone())?; let build_type = match &ast.data { - Data::Struct(ref s) => generate_composite_type(s), - Data::Enum(ref e) => generate_variant_type(e), + Data::Struct(ref s) => generate_composite_type(s, &scale_info), + Data::Enum(ref e) => generate_variant_type(e, &scale_info), Data::Union(_) => return Err(Error::new_spanned(input, "Unions not supported")), }; let generic_types = ast.generics.type_params(); let type_info_impl = quote! { - impl <#( #generic_types ),*> _scale_info::TypeInfo for #ident #ty_generics #where_clause { + impl <#( #generic_types ),*> :: #scale_info ::TypeInfo for #ident #ty_generics #where_clause { type Identity = Self; - fn type_info() -> _scale_info::Type { - _scale_info::Type::builder() - .path(_scale_info::Path::new(stringify!(#ident), module_path!())) - .type_params(_scale_info::prelude::vec![ #( #generic_type_ids ),* ]) + fn type_info() -> :: #scale_info ::Type { + :: #scale_info ::Type::builder() + .path(:: #scale_info ::Path::new(stringify!(#ident), module_path!())) + .type_params(:: #scale_info ::prelude::vec![ #( #generic_type_ids ),* ]) .#build_type } } }; - Ok(impl_wrapper::wrap(type_info_impl)) + Ok(quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #type_info_impl; + }; + }) +} + +/// Get the name of a crate, to be robust against renamed dependencies. +fn crate_name_ident(name: &str) -> Result { + proc_macro_crate::crate_name(name) + .map(|crate_name| Ident::new(&crate_name, Span::call_site())) + .map_err(|e| syn::Error::new(Span::call_site(), &e)) } type FieldsList = Punctuated; @@ -181,7 +205,7 @@ fn clean_type_string(input: &str) -> String { .replace("& \'", "&'") } -fn generate_composite_type(data_struct: &DataStruct) -> TokenStream2 { +fn generate_composite_type(data_struct: &DataStruct, scale_info: &Ident) -> TokenStream2 { let fields = match data_struct.fields { Fields::Named(ref fs) => { let fields = generate_fields(&fs.named); @@ -198,13 +222,13 @@ fn generate_composite_type(data_struct: &DataStruct) -> TokenStream2 { } }; quote! { - composite(_scale_info::build::Fields::#fields) + composite(:: #scale_info ::build::Fields::#fields) } } type VariantList = Punctuated; -fn generate_c_like_enum_def(variants: &VariantList) -> TokenStream2 { +fn generate_c_like_enum_def(variants: &VariantList, scale_info: &Ident) -> TokenStream2 { let variants = variants.into_iter().enumerate().map(|(i, v)| { let name = &v.ident; let discriminant = if let Some(( @@ -228,7 +252,7 @@ fn generate_c_like_enum_def(variants: &VariantList) -> TokenStream2 { }); quote! { variant( - _scale_info::build::Variants::fieldless() + :: #scale_info ::build::Variants::fieldless() #( #variants )* ) } @@ -241,11 +265,11 @@ fn is_c_like_enum(variants: &VariantList) -> bool { variants.iter().all(|v| matches!(v.fields, Fields::Unit)) } -fn generate_variant_type(data_enum: &DataEnum) -> TokenStream2 { +fn generate_variant_type(data_enum: &DataEnum, scale_info: &Ident) -> TokenStream2 { let variants = &data_enum.variants; if is_c_like_enum(&variants) { - return generate_c_like_enum_def(variants) + return generate_c_like_enum_def(variants, scale_info) } let variants = variants.into_iter().map(|v| { @@ -257,7 +281,7 @@ fn generate_variant_type(data_enum: &DataEnum) -> TokenStream2 { quote! { .variant( #v_name, - _scale_info::build::Fields::named() + :: #scale_info ::build::Fields::named() #( #fields)* ) } @@ -267,7 +291,7 @@ fn generate_variant_type(data_enum: &DataEnum) -> TokenStream2 { quote! { .variant( #v_name, - _scale_info::build::Fields::unnamed() + :: #scale_info ::build::Fields::unnamed() #( #fields)* ) } @@ -281,7 +305,7 @@ fn generate_variant_type(data_enum: &DataEnum) -> TokenStream2 { }); quote! { variant( - _scale_info::build::Variants::with_fields() + :: #scale_info ::build::Variants::with_fields() #( #variants)* ) } diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index 70d57010..8a64dd85 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -32,6 +32,8 @@ pub fn make_where_clause<'a>( input_ident: &'a Ident, generics: &'a Generics, data: &'a syn::Data, + scale_info: &Ident, + parity_scale_codec: &Ident, ) -> Result { let mut where_clause = generics.where_clause.clone().unwrap_or_else(|| { WhereClause { @@ -57,21 +59,21 @@ pub fn make_where_clause<'a>( if is_compact { where_clause .predicates - .push(parse_quote!(#ty : _scale::HasCompact)); + .push(parse_quote!(#ty : :: #parity_scale_codec ::HasCompact)); where_clause .predicates - .push(parse_quote!(<#ty as _scale::HasCompact>::Type : _scale_info::TypeInfo + 'static)); + .push(parse_quote!(<#ty as :: #parity_scale_codec ::HasCompact>::Type : :: #scale_info ::TypeInfo + 'static)); } else { where_clause .predicates - .push(parse_quote!(#ty : _scale_info::TypeInfo + 'static)); + .push(parse_quote!(#ty : :: #scale_info ::TypeInfo + 'static)); } }); generics.type_params().into_iter().for_each(|type_param| { let ident = type_param.ident.clone(); let mut bounds = type_param.bounds.clone(); - bounds.push(parse_quote!(_scale_info::TypeInfo)); + bounds.push(parse_quote!(:: #scale_info ::TypeInfo)); bounds.push(parse_quote!('static)); where_clause .predicates