--- a/crates/evm-coder/procedural/src/solidity_interface.rs +++ b/crates/evm-coder/procedural/src/solidity_interface.rs @@ -721,7 +721,7 @@ for arg in self.args.iter().filter(|a| !a.is_special()) { has_params = true; let ty = &arg.ty; - args.extend(quote! {nameof(#ty)}); + args.extend(quote! {nameof(<#ty>::SIGNATURE)}); args.extend(quote! {fixed(",")}) } --- a/crates/evm-coder/src/abi.rs +++ b/crates/evm-coder/src/abi.rs @@ -428,7 +428,7 @@ } impl Signature for Vec { - const SIGNATURE: SignatureUnit = make_signature!(new nameof(R) fixed("[]")); + const SIGNATURE: SignatureUnit = make_signature!(new nameof(R::SIGNATURE) fixed("[]")); } impl sealed::CanBePlacedInVec for EthCrossAccount {} @@ -524,7 +524,7 @@ { const SIGNATURE: SignatureUnit = make_signature!( new fixed("(") - $(nameof($ident) fixed(","))+ + $(nameof(<$ident>::SIGNATURE) fixed(","))+ shift_left(1) fixed(")") ); --- a/crates/evm-coder/src/custom_signature.rs +++ b/crates/evm-coder/src/custom_signature.rs @@ -9,37 +9,33 @@ //! #### Example //! ``` //! use std::str::from_utf8; -//! use evm_coder::make_signature; -//! use evm_coder::custom_signature::{ -//! SignatureUnit, -//! SIGNATURE_SIZE_LIMIT -//! }; +//! use evm_coder::{custom_signature::SignatureUnit, make_signature}; //! //! // Create trait for our signature //! trait SoliditySignature { -//! const SIGNATURE: SignatureUnit; +//! const SIGNATURE: SignatureUnit; //! -//! fn name() -> &'static str { -//! from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8") -//! } -//! } +//! fn name() -> &'static str { +//! from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8") +//! } +//! } //! //! // Make signatures for some types -//! impl SoliditySignature for u8 { -//! make_signature!(new fixed("uint8")); -//! } -//! impl SoliditySignature for u32 { -//! make_signature!(new fixed("uint32")); -//! } -//! impl SoliditySignature for Vec { -//! make_signature!(new nameof(T) fixed("[]")); -//! } -//! impl SoliditySignature for (A, B) { -//! make_signature!(new fixed("(") nameof(A) fixed(",") nameof(B) fixed(")")); -//! } -//! impl SoliditySignature for (A,) { -//! make_signature!(new fixed("(") nameof(A) fixed(",") shift_left(1) fixed(")")); -//! } +//! impl SoliditySignature for u8 { +//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint8")); +//! } +//! impl SoliditySignature for u32 { +//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint32")); +//! } +//! impl SoliditySignature for Vec { +//! const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]")); +//! } +//! impl SoliditySignature for (A, B) { +//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("(") nameof(A::SIGNATURE) fixed(",") nameof(B::SIGNATURE) fixed(")")); +//! } +//! impl SoliditySignature for (A,) { +//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("(") nameof(A::SIGNATURE) fixed(",") shift_left(1) fixed(")")); +//! } //! //! assert_eq!(u8::name(), "uint8"); //! assert_eq!(>::name(), "uint8[]"); @@ -52,28 +48,23 @@ //! #### Example //! ``` //! use core::str::from_utf8; -//! use evm_coder::{ -//! make_signature, -//! custom_signature::{ -//! SIGNATURE_SIZE_LIMIT, SignatureUnit, SignaturePreferences, FunctionSignature, -//! }, -//! }; +//! use evm_coder::{custom_signature::SignatureUnit, make_signature}; //! // Trait for our signature //! trait SoliditySignature { -//! const SIGNATURE: SignatureUnit; +//! const SIGNATURE: SignatureUnit; //! -//! fn name() -> &'static str { -//! from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8") -//! } -//! } +//! fn name() -> &'static str { +//! from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8") +//! } +//! } //! //! // Make signatures for some types -//! impl SoliditySignature for u8 { -//! make_signature!(new fixed("uint8")); -//! } -//! impl SoliditySignature for Vec { -//! make_signature!(new nameof(T) fixed("[]")); -//! } +//! impl SoliditySignature for u8 { +//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint8")); +//! } +//! impl SoliditySignature for Vec { +//! const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]")); +//! } //! ``` /// The maximum length of the signature. @@ -134,8 +125,23 @@ (@size; fixed($expr:expr) $($tt:tt)*) => { $expr.len() + $crate::make_signature!(@size; $($tt)*) }; - (@size; nameof($expr:ty) $($tt:tt)*) => { - <$expr>::SIGNATURE.len + $crate::make_signature!(@size; $($tt)*) + (@size; nameof($expr:expr) $($tt:tt)*) => { + $expr.len + $crate::make_signature!(@size; $($tt)*) + }; + (@size; numof($expr:expr) $($tt:tt)*) => { + { + let mut out = 0; + let mut v = $expr; + if v == 0 { + out = 1; + } else { + while v > 0 { + out += 1; + v /= 10; + } + } + out + } + $crate::make_signature!(@size; $($tt)*) }; (@size; shift_left($expr:expr) $($tt:tt)*) => { $crate::make_signature!(@size; $($tt)*) - $expr @@ -150,12 +156,41 @@ } $crate::make_signature!(@data($dst, $dst_offset); $($tt)*) }; - (@data($dst:ident, $dst_offset:ident); nameof($expr:ty) $($tt:tt)*) => { + (@data($dst:ident, $dst_offset:ident); nameof($expr:expr) $($tt:tt)*) => { { - $crate::make_signature!(@copy(&<$expr>::SIGNATURE.data, $dst, <$expr>::SIGNATURE.len, $dst_offset)); + $crate::make_signature!(@copy(&$expr.data, $dst, $expr.len, $dst_offset)); } $crate::make_signature!(@data($dst, $dst_offset); $($tt)*) }; + (@data($dst:ident, $dst_offset:ident); numof($expr:expr) $($tt:tt)*) => { + { + let mut v = $expr; + let mut need_to_swap = 0; + if v == 0 { + $dst[$dst_offset] = b'0'; + $dst_offset += 1; + } else { + while v > 0 { + let n = (v % 10) as u8; + $dst[$dst_offset] = b'0' + n; + v /= 10; + need_to_swap += 1; + $dst_offset += 1; + } + } + let mut i = 0; + #[allow(clippy::manual_swap)] + while i < need_to_swap / 2 { + let a = $dst_offset - i - 1; + let b = $dst_offset - need_to_swap + i; + let v = $dst[a]; + $dst[a] = $dst[b]; + $dst[b] = v; + i += 1; + } + } + $crate::make_signature!(@data($dst, $dst_offset); $($tt)*) + }; (@data($dst:ident, $dst_offset:ident); shift_left($expr:expr) $($tt:tt)*) => { $dst_offset -= $expr; $crate::make_signature!(@data($dst, $dst_offset); $($tt)*) @@ -181,34 +216,38 @@ use super::{SIGNATURE_SIZE_LIMIT, SignatureUnit}; trait Name { - const SIGNATURE: SignatureUnit; + const NAME: SignatureUnit; fn name() -> &'static str { - from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8") + from_utf8(&Self::NAME.data[..Self::NAME.len]).expect("bad utf-8") } } impl Name for u8 { - const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint8")); + const NAME: SignatureUnit = make_signature!(new fixed("uint8")); } impl Name for u32 { - const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint32")); + const NAME: SignatureUnit = make_signature!(new fixed("uint32")); } impl Name for Vec { - const SIGNATURE: SignatureUnit = make_signature!(new nameof(T) fixed("[]")); + const NAME: SignatureUnit = make_signature!(new nameof(T::NAME) fixed("[]")); } impl Name for (A, B) { - const SIGNATURE: SignatureUnit = - make_signature!(new fixed("(") nameof(A) fixed(",") nameof(B) fixed(")")); + const NAME: SignatureUnit = + make_signature!(new fixed("(") nameof(A::NAME) fixed(",") nameof(B::NAME) fixed(")")); } impl Name for (A,) { - const SIGNATURE: SignatureUnit = - make_signature!(new fixed("(") nameof(A) fixed(",") shift_left(1) fixed(")")); + const NAME: SignatureUnit = + make_signature!(new fixed("(") nameof(A::NAME) fixed(",") shift_left(1) fixed(")")); + } + impl Name for [A; SIZE] { + const NAME: SignatureUnit = + make_signature!(new nameof(A::NAME) fixed("[") numof(SIZE) fixed("]")); } struct MaxSize(); impl Name for MaxSize { - const SIGNATURE: SignatureUnit = SignatureUnit { + const NAME: SignatureUnit = SignatureUnit { data: [b'!'; SIGNATURE_SIZE_LIMIT], len: SIGNATURE_SIZE_LIMIT, }; @@ -273,6 +312,13 @@ } #[test] + fn num() { + assert_eq!(<[u8; 0]>::name(), "uint8[0]"); + assert_eq!(<[u8; 1234]>::name(), "uint8[1234]"); + assert_eq!(<[u8; 12345]>::name(), "uint8[12345]"); + } + + #[test] fn over_max_size() { let t = trybuild::TestCases::new(); t.compile_fail("tests/build_failed/custom_signature_over_max_size.rs"); --- a/crates/evm-coder/tests/build_failed/custom_signature_over_max_size.rs +++ b/crates/evm-coder/tests/build_failed/custom_signature_over_max_size.rs @@ -15,7 +15,8 @@ } impl Name for Vec { - evm_coder::make_signature!(new nameof(T) fixed("[]")); + const SIGNATURE: SignatureUnit = + evm_coder::make_signature!(new nameof(T::SIGNATURE) fixed("[]")); } struct MaxSize(); --- a/crates/evm-coder/tests/build_failed/custom_signature_over_max_size.stderr +++ b/crates/evm-coder/tests/build_failed/custom_signature_over_max_size.stderr @@ -1,18 +1,28 @@ +warning: unused import: `make_signature` + --> tests/build_failed/custom_signature_over_max_size.rs:5:2 + | +5 | make_signature, + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_imports)]` on by default + error: any use of this value will cause an error - --> tests/build_failed/custom_signature_over_max_size.rs:18:2 + --> tests/build_failed/custom_signature_over_max_size.rs:19:3 | -18 | evm_coder::make_signature!(new nameof(T) fixed("[]")); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 256 but the index is 256 +18 | const SIGNATURE: SignatureUnit = + | ------------------------------ +19 | evm_coder::make_signature!(new nameof(T::SIGNATURE) fixed("[]")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 256 but the index is 256 | = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 - = note: this error originates in the macro `make_signature` which comes from the expansion of the macro `evm_coder::make_signature` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::make_signature` which comes from the expansion of the macro `evm_coder::make_signature` (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> tests/build_failed/custom_signature_over_max_size.rs:29:29 + --> tests/build_failed/custom_signature_over_max_size.rs:30:29 | -29 | const NAME: SignatureUnit = >::SIGNATURE; +30 | const NAME: SignatureUnit = >::SIGNATURE; | ------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! --- a/crates/evm-coder/tests/conditional_is.rs +++ b/crates/evm-coder/tests/conditional_is.rs @@ -1,11 +1,4 @@ use evm_coder::{types::*, solidity_interface, execution::Result}; -use evm_coder::{ - make_signature, - custom_signature::{ - SIGNATURE_SIZE_LIMIT, SignatureUnit, SignaturePreferences, FunctionSignature, - }, - types::Signature, -}; pub struct Contract(bool); --- a/crates/evm-coder/tests/generics.rs +++ b/crates/evm-coder/tests/generics.rs @@ -16,12 +16,6 @@ use std::marker::PhantomData; use evm_coder::{execution::Result, generate_stubgen, solidity_interface, types::*}; -use evm_coder::{ - make_signature, - custom_signature::{ - SIGNATURE_SIZE_LIMIT, SignatureUnit, SignaturePreferences, FunctionSignature, - }, -}; pub struct Generic(PhantomData); --- a/crates/evm-coder/tests/random.rs +++ b/crates/evm-coder/tests/random.rs @@ -17,13 +17,7 @@ #![allow(dead_code)] // This test only checks that macros is not panicking use evm_coder::{ToLog, execution::Result, solidity_interface, types::*, solidity, weight}; -use evm_coder::{ - make_signature, - custom_signature::{ - SIGNATURE_SIZE_LIMIT, SignatureUnit, SignaturePreferences, FunctionSignature, - }, - types::Signature, -}; +use evm_coder::{types::Signature}; pub struct Impls; --- a/crates/evm-coder/tests/solidity_generation.rs +++ b/crates/evm-coder/tests/solidity_generation.rs @@ -15,13 +15,7 @@ // along with Unique Network. If not, see . use evm_coder::{execution::Result, generate_stubgen, solidity_interface, types::*}; -use evm_coder::{ - make_signature, - custom_signature::{ - SIGNATURE_SIZE_LIMIT, SignatureUnit, SignaturePreferences, FunctionSignature, - }, - types::Signature, -}; +use evm_coder::{types::Signature}; pub struct ERC20;