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 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 diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 6530b86e..c42f56bd 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -18,3 +18,5 @@ 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" +once_cell = "1.5" diff --git a/derive/src/impl_wrapper.rs b/derive/src/impl_wrapper.rs deleted file mode 100644 index 4acf1360..00000000 --- a/derive/src/impl_wrapper.rs +++ /dev/null @@ -1,43 +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. - -#[cfg(not(feature = "std"))] -use alloc::{ - format, - string::ToString, -}; - -use proc_macro2::{ - Span, - TokenStream as TokenStream2, -}; -use quote::quote; -use syn::Ident; - -pub fn wrap( - ident: &Ident, - 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()); - - quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const #dummy_const: () = { - #impl_quote; - }; - } -} diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 016d892b..52bcf98b 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, @@ -56,6 +59,26 @@ use syn::{ Variant, }; +use once_cell::sync::Lazy; + +struct IdentHelper(Lazy); + +impl quote::ToTokens for IdentHelper { + fn to_tokens(&self, tokens: &mut TokenStream2) { + Ident::new(&self.0, Span::call_site()).to_tokens(tokens) + } +} +/// Get the name of the scale-info crate, to be robust against renamed dependencies. +static SCALE_INFO: IdentHelper = IdentHelper(Lazy::new(|| { + proc_macro_crate::crate_name("scale-info") + .expect("Missing scale-info dependency. Please add it to your Cargo.toml") +})); +/// Get the name of the parity-scale-codec crate, to be robust against renamed dependencies. +static CODEC: IdentHelper = IdentHelper(Lazy::new(|| { + proc_macro_crate::crate_name("parity-scale-codec") + .expect("Missing parity-scale-codec dependency. Please add it to your Cargo.toml") +})); + #[proc_macro_derive(TypeInfo)] pub fn type_info(input: TokenStream) -> TokenStream { match generate(input.into()) { @@ -85,7 +108,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,18 +120,23 @@ 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 } } }; - Ok(impl_wrapper::wrap(ident, "TYPE_INFO", type_info_impl)) + Ok(quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #type_info_impl; + }; + }) } type FieldsList = Punctuated; @@ -198,7 +226,7 @@ fn generate_composite_type(data_struct: &DataStruct) -> TokenStream2 { } }; quote! { - composite(::scale_info::build::Fields::#fields) + composite(:: #SCALE_INFO ::build::Fields::#fields) } } @@ -228,7 +256,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 +285,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 +295,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 +309,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..ef039093 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -12,6 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +use super::{ + CODEC, + SCALE_INFO, +}; use alloc::vec::Vec; use proc_macro2::Ident; use syn::{ @@ -57,21 +61,21 @@ pub fn make_where_clause<'a>( if is_compact { where_clause .predicates - .push(parse_quote!(#ty : ::scale::HasCompact)); + .push(parse_quote!(#ty : :: #CODEC ::HasCompact)); where_clause .predicates - .push(parse_quote!(<#ty as ::scale::HasCompact>::Type : ::scale_info::TypeInfo + 'static)); + .push(parse_quote!(<#ty as :: #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 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::{