From 99a77af9b754029e60375c913a1293672d14d247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sun, 23 Feb 2020 15:58:25 +0100 Subject: [PATCH 001/286] Performance improvements (#180) * Extend the benchmarks * Optimize encoding/decoding of primitive type vectors * Adds a benchmark for a complex type * Optimize `u8` and `i8` * Implement some more `size_hint` and improve array `encode_to` * Fix the range... --- Cargo.toml | 4 +- benches/benches.rs | 63 ++++++++-- src/codec.rs | 304 ++++++++++++++++++++++++++++++++------------- src/compact.rs | 4 +- tests/mod.rs | 8 +- 5 files changed, 276 insertions(+), 107 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ab6954f7..cd3105e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ arrayvec = { version = "0.5.1", default-features = false, features = ["array-siz serde = { version = "1.0.102", optional = true } parity-scale-codec-derive = { path = "derive", version = "^1.0.2", default-features = false, optional = true } bitvec = { version = "0.15", default-features = false, features = ["alloc"], optional = true } -byte-slice-cast = { version = "0.3.4", default-features = false, optional = true } +byte-slice-cast = { version = "0.3.4", default-features = false, features = ["alloc"] } generic-array = { version = "0.13.2", optional = true } [dev-dependencies] @@ -33,7 +33,7 @@ bench = false default = ["std"] derive = ["parity-scale-codec-derive"] std = ["serde", "bitvec/std", "byte-slice-cast/std"] -bit-vec = ["bitvec", "byte-slice-cast"] +bit-vec = ["bitvec"] # WARNING: DO _NOT_ USE THIS FEATURE IF YOU ARE WORKING ON CONSENSUS CODE!* # diff --git a/benches/benches.rs b/benches/benches.rs index f8fea7e5..dee68ffb 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::time::Duration; +use std::{time::Duration, any::type_name, convert::{TryFrom, TryInto}}; +#[cfg(feature = "bit-vec")] use bitvec::vec::BitVec; use criterion::{Criterion, black_box, Bencher, criterion_group, criterion_main}; use parity_scale_codec::*; @@ -99,30 +100,66 @@ fn vec_append_with_encode_append(b: &mut Bencher) { }); } -fn encode_decode_vec_u8(c: &mut Criterion) { - c.bench_function_over_inputs("vec_u8_encode - Vec", |b, &vec_size| { - let vec: Vec = (0..=255u8) +fn encode_decode_vec + Codec>(c: &mut Criterion) where T::Error: std::fmt::Debug { + c.bench_function_over_inputs(&format!("vec_encode_{}", type_name::()), |b, &vec_size| { + let vec: Vec = (0..=127u8) .cycle() .take(vec_size) + .map(|v| v.try_into().unwrap()) .collect(); let vec = black_box(vec); b.iter(|| vec.encode()) - }, vec![1, 2, 5, 32, 1024]); + }, vec![1, 2, 5, 32, 1024, 2048, 16384]); - c.bench_function_over_inputs("vec_u8_decode - Vec", |b, &vec_size| { - let vec: Vec = (0..=255u8) + c.bench_function_over_inputs(&format!("vec_decode_{}", type_name::()), |b, &vec_size| { + let vec: Vec = (0..=127u8) .cycle() .take(vec_size) + .map(|v| v.try_into().unwrap()) .collect(); let vec = vec.encode(); let vec = black_box(vec); b.iter(|| { - let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); + let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); }) - }, vec![1, 2, 5, 32, 1024]); + }, vec![1, 2, 5, 32, 1024, 2048, 16384]); +} + +fn encode_decode_complex_type(c: &mut Criterion) { + #[derive(Encode, Decode, Clone)] + struct ComplexType { + _val: u32, + _other_val: u128, + _vec: Vec, + } + + let complex_types = vec![ + ComplexType { _val: 3, _other_val: 345634635, _vec: vec![1, 2, 3, 5, 6, 7] }, + ComplexType { _val: 1000, _other_val: 0980345634635, _vec: vec![1, 2, 3, 5, 6, 7] }, + ComplexType { _val: 43564, _other_val: 342342345634635, _vec: vec![1, 2, 3, 5, 6, 7] }, + ]; + let complex_types2 = complex_types.clone(); + + c.bench_function_over_inputs("vec_encode_complex_type", move |b, &vec_size| { + let vec: Vec = complex_types.clone().into_iter().cycle().take(vec_size).collect(); + + let vec = black_box(vec); + b.iter(|| vec.encode()) + }, vec![1, 2, 5, 32, 1024, 2048, 16384]); + + c.bench_function_over_inputs("vec_decode_complex_type", move |b, &vec_size| { + let vec: Vec = complex_types2.clone().into_iter().cycle().take(vec_size).collect(); + + let vec = vec.encode(); + + let vec = black_box(vec); + b.iter(|| { + let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); + }) + }, vec![1, 2, 5, 32, 1024, 2048, 16384]); } fn bench_fn(c: &mut Criterion) { @@ -135,6 +172,9 @@ fn bench_fn(c: &mut Criterion) { } fn encode_decode_bitvec_u8(c: &mut Criterion) { + let _ = c; + + #[cfg(feature = "bit-vec")] c.bench_function_over_inputs("bitvec_u8_encode - BitVec", |b, &size| { let vec: BitVec = [true, false] .iter() @@ -147,6 +187,7 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { b.iter(|| vec.encode()) }, vec![1, 2, 5, 32, 1024]); + #[cfg(feature = "bit-vec")] c.bench_function_over_inputs("bitvec_u8_decode - BitVec", |b, &size| { let vec: BitVec = [true, false] .iter() @@ -167,6 +208,8 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { criterion_group!{ name = benches; config = Criterion::default().warm_up_time(Duration::from_millis(500)).without_plots(); - targets = encode_decode_vec_u8, bench_fn, encode_decode_bitvec_u8 + targets = encode_decode_vec::, encode_decode_vec::, encode_decode_vec::, encode_decode_vec::, + encode_decode_vec::, encode_decode_vec::, encode_decode_vec::, encode_decode_vec::, + bench_fn, encode_decode_bitvec_u8, encode_decode_complex_type } criterion_main!(benches); diff --git a/src/codec.rs b/src/codec.rs index 73f09890..c7ee3ed8 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -20,6 +20,8 @@ use core::{mem, ops::Deref, marker::PhantomData, iter::FromIterator, convert::Tr use arrayvec::ArrayVec; +use byte_slice_cast::{AsByteSlice, IntoVecOf}; + #[cfg(any(feature = "std", feature = "full"))] use crate::alloc::{ string::String, @@ -223,12 +225,25 @@ impl Output for W { } } -/// This enum must not be exported and must only be instantiable by parity-scale-codec. -/// Because implementation of Encode and Decode for u8 is done in this crate -/// and there is not other usage. -pub enum IsU8 { - Yes, - No, + +/// !INTERNAL USE ONLY! +/// +/// This enum provides type information to optimize encoding/decoding by doing fake specialization. +#[doc(hidden)] +#[non_exhaustive] +pub enum TypeInfo { + /// Default value of [`Encode::TYPE_INFO`] to not require implementors to set this value in the trait. + Unknown, + U8, + I8, + U16, + I16, + U32, + I32, + U64, + I64, + U128, + I128, } /// Trait that allows zero-copy write of value-references to slices in LE format. @@ -236,9 +251,10 @@ pub enum IsU8 { /// Implementations should override `using_encoded` for value types and `encode_to` and `size_hint` for allocating types. /// Wrapper types should override all methods. pub trait Encode { + // !INTERNAL USE ONLY! + // This const helps SCALE to optimize the encoding/decoding by doing fake specialization. #[doc(hidden)] - // This const is used to optimise implementation of codec for Vec. - const IS_U8: IsU8 = IsU8::No; + const TYPE_INFO: TypeInfo = TypeInfo::Unknown; /// If possible give a hint of expected size of the encoding. /// @@ -275,8 +291,10 @@ pub trait DecodeLength { /// Trait that allows zero-copy read of value-references from slices in LE format. pub trait Decode: Sized { + // !INTERNAL USE ONLY! + // This const helps SCALE to optimize the encoding/decoding by doing fake specialization. #[doc(hidden)] - const IS_U8: IsU8 = IsU8::No; + const TYPE_INFO: TypeInfo = TypeInfo::Unknown; /// Attempt to deserialise the value from input. fn decode(value: &mut I) -> Result; @@ -392,6 +410,31 @@ impl Decode for X where fn decode(input: &mut I) -> Result { Ok(T::decode(input)?.into()) } + +} + +/// A macro that matches on a [`TypeInfo`] and expands a given macro per variant. +/// +/// The first parameter to the given macro will be the type of variant (e.g. `u8`, `u32`, etc.) and other parameters +/// given to this macro. +/// +/// The last parameter is the code that should be executed for the `Unknown` type info. +macro_rules! with_type_info { + ( $type_info:expr, $macro:ident $( ( $( $params:ident ),* ) )?, { $( $unknown_variant:tt )* }, ) => { + match $type_info { + TypeInfo::U8 => { $macro!(u8 $( $( , $params )* )? ) }, + TypeInfo::I8 => { $macro!(i8 $( $( , $params )* )? ) }, + TypeInfo::U16 => { $macro!(u16 $( $( , $params )* )? ) }, + TypeInfo::I16 => { $macro!(i16 $( $( , $params )* )? ) }, + TypeInfo::U32 => { $macro!(u32 $( $( , $params )* )? ) }, + TypeInfo::I32 => { $macro!(i32 $( $( , $params )* )? ) }, + TypeInfo::U64 => { $macro!(u64 $( $( , $params )* )? ) }, + TypeInfo::I64 => { $macro!(i64 $( $( , $params )* )? ) }, + TypeInfo::U128 => { $macro!(u128 $( $( , $params )* )? ) }, + TypeInfo::I128 => { $macro!(i128 $( $( , $params )* )? ) }, + TypeInfo::Unknown => { $( $unknown_variant )* }, + } + }; } /// Something that can be encoded as a reference. @@ -512,9 +555,36 @@ macro_rules! impl_array { ( $( $n:expr, )* ) => { $( impl Encode for [T; $n] { + fn size_hint(&self) -> usize { + mem::size_of::() * $n + } + fn encode_to(&self, dest: &mut W) { - for item in self.iter() { - item.encode_to(dest); + macro_rules! encode_to { + ( u8, $self:ident, $dest:ident ) => {{ + let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$self[..]) }; + $dest.write(&typed) + }}; + ( i8, $self:ident, $dest:ident ) => {{ + // `i8` has the same size as `u8`. We can just convert it here and write to the + // dest buffer directly. + let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$self[..]) }; + $dest.write(&typed) + }}; + ( $ty:ty, $self:ident, $dest:ident ) => {{ + let typed = unsafe { mem::transmute::<&[T], &[$ty]>(&$self[..]) }; + $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed)) + }}; + } + + with_type_info! { + ::TYPE_INFO, + encode_to(self, dest), + { + for item in self.iter() { + item.encode_to(dest); + } + }, } } } @@ -547,7 +617,7 @@ impl_array!( 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, @@ -614,29 +684,76 @@ pub(crate) fn compact_encode_len_to(dest: &mut W, len: usize) -> Resu impl Encode for [T] { fn size_hint(&self) -> usize { - if let IsU8::Yes = ::IS_U8 { - self.len() + mem::size_of::() - } else { - 0 - } + mem::size_of::() + mem::size_of::() * self.len() } fn encode_to(&self, dest: &mut W) { compact_encode_len_to(dest, self.len()).expect("Compact encodes length"); - if let IsU8::Yes= ::IS_U8 { - let self_transmute = unsafe { - core::mem::transmute::<&[T], &[u8]>(self) - }; - dest.write(self_transmute) - } else { - for item in self { - item.encode_to(dest); - } + macro_rules! encode_to { + ( u8, $self:ident, $dest:ident ) => {{ + let typed = unsafe { mem::transmute::<&[T], &[u8]>($self) }; + $dest.write(&typed) + }}; + ( i8, $self:ident, $dest:ident ) => {{ + // `i8` has the same size as `u8`. We can just convert it here and write to the + // dest buffer directly. + let typed = unsafe { mem::transmute::<&[T], &[u8]>($self) }; + $dest.write(&typed) + }}; + ( $ty:ty, $self:ident, $dest:ident ) => {{ + let typed = unsafe { mem::transmute::<&[T], &[$ty]>($self) }; + $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed)) + }}; + } + + with_type_info! { + ::TYPE_INFO, + encode_to(self, dest), + { + for item in self { + item.encode_to(dest); + } + }, } } } +/// Read an `u8` vector from the given input. +fn read_vec_u8(input: &mut I, len: usize) -> Result, Error> { + let input_len = input.remaining_len()?; + + // If there is input len and it cannot be pre-allocated then return directly. + if input_len.map(|l| l < len).unwrap_or(false) { + return Err("Not enough data to decode vector".into()) + } + + // Note: we checked that if input_len is some then it can preallocated. + let r = if input_len.is_some() || len < MAX_PREALLOCATION { + // Here we pre-allocate the whole buffer. + let mut r = vec![0; len]; + input.read(&mut r)?; + + r + } else { + // Here we pre-allocate only the maximum pre-allocation + let mut r = vec![]; + + let mut remains = len; + while remains != 0 { + let len_read = MAX_PREALLOCATION.min(remains); + let len_filled = r.len(); + r.resize(len_filled + len_read, 0); + input.read(&mut r[len_filled..])?; + remains -= len_read; + } + + r + }; + + Ok(r) +} + impl WrapperTypeEncode for Vec {} impl, U: Encode> EncodeLike> for Vec {} impl, U: Encode> EncodeLike<&[U]> for Vec {} @@ -646,49 +763,39 @@ impl Decode for Vec { fn decode(input: &mut I) -> Result { >::decode(input).and_then(move |Compact(len)| { let len = len as usize; - if let IsU8::Yes = ::IS_U8 { - let input_len = input.remaining_len()?; - // If there is input len and it cannot be pre-allocated then return directly. - if input_len.map(|l| l < len).unwrap_or(false) { - return Err("Not enough data to decode vector".into()) - } + macro_rules! decode { + ( u8, $input:ident, $len:ident ) => {{ + let vec = read_vec_u8($input, $len)?; + Ok(unsafe { mem::transmute::, Vec>(vec) }) + }}; + ( i8, $input:ident, $len:ident ) => {{ + let vec = read_vec_u8($input, $len)?; + Ok(unsafe { mem::transmute::, Vec>(vec) }) + }}; + ( $ty:ty, $input:ident, $len:ident ) => {{ + let vec = read_vec_u8($input, $len * mem::size_of::<$ty>())?; + let typed = vec.into_vec_of::<$ty>() + .map_err(|_| "Failed to convert from `Vec` to typed vec")?; + + Ok(unsafe { mem::transmute::, Vec>(typed) }) + }}; + } - // Note: we checked that if input_len is some then it can preallocated. - let r = if input_len.is_some() || len < MAX_PREALLOCATION { - // Here we pre-allocate the whole buffer. - let mut r = vec![0; len]; - input.read(&mut r)?; - - r - } else { - // Here we pre-allocate only the maximum pre-allocation - let mut r = vec![]; - - let mut remains = len; - while remains != 0 { - let len_read = MAX_PREALLOCATION.min(remains); - let len_filled = r.len(); - r.resize(len_filled + len_read, 0); - input.read(&mut r[len_filled..])?; - remains -= len_read; + with_type_info! { + ::TYPE_INFO, + decode(input, len), + { + let capacity = input.remaining_len()? + .unwrap_or(MAX_PREALLOCATION) + .checked_div(mem::size_of::()) + .unwrap_or(0); + let mut r = Vec::with_capacity(capacity); + for _ in 0..len { + r.push(T::decode(input)?); } - - r - }; - - let r = unsafe { mem::transmute::, Vec>(r) }; - Ok(r) - } else { - let capacity = input.remaining_len()? - .unwrap_or(MAX_PREALLOCATION) - .checked_div(mem::size_of::()) - .unwrap_or(0); - let mut r = Vec::with_capacity(capacity); - for _ in 0..len { - r.push(T::decode(input)?); - } - Ok(r) + Ok(r) + }, } }) } @@ -701,9 +808,11 @@ macro_rules! impl_codec_through_iterator { { $( $type_like_generics:ident ),* } { $( $impl_like_generics:tt )* } )*) => {$( - impl<$( $generics: Encode ),*> Encode - for $type<$( $generics ),*> - { + impl<$( $generics: Encode ),*> Encode for $type<$( $generics, )*> { + fn size_hint(&self) -> usize { + mem::size_of::() $( + mem::size_of::<$generics>() * self.len() )* + } + fn encode_to(&self, dest: &mut W) { compact_encode_len_to(dest, self.len()).expect("Compact encodes length"); @@ -714,7 +823,7 @@ macro_rules! impl_codec_through_iterator { } impl<$( $generics: Decode $( + $decode_additional )? ),*> Decode - for $type<$( $generics ),*> + for $type<$( $generics, )*> { fn decode(input: &mut I) -> Result { >::decode(input).and_then(move |Compact(len)| { @@ -725,10 +834,10 @@ macro_rules! impl_codec_through_iterator { impl<$( $impl_like_generics )*> EncodeLike<$type<$( $type_like_generics ),*>> for $type<$( $generics ),*> {} - impl<$( $impl_like_generics )*> EncodeLike<&[( $( $type_like_generics),* )]> + impl<$( $impl_like_generics )*> EncodeLike<&[( $( $type_like_generics, )* )]> for $type<$( $generics ),*> {} impl<$( $impl_like_generics )*> EncodeLike<$type<$( $type_like_generics ),*>> - for &[( $( $generics ),* )] {} + for &[( $( $generics, )* )] {} )*} } @@ -748,20 +857,33 @@ impl + Ord, U: Encode> EncodeLike<&[U]> for VecDeque {} impl, U: Encode + Ord> EncodeLike> for &[T] {} impl Encode for VecDeque { + fn size_hint(&self) -> usize { + mem::size_of::() + mem::size_of::() * self.len() + } + fn encode_to(&self, dest: &mut W) { compact_encode_len_to(dest, self.len()).expect("Compact encodes length"); - if let IsU8::Yes = ::IS_U8 { - let slices = self.as_slices(); - let slices_transmute = unsafe { - core::mem::transmute::<(&[T], &[T]), (&[u8], &[u8])>(slices) - }; - dest.write(slices_transmute.0); - dest.write(slices_transmute.1); - } else { - for item in self { - item.encode_to(dest); - } + macro_rules! encode_to { + ( $ty:ty, $self:ident, $dest:ident ) => {{ + let slices = $self.as_slices(); + let typed = unsafe { + core::mem::transmute::<(&[T], &[T]), (&[$ty], &[$ty])>(slices) + }; + + $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.0)); + $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.1)); + }}; + } + + with_type_info! { + ::TYPE_INFO, + encode_to(self, dest), + { + for item in self { + item.encode_to(dest); + } + }, } } } @@ -896,10 +1018,12 @@ mod inner_tuple_impl { } macro_rules! impl_endians { - ( $( $t:ty ),* ) => { $( + ( $( $t:ty; $ty_info:ident ),* ) => { $( impl EncodeLike for $t {} impl Encode for $t { + const TYPE_INFO: TypeInfo = TypeInfo::$ty_info; + fn size_hint(&self) -> usize { mem::size_of::<$t>() } @@ -911,6 +1035,8 @@ macro_rules! impl_endians { } impl Decode for $t { + const TYPE_INFO: TypeInfo = TypeInfo::$ty_info; + fn decode(input: &mut I) -> Result { let mut buf = [0u8; mem::size_of::<$t>()]; input.read(&mut buf)?; @@ -920,11 +1046,11 @@ macro_rules! impl_endians { )* } } macro_rules! impl_one_byte { - ( $( $t:ty $( { $is_u8:ident } )? ),* ) => { $( + ( $( $t:ty; $ty_info:ident ),* ) => { $( impl EncodeLike for $t {} impl Encode for $t { - $( const $is_u8: IsU8 = IsU8::Yes; )? + const TYPE_INFO: TypeInfo = TypeInfo::$ty_info; fn size_hint(&self) -> usize { mem::size_of::<$t>() @@ -936,7 +1062,7 @@ macro_rules! impl_one_byte { } impl Decode for $t { - $( const $is_u8: IsU8 = IsU8::Yes; )? + const TYPE_INFO: TypeInfo = TypeInfo::$ty_info; fn decode(input: &mut I) -> Result { Ok(input.read_byte()? as $t) @@ -945,8 +1071,8 @@ macro_rules! impl_one_byte { )* } } -impl_endians!(u16, u32, u64, u128, i16, i32, i64, i128); -impl_one_byte!(u8 {IS_U8}, i8); +impl_endians!(u16; U16, u32; U32, u64; U64, u128; U128, i16; I16, i32; I32, i64; I64, i128; I128); +impl_one_byte!(u8; U8, i8; I8); impl EncodeLike for bool {} diff --git a/src/compact.rs b/src/compact.rs index c0c999ab..1d77da08 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -881,7 +881,7 @@ mod tests { (u64::max_value() << 8) - 1, u64::max_value() << 16, (u64::max_value() << 16) - 1, - ].into_iter() { + ].iter() { let e = Compact::::encode(&Compact(*a)); let d = Compact::::decode(&mut &e[..]).unwrap().0; assert_eq!(*a, d); @@ -895,7 +895,7 @@ mod tests { (u64::max_value() - 10) as u128, u128::max_value(), u128::max_value() - 10, - ].into_iter() { + ].iter() { let e = Compact::::encode(&Compact(*a)); let d = Compact::::decode(&mut &e[..]).unwrap().0; assert_eq!(*a, d); diff --git a/tests/mod.rs b/tests/mod.rs index bb194688..c885e234 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -476,7 +476,7 @@ fn encode_decode_empty_enum() { #[derive(Encode, Decode, PartialEq, Debug)] enum EmptyEnumDerive {} - fn impls_encode_decode() {} + fn impls_encode_decode() {} impls_encode_decode::(); assert_eq!(EmptyEnumDerive::decode(&mut &[1, 2, 3][..]), Err("No such variant in enum EmptyEnumDerive".into())); @@ -489,7 +489,7 @@ fn codec_vec_u8() { vec![0u8; 10], vec![0u8; 100], vec![0u8; 1000], - ].into_iter() { + ].iter() { let e = v.encode(); assert_eq!(v, &Vec::::decode(&mut &e[..]).unwrap()); } @@ -514,7 +514,7 @@ fn recursive_type() { fn crafted_input_for_vec_u8() { assert_eq!( Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]).err().unwrap().what(), - "Not enough data to decode vector" + "Not enough data to decode vector", ); } @@ -522,7 +522,7 @@ fn crafted_input_for_vec_u8() { fn crafted_input_for_vec_t() { assert_eq!( Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]).err().unwrap().what(), - "Not enough data to fill buffer" + "Not enough data to decode vector", ); } From 40a2bb97d79b18d8550d03640bf871c48bec14a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 27 Feb 2020 13:40:06 +0100 Subject: [PATCH 002/286] Implement `EncodeAppend` for `VecDeque` (#182) Also implements `EncodeLike` for `VecDeque`/`Vec`. --- src/codec.rs | 24 ++++++++++++++++---- src/encode_append.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index c7ee3ed8..fbf1f65e 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -852,11 +852,13 @@ impl_codec_through_iterator! { { T: EncodeLike, LikeT: Encode } } -impl EncodeLike for VecDeque {} -impl + Ord, U: Encode> EncodeLike<&[U]> for VecDeque {} -impl, U: Encode + Ord> EncodeLike> for &[T] {} +impl EncodeLike for VecDeque {} +impl, U: Encode> EncodeLike<&[U]> for VecDeque {} +impl, U: Encode> EncodeLike> for &[T] {} +impl, U: Encode> EncodeLike> for VecDeque {} +impl, U: Encode> EncodeLike> for Vec {} -impl Encode for VecDeque { +impl Encode for VecDeque { fn size_hint(&self) -> usize { mem::size_of::() + mem::size_of::() * self.len() } @@ -1374,4 +1376,18 @@ mod tests { t::<&[u8]>(); t::<&str>(); } + + #[test] + fn vec_deque_encode_like_vec() { + let data: VecDeque = vec![1, 2, 3, 4, 5, 6].into(); + let encoded = data.encode(); + + let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); + assert!(decoded.iter().all(|v| data.contains(&v))); + assert_eq!(data.len(), decoded.len()); + + let encoded = decoded.encode(); + let decoded = VecDeque::::decode(&mut &encoded[..]).unwrap(); + assert_eq!(data, decoded); + } } diff --git a/src/encode_append.rs b/src/encode_append.rs index 8d6c97f2..ea01d332 100644 --- a/src/encode_append.rs +++ b/src/encode_append.rs @@ -83,6 +83,29 @@ impl EncodeAppend for Vec { } } +impl EncodeAppend for crate::alloc::collections::VecDeque { + type Item = T; + + fn append<'a, I: IntoIterator>( + self_encoded: Vec, + iter: I, + ) -> Result, Error> where Self::Item: 'a, I::IntoIter: ExactSizeIterator { + append_or_new_vec_with_any_item(self_encoded, iter) + } + + fn append_or_new( + self_encoded: Vec, + iter: I, + ) -> Result, Error> + where + I: IntoIterator, + EncodeLikeItem: EncodeLike, + I::IntoIter: ExactSizeIterator, + { + append_or_new_vec_with_any_item(self_encoded, iter) + } +} + fn extract_length_data(data: &[u8], input_len: usize) -> Result<(u32, usize, usize), Error> { let len = u32::from(Compact::::decode(&mut &data[..])?); let new_len = len @@ -152,6 +175,7 @@ where mod tests { use super::*; use crate::{Input, Encode, EncodeLike}; + use std::collections::VecDeque; #[test] fn vec_encode_append_works() { @@ -181,6 +205,34 @@ mod tests { assert_eq!(decoded, expected); } + #[test] + fn vecdeque_encode_append_works() { + let max_value = 1_000_000; + + let encoded = (0..max_value).fold(Vec::new(), |encoded, v| { + as EncodeAppend>::append_or_new(encoded, std::iter::once(&v)).unwrap() + }); + + let decoded = VecDeque::::decode(&mut &encoded[..]).unwrap(); + assert_eq!(decoded, (0..max_value).collect::>()); + } + + #[test] + fn vecdeque_encode_append_multiple_items_works() { + let max_value = 1_000_000u32; + + let encoded = (0..max_value).fold(Vec::new(), |encoded, v| { + as EncodeAppend>::append_or_new(encoded, &[v, v, v, v]).unwrap() + }); + + let decoded = VecDeque::::decode(&mut &encoded[..]).unwrap(); + let expected = (0..max_value).fold(Vec::new(), |mut vec, i| { + vec.append(&mut vec![i, i, i, i]); + vec + }); + assert_eq!(decoded, expected); + } + #[test] fn append_non_copyable() { #[derive(Eq, PartialEq, Debug)] From 3bcb77918c3970204709d4d075424747ce2ab50d Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Mon, 2 Mar 2020 22:13:23 +0100 Subject: [PATCH 003/286] Fixed capacity calculation when decoding Vec (#183) * Fixed capacity calcuation when decoding Vec * Added a test --- src/codec.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index fbf1f65e..34f24c5e 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -786,11 +786,11 @@ impl Decode for Vec { ::TYPE_INFO, decode(input, len), { - let capacity = input.remaining_len()? + let input_capacity = input.remaining_len()? .unwrap_or(MAX_PREALLOCATION) .checked_div(mem::size_of::()) .unwrap_or(0); - let mut r = Vec::with_capacity(capacity); + let mut r = Vec::with_capacity(input_capacity.min(len)); for _ in 0..len { r.push(T::decode(input)?); } @@ -1390,4 +1390,21 @@ mod tests { let decoded = VecDeque::::decode(&mut &encoded[..]).unwrap(); assert_eq!(data, decoded); } + + #[test] + fn vec_decode_right_capacity() { + let data: Vec = vec![1, 2, 3]; + let mut encoded = data.encode(); + encoded.resize(encoded.len() * 2, 0); + let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); + assert_eq!(data, decoded); + assert_eq!(decoded.capacity(), decoded.len()); + // Check with non-integer type + let data: Vec = vec!["1".into(), "2".into(), "3".into()]; + let mut encoded = data.encode(); + encoded.resize(65536, 0); + let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); + assert_eq!(data, decoded); + assert_eq!(decoded.capacity(), decoded.len()); + } } From 407a77ce36c69514e88417b520dd07f4eda6e461 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 3 Mar 2020 09:46:29 +0100 Subject: [PATCH 004/286] add doc for encoded_as stating it is intended to be used for HasCompact types (#185) * add doc --- derive/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index d53d2b6a..d35dcc70 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -78,7 +78,8 @@ fn wrap_with_dummy_const(impl_block: proc_macro2::TokenStream) -> proc_macro::To /// implement `parity_scale_codec::HasCompact` and will be encoded as `HasCompact::Type`. /// * `#[codec(encoded_as = "$EncodeAs")]`: the field is encoded as an alternative type. $EncodedAs /// type must implement `parity_scale_codec::EncodeAsRef<'_, $FieldType>` with $FieldType the -/// type of the field with the attribute. +/// type of the field with the attribute. This is intended to be used for types implementing +/// `HasCompact` as shown in the example. /// /// ``` /// # use parity_scale_codec_derive::Encode; From 696a9c01d91a9189968845b1c469709b443ff346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 3 Mar 2020 09:53:45 +0100 Subject: [PATCH 005/286] Release `1.2.0` (#184) --- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cd3105e1..5d97e8b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "1.1.2" +version = "1.2.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,7 +11,7 @@ edition = "2018" [dependencies] arrayvec = { version = "0.5.1", default-features = false, features = ["array-sizes-33-128", "array-sizes-129-255"] } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "^1.0.2", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "1.2.0", default-features = false, optional = true } bitvec = { version = "0.15", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "0.3.4", default-features = false, features = ["alloc"] } generic-array = { version = "0.13.2", optional = true } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index e94a5fe7..cdb2a4f2 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "1.1.1" +version = "1.2.0" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" From 1893fbecd43906c44e52d412b35753cdec4cc180 Mon Sep 17 00:00:00 2001 From: Stefanie Doll Date: Tue, 3 Mar 2020 22:11:38 +0100 Subject: [PATCH 006/286] Add Github Action for Matrix release bot (#186) --- .github/workflows/release-bot.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/release-bot.yml diff --git a/.github/workflows/release-bot.yml b/.github/workflows/release-bot.yml new file mode 100644 index 00000000..08aa9441 --- /dev/null +++ b/.github/workflows/release-bot.yml @@ -0,0 +1,18 @@ +name: Pushes release updates to a pre-defined Matrix room +on: + release: + types: + - edited + - prereleased + - published +jobs: + ping_matrix: + runs-on: ubuntu-latest + steps: + - name: send message + uses: s3krit/matrix-message-action@v0.0.2 + with: + room_id: ${{ secrets.MATRIX_ROOM_ID }} + access_token: ${{ secrets.MATRIX_ACCESS_TOKEN }} + message: "**${{github.event.repository.full_name}}:** A release has been ${{github.event.action}}
Release version [${{github.event.release.tag_name}}](${{github.event.release.html_url}})

***Description:***
${{github.event.release.body}}
" + server: "matrix.parity.io" From 7db8bf90c4e0b20b1731bfe90e5b4074088f1abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 5 Mar 2020 22:15:20 +0100 Subject: [PATCH 007/286] Update README.md (#187) Fixed link to `Compact Integers` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e38bf77..2f64b224 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Returns an `Err` if the decoding fails. ### CompactAs The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes them even more space/memory efficient. -The compact encoding is described [here](https://substrate.dev/docs/en/overview/low-level-data-format#compact-general-integers). +The compact encoding is described [here](https://substrate.dev/docs/en/overview/low-level-data-format#compactgeneral-integers). * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. The type `As` is defined in the same trait and its implementation should be compact encode-able. From 5f668d00b20fd0ad61e891b6483b3eefcde5e232 Mon Sep 17 00:00:00 2001 From: pscott <30843220+pscott@users.noreply.github.com> Date: Tue, 10 Mar 2020 13:27:53 +0100 Subject: [PATCH 008/286] Add duration to codec (#188) --- fuzzer/Cargo.toml | 2 +- fuzzer/src/main.rs | 2 ++ src/codec.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 212e1580..065ec340 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -7,5 +7,5 @@ publish = false [dependencies] parity-scale-codec = { path = "../", features = [ "derive", "bit-vec" ] } -honggfuzz = "0.5.45" +honggfuzz = "0.5.47" bitvec = { version = "0.15.2", features = ["alloc"] } diff --git a/fuzzer/src/main.rs b/fuzzer/src/main.rs index 844e88bc..a457abc3 100644 --- a/fuzzer/src/main.rs +++ b/fuzzer/src/main.rs @@ -1,4 +1,5 @@ use std::collections::{BTreeMap, BTreeSet, VecDeque, LinkedList, BinaryHeap}; +use std::time::Duration; use bitvec::{vec::BitVec, cursor::BigEndian}; use honggfuzz::fuzz; @@ -98,6 +99,7 @@ fn fuzz_one_input(data: &[u8]){ MockEnum, BitVec, BitVec, + Duration, } } diff --git a/src/codec.rs b/src/codec.rs index 34f24c5e..2fe50f0a 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -16,7 +16,7 @@ #[cfg(feature = "std")] use std::fmt; -use core::{mem, ops::Deref, marker::PhantomData, iter::FromIterator, convert::TryFrom}; +use core::{mem, ops::Deref, marker::PhantomData, iter::FromIterator, convert::TryFrom, time::Duration}; use arrayvec::ArrayVec; @@ -40,6 +40,7 @@ use crate::compact::Compact; use crate::encode_like::EncodeLike; const MAX_PREALLOCATION: usize = 4 * 1024; +const A_BILLION: u32 = 1_000_000_000; /// Descriptive error type #[cfg(feature = "std")] @@ -1099,13 +1100,38 @@ impl Decode for bool { } } +impl Encode for Duration { + fn size_hint(&self) -> usize { + mem::size_of::() + mem::size_of::() + } + + fn encode(&self) -> Vec { + let secs = self.as_secs(); + let nanos = self.subsec_nanos(); + (secs, nanos).encode() + } +} + +impl Decode for Duration { + fn decode(input: &mut I) -> Result { + let (secs, nanos) = <(u64, u32)>::decode(input)?; + if nanos >= A_BILLION { + Err("Number of nanoseconds should not be higher than 10^9.".into()) + } else { + Ok(Duration::new(secs, nanos)) + } + } +} + +impl EncodeLike for Duration {} + #[cfg(test)] mod tests { use super::*; use std::borrow::Cow; #[test] - fn vec_is_slicable() { + fn vec_is_sliceable() { let v = b"Hello world".to_vec(); v.using_encoded(|ref slice| assert_eq!(slice, &b"\x2cHello world") @@ -1407,4 +1433,60 @@ mod tests { assert_eq!(data, decoded); assert_eq!(decoded.capacity(), decoded.len()); } + + #[test] + fn duration() { + let num_secs = 13; + let num_nanos = 37; + + let duration = Duration::new(num_secs, num_nanos); + let expected = (num_secs, num_nanos as u32).encode(); + + assert_eq!(duration.encode(), expected); + assert_eq!(Duration::decode(&mut &expected[..]).unwrap(), duration); + } + + #[test] + fn malformed_duration_encoding_fails() { + // This test should fail, as the number of nanoseconds encoded is exactly 10^9. + let invalid_nanos = A_BILLION; + let encoded = (0u64, invalid_nanos).encode(); + assert!(Duration::decode(&mut &encoded[..]).is_err()); + + let num_secs = 1u64; + let num_nanos = 37u32; + let invalid_nanos = num_secs as u32 * A_BILLION + num_nanos; + let encoded = (num_secs, invalid_nanos).encode(); + // This test should fail, as the number of nano seconds encoded is bigger than 10^9. + assert!(Duration::decode(&mut &encoded[..]).is_err()); + + // Now constructing a valid duration and encoding it. Those asserts should not fail. + let duration = Duration::from_nanos(invalid_nanos as u64); + let expected = (num_secs, num_nanos).encode(); + + assert_eq!(duration.encode(), expected); + assert_eq!(Duration::decode(&mut &expected[..]).unwrap(), duration); + } + + #[test] + fn u64_max() { + let num_secs = u64::max_value(); + let num_nanos = 0; + let duration = Duration::new(num_secs, num_nanos); + let expected = (num_secs, num_nanos).encode(); + + assert_eq!(duration.encode(), expected); + assert_eq!(Duration::decode(&mut &expected[..]).unwrap(), duration); + } + + #[test] + fn decoding_does_not_overflow() { + let num_secs = u64::max_value(); + let num_nanos = A_BILLION; + + // `num_nanos`' carry should make `num_secs` overflow if we were to call `Duration::new()`. + // This test checks that the we do not call `Duration::new()`. + let encoded = (num_secs, num_nanos).encode(); + assert!(Duration::decode(&mut &encoded[..]).is_err()); + } } From 70ae5262a158545f1c0663730a30a00bbc8339b2 Mon Sep 17 00:00:00 2001 From: pscott <30843220+pscott@users.noreply.github.com> Date: Wed, 18 Mar 2020 13:03:25 +0100 Subject: [PATCH 009/286] Handle invalid utf8 sequence (#189) * Change from_utf8_lossy to from_utf8 to avoid replacement characters * Compact code to make it clearer * Add invalid utf8 string decode * Fix code for no-std --- src/codec.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/codec.rs b/src/codec.rs index 2fe50f0a..2e33a9b6 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -670,7 +670,7 @@ impl Decode for PhantomData { #[cfg(any(feature = "std", feature = "full"))] impl Decode for String { fn decode(input: &mut I) -> Result { - Ok(Self::from_utf8_lossy(&Vec::decode(input)?).into()) + Self::from_utf8(Vec::decode(input)?).map_err(|_| "Invalid utf8 sequence".into()) } } @@ -1489,4 +1489,13 @@ mod tests { let encoded = (num_secs, num_nanos).encode(); assert!(Duration::decode(&mut &encoded[..]).is_err()); } + + #[test] + fn string_invalid_utf8() { + // `167, 10` is not a valid utf8 sequence, so this should be an error. + let mut bytes: &[u8] = &[20, 114, 167, 10, 20, 114]; + + let obj = ::decode(&mut bytes); + assert!(obj.is_err()); + } } From 9bde8530f5c8ef0c31121b85ec869148c1dd58f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 28 Mar 2020 13:16:18 +0100 Subject: [PATCH 010/286] Upgrade to latest `BitVec` and release a new version (#193) --- Cargo.toml | 4 +- fuzzer/Cargo.toml | 2 +- fuzzer/src/main.rs | 6 +-- src/bit_vec.rs | 96 +++++++++++++++++++++++----------------------- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5d97e8b0..d1a20150 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "1.2.0" +version = "1.3.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ edition = "2018" arrayvec = { version = "0.5.1", default-features = false, features = ["array-sizes-33-128", "array-sizes-129-255"] } serde = { version = "1.0.102", optional = true } parity-scale-codec-derive = { path = "derive", version = "1.2.0", default-features = false, optional = true } -bitvec = { version = "0.15", default-features = false, features = ["alloc"], optional = true } +bitvec = { version = "0.17.4", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "0.3.4", default-features = false, features = ["alloc"] } generic-array = { version = "0.13.2", optional = true } diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 065ec340..a926ed42 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -8,4 +8,4 @@ publish = false [dependencies] parity-scale-codec = { path = "../", features = [ "derive", "bit-vec" ] } honggfuzz = "0.5.47" -bitvec = { version = "0.15.2", features = ["alloc"] } +bitvec = { version = "0.17.4", features = ["alloc"] } diff --git a/fuzzer/src/main.rs b/fuzzer/src/main.rs index a457abc3..151d337f 100644 --- a/fuzzer/src/main.rs +++ b/fuzzer/src/main.rs @@ -1,7 +1,7 @@ use std::collections::{BTreeMap, BTreeSet, VecDeque, LinkedList, BinaryHeap}; use std::time::Duration; -use bitvec::{vec::BitVec, cursor::BigEndian}; +use bitvec::{vec::BitVec, order::Msb0}; use honggfuzz::fuzz; use parity_scale_codec::{Encode, Decode, Compact}; @@ -97,8 +97,8 @@ fn fuzz_one_input(data: &[u8]){ BinaryHeap, MockStruct, MockEnum, - BitVec, - BitVec, + BitVec, + BitVec, Duration, } } diff --git a/src/bit_vec.rs b/src/bit_vec.rs index b63c9719..ce3efcc8 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -16,7 +16,7 @@ use core::mem; -use bitvec::{vec::BitVec, store::BitStore, cursor::Cursor, slice::BitSlice, boxed::BitBox}; +use bitvec::{vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox}; use byte_slice_cast::{AsByteSlice, ToByteSlice, FromByteSlice, Error as FromByteSliceError}; use crate::codec::{Encode, Decode, Input, Output, Error}; @@ -36,7 +36,13 @@ impl From for Error { } } -impl Encode for BitSlice { +impl Encode for BitSlice { + fn encode_to(&self, dest: &mut W) { + self.to_vec().encode_to(dest) + } +} + +impl Encode for BitVec { fn encode_to(&self, dest: &mut W) { let len = self.len(); assert!( @@ -48,15 +54,9 @@ impl Encode for BitSlice { } } -impl Encode for BitVec { - fn encode_to(&self, dest: &mut W) { - self.as_bitslice().encode_to(dest) - } -} - -impl EncodeLike for BitVec {} +impl EncodeLike for BitVec {} -impl Decode for BitVec { +impl Decode for BitVec { fn decode(input: &mut I) -> Result { >::decode(input).and_then(move |Compact(bits)| { let bits = bits as usize; @@ -72,17 +72,17 @@ impl Decode for BitVec { } } -impl Encode for BitBox { +impl Encode for BitBox { fn encode_to(&self, dest: &mut W) { self.as_bitslice().encode_to(dest) } } -impl EncodeLike for BitBox {} +impl EncodeLike for BitBox {} -impl Decode for BitBox { +impl Decode for BitBox { fn decode(input: &mut I) -> Result { - Ok(Self::from_bitslice(BitVec::::decode(input)?.as_bitslice())) + Ok(Self::from_bitslice(BitVec::::decode(input)?.as_bitslice())) } } @@ -95,34 +95,34 @@ fn required_bytes(bits: usize) -> usize { #[cfg(test)] mod tests { use super::*; - use bitvec::{bitvec, cursor::BigEndian}; + use bitvec::{bitvec, order::Msb0}; macro_rules! test_data { - ($inner_type: ty) => ( + ($inner_type:ident) => ( [ - BitVec::::new(), - bitvec![BigEndian, $inner_type; 0], - bitvec![BigEndian, $inner_type; 1], - bitvec![BigEndian, $inner_type; 0, 0], - bitvec![BigEndian, $inner_type; 1, 0], - bitvec![BigEndian, $inner_type; 0, 1], - bitvec![BigEndian, $inner_type; 1, 1], - bitvec![BigEndian, $inner_type; 1, 0, 1], - bitvec![BigEndian, $inner_type; 0, 1, 0, 1, 0, 1, 1], - bitvec![BigEndian, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0], - bitvec![BigEndian, $inner_type; 1, 1, 0, 1, 0, 1, 1, 0, 1], - bitvec![BigEndian, $inner_type; 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0], - bitvec![BigEndian, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0], - bitvec![BigEndian, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0], - bitvec![BigEndian, $inner_type; 0; 15], - bitvec![BigEndian, $inner_type; 1; 16], - bitvec![BigEndian, $inner_type; 0; 17], - bitvec![BigEndian, $inner_type; 1; 31], - bitvec![BigEndian, $inner_type; 0; 32], - bitvec![BigEndian, $inner_type; 1; 33], - bitvec![BigEndian, $inner_type; 0; 63], - bitvec![BigEndian, $inner_type; 1; 64], - bitvec![BigEndian, $inner_type; 0; 65], + BitVec::::new(), + bitvec![Msb0, $inner_type; 0], + bitvec![Msb0, $inner_type; 1], + bitvec![Msb0, $inner_type; 0, 0], + bitvec![Msb0, $inner_type; 1, 0], + bitvec![Msb0, $inner_type; 0, 1], + bitvec![Msb0, $inner_type; 1, 1], + bitvec![Msb0, $inner_type; 1, 0, 1], + bitvec![Msb0, $inner_type; 0, 1, 0, 1, 0, 1, 1], + bitvec![Msb0, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0], + bitvec![Msb0, $inner_type; 1, 1, 0, 1, 0, 1, 1, 0, 1], + bitvec![Msb0, $inner_type; 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0], + bitvec![Msb0, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0], + bitvec![Msb0, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0], + bitvec![Msb0, $inner_type; 0; 15], + bitvec![Msb0, $inner_type; 1; 16], + bitvec![Msb0, $inner_type; 0; 17], + bitvec![Msb0, $inner_type; 1; 31], + bitvec![Msb0, $inner_type; 0; 32], + bitvec![Msb0, $inner_type; 1; 33], + bitvec![Msb0, $inner_type; 0; 63], + bitvec![Msb0, $inner_type; 1; 64], + bitvec![Msb0, $inner_type; 0; 65], ] ) } @@ -158,7 +158,7 @@ mod tests { fn bitvec_u8() { for v in &test_data!(u8) { let encoded = v.encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); } } @@ -166,7 +166,7 @@ mod tests { fn bitvec_u16() { for v in &test_data!(u16) { let encoded = v.encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); } } @@ -174,33 +174,33 @@ mod tests { fn bitvec_u32() { for v in &test_data!(u32) { let encoded = v.encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); } } #[test] fn bitvec_u64() { for v in &test_data!(u64) { - let encoded = v.encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + let encoded = dbg!(v.encode()); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); } } #[test] fn bitslice() { let data: &[u8] = &[0x69]; - let slice: &BitSlice = data.into(); + let slice = BitSlice::::from_slice(data); let encoded = slice.encode(); - let decoded = BitVec::::decode(&mut &encoded[..]).unwrap(); + let decoded = BitVec::::decode(&mut &encoded[..]).unwrap(); assert_eq!(slice, decoded.as_bitslice()); } #[test] fn bitbox() { let data: &[u8] = &[5, 10]; - let bb: BitBox = data.into(); + let bb = BitBox::::from_slice(data); let encoded = bb.encode(); - let decoded = BitBox::::decode(&mut &encoded[..]).unwrap(); + let decoded = BitBox::::decode(&mut &encoded[..]).unwrap(); assert_eq!(bb, decoded); } } From f4a58fff967b2487bfb2798ba0b50069d9da3df0 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 2 Apr 2020 11:26:00 +0200 Subject: [PATCH 011/286] impl return error for decode_from in CompactAs trait (#197) * impl return error for decode_from in CompactAs trait * update readme * update doc test and readme --- README.md | 8 ++++---- derive/src/lib.rs | 10 +++++++--- src/compact.rs | 14 +++++++------- src/lib.rs | 8 ++++---- tests/mod.rs | 6 +++--- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 2f64b224..f4461e8f 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ The compact encoding is described [here](https://substrate.dev/docs/en/overview/ * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. The type `As` is defined in the same trait and its implementation should be compact encode-able. -* `decode_from(_: Self::As) -> Self`: Decodes the type (self) from a compact encode-able type. +* `decode_from(_: Self::As) -> Result`: Decodes the type (self) from a compact encode-able type. ### HasCompact @@ -142,7 +142,7 @@ assert_eq!(>::decode(&mut &encoded[..]).unwrap().bar ```rust use serde_derive::{Serialize, Deserialize}; -use parity_scale_codec::{Encode, Decode, Compact, HasCompact, CompactAs}; +use parity_scale_codec::{Encode, Decode, Compact, HasCompact, CompactAs, Error}; #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] #[derive(PartialEq, Eq, Clone)] @@ -155,8 +155,8 @@ impl CompactAs for StructHasCompact { &12 } - fn decode_from(_: Self::As) -> Self { - StructHasCompact(12) + fn decode_from(_: Self::As) -> Result { + Ok(StructHasCompact(12)) } } diff --git a/derive/src/lib.rs b/derive/src/lib.rs index d35dcc70..e26d2051 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -299,12 +299,16 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr fn encode_as(&self) -> &#inner_ty { #inner_field } - fn decode_from(x: #inner_ty) -> #name #ty_generics { - #constructor + fn decode_from(x: #inner_ty) + -> core::result::Result<#name #ty_generics, _parity_scale_codec::Error> + { + Ok(#constructor) } } - impl #impl_generics From<_parity_scale_codec::Compact<#name #ty_generics>> for #name #ty_generics #where_clause { + impl #impl_generics From<_parity_scale_codec::Compact<#name #ty_generics>> + for #name #ty_generics #where_clause + { fn from(x: _parity_scale_codec::Compact<#name #ty_generics>) -> #name #ty_generics { x.0 } diff --git a/src/compact.rs b/src/compact.rs index 1d77da08..ced22fcd 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -90,11 +90,11 @@ pub trait CompactAs: From> { /// A compact-encodable type that should be used as the encoding. type As; - /// Returns the encodable type. + /// Returns the compact-encodable type. fn encode_as(&self) -> &Self::As; - /// Create `Self` from the decodable type. - fn decode_from(_: Self::As) -> Self; + /// Decode `Self` from the compact-decoded type. + fn decode_from(_: Self::As) -> Result; } impl EncodeLike for Compact @@ -157,8 +157,8 @@ where Compact: Decode, { fn decode(input: &mut I) -> Result { - Compact::::decode(input) - .map(|x| Compact(::decode_from(x.0))) + let as_ = Compact::::decode(input)?; + Ok(Compact(::decode_from(as_.0)?)) } } @@ -769,8 +769,8 @@ mod tests { fn encode_as(&self) -> &u8 { &self.0 } - fn decode_from(x: u8) -> Wrapper { - Wrapper(x) + fn decode_from(x: u8) -> Result { + Ok(Wrapper(x)) } } diff --git a/src/lib.rs b/src/lib.rs index ecdcd0cb..552efebc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,7 +64,7 @@ //! //! * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. //! The type `As` is defined in the same trait and its implementation should be compact encode-able. -//! * `decode_from(_: Self::As) -> Self`: Decodes the type (self) from a compact encode-able type. +//! * `decode_from(_: Self::As) -> Result`: Decodes the type (self) from a compact encode-able type. //! //! ### HasCompact //! @@ -168,7 +168,7 @@ //! # use parity_scale_codec_derive::{Encode, Decode}; //! //! use serde_derive::{Serialize, Deserialize}; -//! use parity_scale_codec::{Encode, Decode, Compact, HasCompact, CompactAs}; +//! use parity_scale_codec::{Encode, Decode, Compact, HasCompact, CompactAs, Error}; //! //! #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] //! #[derive(PartialEq, Eq, Clone)] @@ -181,8 +181,8 @@ //! &12 //! } //! -//! fn decode_from(_: Self::As) -> Self { -//! StructHasCompact(12) +//! fn decode_from(_: Self::As) -> Result { +//! Ok(StructHasCompact(12)) //! } //! } //! diff --git a/tests/mod.rs b/tests/mod.rs index c885e234..54103ae2 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -14,7 +14,7 @@ #[cfg(not(feature="derive"))] use parity_scale_codec_derive::{Encode, Decode}; -use parity_scale_codec::{Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs}; +use parity_scale_codec::{Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error}; use serde_derive::{Serialize, Deserialize}; #[derive(Debug, PartialEq, Encode, Decode)] @@ -376,8 +376,8 @@ fn generic_bound_hascompact() { fn encode_as(&self) -> &Self::As { &0 } - fn decode_from(_: Self::As) -> Self { - StructHasCompact(0) + fn decode_from(_: Self::As) -> Result { + Ok(StructHasCompact(0)) } } From 1e4aa04f71021cf893df8eaa552d9d1db7f25524 Mon Sep 17 00:00:00 2001 From: Hero Bird Date: Mon, 6 Apr 2020 23:10:53 +0200 Subject: [PATCH 012/286] Add Encode and Decode impls for NonZero* types (#199) * add Encode and Decode impls for NonZero* types * fix Wasm32 build for Error instantiation * apply code review requests --- src/codec.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/codec.rs b/src/codec.rs index 2e33a9b6..ffebf6a2 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -17,7 +17,18 @@ #[cfg(feature = "std")] use std::fmt; use core::{mem, ops::Deref, marker::PhantomData, iter::FromIterator, convert::TryFrom, time::Duration}; - +use core::num::{ + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroI128, + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128, +}; use arrayvec::ArrayVec; use byte_slice_cast::{AsByteSlice, IntoVecOf}; @@ -552,6 +563,49 @@ impl Decode for Option { } } +macro_rules! impl_for_non_zero { + ( $( $name:ty ),* $(,)? ) => { + $( + impl Encode for $name { + fn size_hint(&self) -> usize { + self.get().size_hint() + } + + fn encode_to(&self, dest: &mut W) { + self.get().encode_to(dest) + } + + fn encode(&self) -> Vec { + self.get().encode() + } + + fn using_encoded R>(&self, f: F) -> R { + self.get().using_encoded(f) + } + } + + impl Decode for $name { + fn decode(input: &mut I) -> Result { + Self::new(Decode::decode(input)?) + .ok_or_else(|| Error::from("cannot create non-zero number from 0")) + } + } + )* + } +} +impl_for_non_zero! { + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroI128, + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128, +} + macro_rules! impl_array { ( $( $n:expr, )* ) => { $( From 205d19e613cc1924c0703acf2287071b5f847e0a Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 7 Apr 2020 16:35:04 +0200 Subject: [PATCH 013/286] remove append (#203) --- src/encode_append.rs | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/encode_append.rs b/src/encode_append.rs index ea01d332..5a33ed95 100644 --- a/src/encode_append.rs +++ b/src/encode_append.rs @@ -25,14 +25,6 @@ pub trait EncodeAppend { /// The item that will be appended. type Item: Encode; - /// Append all items in `iter` to the given `self_encoded` representation - /// or if `self_encoded` value is empty then insert the given input data. - #[deprecated(note = "Consider using `append_or_new` instead")] - fn append<'a, I: IntoIterator>( - self_encoded: Vec, - iter: I, - ) -> Result, Error> where Self::Item: 'a, I::IntoIter: ExactSizeIterator; - /// Append all items in `iter` to the given `self_encoded` representation /// or if `self_encoded` value is empty, `iter` is encoded to the `Self` representation. /// @@ -45,10 +37,10 @@ pub trait EncodeAppend { /// let data = Vec::new(); /// /// let item = 8u32; - /// let encoded = as EncodeAppend>::append(data, std::iter::once(&item)).expect("Adds new element"); + /// let encoded = as EncodeAppend>::append_or_new(data, std::iter::once(&item)).expect("Adds new element"); /// /// // Add multiple element - /// as EncodeAppend>::append(encoded, &[700u32, 800u32, 10u32]).expect("Adds new elements"); + /// as EncodeAppend>::append_or_new(encoded, &[700u32, 800u32, 10u32]).expect("Adds new elements"); /// ``` fn append_or_new( self_encoded: Vec, @@ -63,13 +55,6 @@ pub trait EncodeAppend { impl EncodeAppend for Vec { type Item = T; - fn append<'a, I: IntoIterator>( - self_encoded: Vec, - iter: I, - ) -> Result, Error> where Self::Item: 'a, I::IntoIter: ExactSizeIterator { - append_or_new_vec_with_any_item(self_encoded, iter) - } - fn append_or_new( self_encoded: Vec, iter: I, @@ -86,13 +71,6 @@ impl EncodeAppend for Vec { impl EncodeAppend for crate::alloc::collections::VecDeque { type Item = T; - fn append<'a, I: IntoIterator>( - self_encoded: Vec, - iter: I, - ) -> Result, Error> where Self::Item: 'a, I::IntoIter: ExactSizeIterator { - append_or_new_vec_with_any_item(self_encoded, iter) - } - fn append_or_new( self_encoded: Vec, iter: I, From 2ce46f444b1615b064c7d084f817ebe032e9aa7b Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 8 Apr 2020 14:21:58 +0200 Subject: [PATCH 014/286] Add check for attribute and modify index attribute (#206) * add check for attribute and modify index attribute * fmt * improve doc * improve doc * add custom error message --- README.md | 9 +-- derive/src/lib.rs | 18 +++--- derive/src/utils.rs | 135 ++++++++++++++++++++++++++++++++++++++-- src/lib.rs | 9 +-- tests/mod.rs | 2 +- tests/variant_number.rs | 2 +- 6 files changed, 153 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index f4461e8f..f755f124 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ use parity_scale_codec::{Encode, Decode}; #[derive(Debug, PartialEq, Encode, Decode)] enum EnumType { - #[codec(index = "15")] + #[codec(index = 15)] A, B(u32, u64), C { @@ -190,12 +190,13 @@ The derive implementation supports the following attributes: fall back to just use the type parameters of the type. This can be useful for situation where the algorithm includes private types in the public interface. By using this attribute, you should not get this error/warning again. -- `codec(skip)`: Needs to be placed above a field and makes the field to be skipped while encoding/decoding. +- `codec(skip)`: Needs to be placed above a field or variant and makes it to be skipped while + encoding/decoding. - `codec(compact)`: Needs to be placed above a field and makes the field use compact encoding. (The type needs to support compact encoding.) -- `codec(encoded_as(OtherType))`: Needs to be placed above a field and makes the field being encoded +- `codec(encoded_as = "OtherType")`: Needs to be placed above a field and makes the field being encoded by using `OtherType`. -- `codec(index("0"))`: Needs to be placed above an enum variant to make the variant use the given +- `codec(index = 0)`: Needs to be placed above an enum variant to make the variant use the given index when encoded. By default the index is determined by counting from `0` beginning wth the first variant. diff --git a/derive/src/lib.rs b/derive/src/lib.rs index e26d2051..087a3685 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -116,7 +116,7 @@ fn wrap_with_dummy_const(impl_block: proc_macro2::TokenStream) -> proc_macro::To /// # use parity_scale_codec::Encode as _; /// #[derive(Encode)] /// enum EnumType { -/// #[codec(index = "15")] +/// #[codec(index = 15)] /// A, /// #[codec(skip)] /// B, @@ -135,9 +135,9 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream Ok(input) => input, Err(e) => return e.to_compile_error().into(), }; - if let Some(span) = utils::get_skip(&input.attrs) { - return Error::new(span, "invalid attribute `skip` on root input") - .to_compile_error().into(); + + if let Err(e) = utils::check_attributes(&input) { + return e.to_compile_error().into(); } if let Err(e) = trait_bounds::add( @@ -176,9 +176,9 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream Ok(input) => input, Err(e) => return e.to_compile_error().into(), }; - if let Some(span) = utils::get_skip(&input.attrs) { - return Error::new(span, "invalid attribute `skip` on root input") - .to_compile_error().into(); + + if let Err(e) = utils::check_attributes(&input) { + return e.to_compile_error().into(); } if let Err(e) = trait_bounds::add( @@ -232,6 +232,10 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr Err(e) => return e.to_compile_error().into(), }; + if let Err(e) = utils::check_attributes(&input) { + return e.to_compile_error().into(); + } + if let Err(e) = trait_bounds::add( &input.ident, &mut input.generics, diff --git a/derive/src/utils.rs b/derive/src/utils.rs index 1e515102..f5cc509b 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -12,12 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Various internal utils. +//! +//! NOTE: attributes finder must be checked using check_attribute first, otherwise macro can panic. + use std::str::FromStr; use proc_macro2::{TokenStream, Span}; use syn::{ spanned::Spanned, - Meta, NestedMeta, Lit, Attribute, Variant, Field, + Meta, NestedMeta, Lit, Attribute, Variant, Field, DeriveInput, Fields, Data, FieldsUnnamed, + FieldsNamed, MetaNameValue }; fn find_meta_item<'a, F, R, I>(itr: I, pred: F) -> Option where @@ -26,7 +31,9 @@ fn find_meta_item<'a, F, R, I>(itr: I, pred: F) -> Option where { itr.filter_map(|attr| { if attr.path.is_ident("codec") { - if let Ok(Meta::List(ref meta_list)) = attr.parse_meta() { + if let Meta::List(ref meta_list) = attr.parse_meta() + .expect("Internal error, parse_meta must have been checked") + { return meta_list.nested.iter().filter_map(pred.clone()).next(); } } @@ -40,8 +47,9 @@ pub fn index(v: &Variant, i: usize) -> TokenStream { let index = find_meta_item(v.attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::NameValue(ref nv)) = meta { if nv.path.is_ident("index") { - if let Lit::Str(ref s) = nv.lit { - let byte: u8 = s.value().parse().expect("Numeric index expected."); + if let Lit::Int(ref v) = nv.lit { + let byte = v.base10_parse::() + .expect("Internal error, index attribute must have been checked"); return Some(byte) } } @@ -67,7 +75,7 @@ pub fn get_encoded_as_type(field_entry: &Field) -> Option { if let Lit::Str(ref s) = nv.lit { return Some( TokenStream::from_str(&s.value()) - .expect("`encoded_as` should be a valid rust type!") + .expect("Internal error, encoded_as attribute must have been checked") ); } } @@ -127,3 +135,120 @@ pub fn filter_skip_unnamed<'a>(fields: &'a syn::FieldsUnnamed) -> impl Iterator< .enumerate() .filter(|(_, f)| get_skip(&f.attrs).is_none()) } + +pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> { + for attr in &input.attrs { + check_top_attribute(attr)?; + } + + match input.data { + Data::Struct(ref data) => match &data.fields { + | Fields::Named(FieldsNamed { named: fields , .. }) + | Fields::Unnamed(FieldsUnnamed { unnamed: fields, .. }) => { + for field in fields { + for attr in &field.attrs { + check_field_attribute(attr)?; + } + } + } + Fields::Unit => (), + } + Data::Enum(ref data) => { + for variant in data.variants.iter() { + for attr in &variant.attrs { + check_variant_attribute(attr)?; + } + for field in &variant.fields { + for attr in &field.attrs { + check_field_attribute(attr)?; + } + } + } + }, + Data::Union(_) => (), + } + Ok(()) +} + +// Is accepted only: +// * `#[codec(skip)]` +// * `#[codec(compact)]` +// * `#[codec(encoded_as = "$EncodeAs")]` with $EncodedAs a valid TokenStream +fn check_field_attribute(attr: &Attribute) -> syn::Result<()> { + let field_error = "Invalid attribute on field, only `#[codec(skip)]`, `#[codec(compact)]` and \ + `#[codec(encoded_as = \"$EncodeAs\")]` are accepted."; + + if attr.path.is_ident("codec") { + match attr.parse_meta()? { + Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { + match meta_list.nested.first().unwrap() { + NestedMeta::Meta(Meta::Path(path)) + if path.get_ident().map_or(false, |i| i == "skip") => Ok(()), + + NestedMeta::Meta(Meta::Path(path)) + if path.get_ident().map_or(false, |i| i == "compact") => Ok(()), + + NestedMeta::Meta(Meta::NameValue(MetaNameValue { path, lit: Lit::Str(lit_str), .. })) + if path.get_ident().map_or(false, |i| i == "encoded_as") + => TokenStream::from_str(&lit_str.value()).map(|_| ()) + .map_err(|_e| syn::Error::new(lit_str.span(), "Invalid token stream")), + + elt @ _ => Err(syn::Error::new(elt.span(), field_error)), + } + }, + meta @ _ => Err(syn::Error::new(meta.span(), field_error)), + } + } else { + Ok(()) + } +} + +// Is accepted only: +// * `#[codec(skip)]` +// * `#[codec(index = $int)]` +fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { + let variant_error = "Invalid attribute on variant, only `#[codec(skip)]` and \ + `#[codec(index = $u8)]` are accepted."; + + if attr.path.is_ident("codec") { + match attr.parse_meta()? { + Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { + match meta_list.nested.first().unwrap() { + NestedMeta::Meta(Meta::Path(path)) + if path.get_ident().map_or(false, |i| i == "skip") => Ok(()), + + NestedMeta::Meta(Meta::NameValue(MetaNameValue { path, lit: Lit::Int(lit_int), .. })) + if path.get_ident().map_or(false, |i| i == "index") + => lit_int.base10_parse::().map(|_| ()) + .map_err(|_| syn::Error::new(lit_int.span(), "Index must be in 0..255")), + + elt @ _ => Err(syn::Error::new(elt.span(), variant_error)), + } + }, + meta @ _ => Err(syn::Error::new(meta.span(), variant_error)), + } + } else { + Ok(()) + } +} + +// Only `#[codec(dumb_trait_bound)]` is accepted as top attribute +fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { + let top_error = "Invalid attribute only `#[codec(dumb_trait_bound)]` is accepted as top \ + attribute"; + if attr.path.is_ident("codec") { + match attr.parse_meta()? { + Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { + match meta_list.nested.first().unwrap() { + NestedMeta::Meta(Meta::Path(path)) + if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => Ok(()), + + elt @ _ => Err(syn::Error::new(elt.span(), top_error)), + } + }, + meta @ _ => Err(syn::Error::new(meta.span(), top_error)), + } + } else { + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index 552efebc..536ac18f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -91,7 +91,7 @@ //! //! #[derive(Debug, PartialEq, Encode, Decode)] //! enum EnumType { -//! #[codec(index = "15")] +//! #[codec(index = 15)] //! A, //! B(u32, u64), //! C { @@ -217,12 +217,13 @@ //! fall back to just use the type parameters of the type. This can be useful for situation where //! the algorithm includes private types in the public interface. By using this attribute, you should //! not get this error/warning again. -//! - `codec(skip)`: Needs to be placed above a field and makes the field to be skipped while encoding/decoding. +//! - `codec(skip)`: Needs to be placed above a field or variant and makes it to be skipped while +//! encoding/decoding. //! - `codec(compact)`: Needs to be placed above a field and makes the field use compact encoding. //! (The type needs to support compact encoding.) -//! - `codec(encoded_as(OtherType))`: Needs to be placed above a field and makes the field being encoded +//! - `codec(encoded_as = "OtherType")`: Needs to be placed above a field and makes the field being encoded //! by using `OtherType`. -//! - `codec(index("0"))`: Needs to be placed above an enum variant to make the variant use the given +//! - `codec(index = 0)`: Needs to be placed above an enum variant to make the variant use the given //! index when encoded. By default the index is determined by counting from `0` beginning wth the //! first variant. //! diff --git a/tests/mod.rs b/tests/mod.rs index 54103ae2..f60064f2 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -47,7 +47,7 @@ impl Struct { #[derive(Debug, PartialEq, Encode, Decode)] enum EnumType { - #[codec(index = "15")] + #[codec(index = 15)] A, B(u32, u64), C { diff --git a/tests/variant_number.rs b/tests/variant_number.rs index 33e4995a..a7113712 100644 --- a/tests/variant_number.rs +++ b/tests/variant_number.rs @@ -31,7 +31,7 @@ fn skipped_variant_not_counted_in_default_index() { fn index_attr_variant_counted_and_reused_in_default_index() { #[derive(Encode)] enum T { - #[codec(index = "1")] + #[codec(index = 1)] A, B, } From 18b49a87441a4cee3dc9a83b9313600843ed41bc Mon Sep 17 00:00:00 2001 From: pscott <30843220+pscott@users.noreply.github.com> Date: Sun, 19 Apr 2020 14:49:59 +0200 Subject: [PATCH 015/286] Extend Fuzzer with Encoding (#191) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Verify bytes after encoding an object that was decoded from original bytes * Add BinaryHeapWrapper to allow PartialEq trait impl * Add Arbitrary crate and derives * Add prototype for encoding testing * Add partial encode fuzz testing * Derive arbitrary to compact * Add types for encode fuzzing * Simplify macro * Remove BitVec from Encoding macro * Add comments about sorting * Add comment for BinaryHeapWrapper * Update bytes sorting and move type display to the end * Make raw1 immutable * Hide arbitrary crate behind feature 'fuzz' * Indent macro * Impl Arbitrary for BitVecWrapper * Differentiate flows depending on fuzzing input * Update comments and add TODO * Change minimal to only_decode * Use more straightforward code for defining eq trait Co-Authored-By: Bastian Köcher * Put comments before derive Co-Authored-By: Bastian Köcher * Put comments before derive Co-Authored-By: Bastian Köcher * Use match in macros; Remove comments on into_iter_sorted and fix compile for paritaleq trait * Use match in fuzz_encode * Fix typo in comments * Apply suggestions from code review Co-Authored-By: Bastian Köcher * Remove useless mut Co-authored-by: Bastian Köcher --- Cargo.toml | 2 + fuzzer/Cargo.toml | 3 +- fuzzer/src/main.rs | 238 +++++++++++++++++++++++++++++++++++++++++---- src/compact.rs | 3 + 4 files changed, 227 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d1a20150..08ed2fbb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ parity-scale-codec-derive = { path = "derive", version = "1.2.0", default-featur bitvec = { version = "0.17.4", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "0.3.4", default-features = false, features = ["alloc"] } generic-array = { version = "0.13.2", optional = true } +arbitrary = { version = "0.4.1", features = ["derive"], optional = true } [dev-dependencies] criterion = "0.3.0" @@ -34,6 +35,7 @@ default = ["std"] derive = ["parity-scale-codec-derive"] std = ["serde", "bitvec/std", "byte-slice-cast/std"] bit-vec = ["bitvec"] +fuzz = ["std", "arbitrary"] # WARNING: DO _NOT_ USE THIS FEATURE IF YOU ARE WORKING ON CONSENSUS CODE!* # diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index a926ed42..51e48050 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" publish = false [dependencies] -parity-scale-codec = { path = "../", features = [ "derive", "bit-vec" ] } +parity-scale-codec = { path = "../", features = [ "derive", "bit-vec", "fuzz" ] } honggfuzz = "0.5.47" +arbitrary = { version = "0.4.1", features = ["derive"] } bitvec = { version = "0.17.4", features = ["alloc"] } diff --git a/fuzzer/src/main.rs b/fuzzer/src/main.rs index 151d337f..bacb8f37 100644 --- a/fuzzer/src/main.rs +++ b/fuzzer/src/main.rs @@ -1,37 +1,66 @@ use std::collections::{BTreeMap, BTreeSet, VecDeque, LinkedList, BinaryHeap}; use std::time::Duration; -use bitvec::{vec::BitVec, order::Msb0}; +use bitvec::{vec::BitVec, order::Msb0, order::BitOrder, store::BitStore}; use honggfuzz::fuzz; use parity_scale_codec::{Encode, Decode, Compact}; +use honggfuzz::arbitrary::{Arbitrary, Unstructured, Result as ArbResult}; -#[derive(Encode, Decode)] +#[derive(Encode, Decode, Clone, PartialEq, Debug, Arbitrary)] pub struct MockStruct{ vec_u: Vec } -#[derive(Encode, Decode)] +/// Used for implementing the Arbitrary trait for a BitVec. +#[derive(Encode, Decode, Clone, PartialEq, Debug)] +pub struct BitVecWrapper(BitVec); + +impl Arbitrary for BitVecWrapper { + fn arbitrary(u: &mut Unstructured<'_>) -> ArbResult { + let v = Vec::::arbitrary(u)?; + Ok(BitVecWrapper(BitVec::::from_vec(v))) + } +} + + +/// Used for implementing the PartialEq trait for a BinaryHeap. +#[derive(Encode, Decode, Debug, Clone, Arbitrary)] +struct BinaryHeapWrapper(BinaryHeap); + +impl PartialEq for BinaryHeapWrapper { + fn eq(&self, other: &BinaryHeapWrapper) -> bool { + self.0.clone().into_sorted_vec() == other.0.clone().into_sorted_vec() + } +} + +#[derive(Encode, Decode, Clone, PartialEq, Debug, Arbitrary)] pub enum MockEnum { Empty, Unit(u32), UnitVec(Vec), Complex { data: Vec, - map: BTreeMap<[u8; 32], Vec>, + bitvec: BitVecWrapper, string: String, }, Mock(MockStruct), NestedVec(Vec>>>>>>>>), } -macro_rules! fuzz_types { +/// `fuzz_flow` parameter can either be `round_trip` or `only_decode`. +/// `round_trip` will decode -> encode and compare the obtained encoded bytes with the original data. +/// `only_decode` will only decode, without trying to encode the decoded object. +/// `round_trip_sort` will decode -> encode and compare the obtained encoded SORTED bytes with the original SORTED data. +macro_rules! fuzz_decoder { ( + $fuzz_flow:ident; $data:ident; $first:ty, $( $rest:ty, )* ) => { - fuzz_types! { + fuzz_decoder! { @INTERNAL + $fuzz_flow; $data; 1u8; { $first; 0u8 } @@ -39,21 +68,73 @@ macro_rules! fuzz_types { } }; (@INTERNAL + $fuzz_flow:ident; $data:ident; $counter:expr; { $( $parsed:ty; $index:expr ),* } $current:ty, $( $rest:ty, )* ) => { - fuzz_types! { + fuzz_decoder! { @INTERNAL + $fuzz_flow; $data; $counter + 1u8; { $current; $counter $(, $parsed; $index )* } $( $rest, )* } }; + // round_trip flow arm. (@INTERNAL + round_trip; + $data:ident; + $counter:expr; + { $( $parsed:ty; $index:expr ),* } + ) => { + let num = $counter; + $( + if $data[0] % num == $index { + let mut d = &$data[1..]; + let raw1 = d.clone(); + let maybe_obj = <$parsed>::decode(&mut d); + + match maybe_obj { + Ok(obj) => { + let mut d2: &[u8] = &obj.encode(); + let raw2 = d2.clone(); + let exp_obj = <$parsed>::decode(&mut d2); + match exp_obj { + Ok(obj2) => { + if obj == obj2 { + let raw1_trunc_to_obj_size = &raw1[..raw1.len()-d.len()]; + if raw1_trunc_to_obj_size != raw2 { + println!("raw1 = {:?}", raw1); + println!("d (leftover/undecoded data) = {:?}", d); + println!("- Decoded data:"); + println!("raw1_trunc = {:?}", raw1_trunc_to_obj_size); + println!("raw2 = {:?}", raw2); + println!("- Encoded objects:"); + println!("obj1 = '{:?}'", obj); + println!("obj2 = '{:?}'", obj2); + println!("Type: {}", std::any::type_name::<$parsed>()); + panic!("raw1 != raw2"); + } + return + } else { + panic!("obj != obj2; obj={:?}, obj2={:?}", obj, obj2); + } + } + Err(e) => panic!("Shouldn’t happen: can't .decode() after .decode().encode(): {}", e), + } + } + Err(_) => return + } + } + )* + }; + // only_decode flow arm. + (@INTERNAL + only_decode; $data:ident; $counter:expr; { $( $parsed:ty; $index:expr ),* } @@ -61,18 +142,70 @@ macro_rules! fuzz_types { let num = $counter; $( if $data[0] % num == $index { - // Check that decode doesn't panic. + // Check that decode doesn't panic let _ = <$parsed>::decode(&mut &$data[1..]); return } )* + }; + // round_trip_sorted flow arm. + (@INTERNAL + round_trip_sorted; + $data:ident; + $counter:expr; + { $( $parsed:ty; $index:expr ),* } + ) => { + let num = $counter; + $( + if $data[0] % num == $index { + let mut d = &$data[1..]; + let raw1 = &d.clone(); - unreachable!() + let maybe_obj = <$parsed>::decode(&mut d); + match maybe_obj { + Ok(obj) => { + let d2 = obj.encode(); + let mut raw2 = d2.clone(); + // We are sorting here because we're in the "sorted" flow. Useful for container types + // which can have multiple valid encoded versions. + raw2.sort(); + let exp_obj = <$parsed>::decode(&mut &d2[..]); + match exp_obj { + Ok(obj2) => { + if obj == obj2 { + let mut raw1_trunc_to_obj_size = Vec::from(&raw1[..raw1.len() - d.len()]); + // Sorting here is necessary: see above comment. + raw1_trunc_to_obj_size.sort(); + if raw1_trunc_to_obj_size != raw2 { + println!("raw1 = {:?}", raw1); + println!("d (leftover/undecoded data) = {:?}", d); + println!("- Decoded data:"); + println!("raw1_trunc = {:?}", raw1_trunc_to_obj_size); + println!("raw2 = {:?}", raw2); + println!("- Encoded objects:"); + println!("obj1 = '{:?}'", obj); + println!("obj2 = '{:?}'", obj2); + println!("Type: {}", std::any::type_name::<$parsed>()); + panic!("raw1 != raw2"); + } + return + } + panic!("obj != obj2; obj={:?}, obj2={:?}", obj, obj2); + }, + Err(e) => panic!("Shouldn’t happen: can't .decode() after .decode().encode(): {}", e), + } + } + Err(_) => return, + } + } + )* }; } -fn fuzz_one_input(data: &[u8]){ - fuzz_types! { +fn fuzz_decode(data: &[u8]) { + // Types for which we wish to apply the "round_trip" method. + fuzz_decoder! { + round_trip; data; u8, u16, @@ -90,23 +223,92 @@ fn fuzz_one_input(data: &[u8]){ Option>, Vec, LinkedList, - BTreeMap>, - BTreeMap, - BTreeSet, VecDeque, - BinaryHeap, MockStruct, MockEnum, BitVec, BitVec, Duration, + }; + // Types for which we wish to apply the "sorted" method. + fuzz_decoder! { + round_trip_sorted; + data; + BinaryHeapWrapper, + }; + // Types for which we only wish to decode. + fuzz_decoder! { + only_decode; + data; + BTreeMap>, + BTreeMap, + BTreeSet, + }; +} + +macro_rules! fuzz_encoder { + () => {}; + ($( $type:ty, )*) => { + $(fuzz!(|data: $type| { fuzz_encode(data) });)* + }; +} + +fn fuzz_encode (data: T) { + let original = data.clone(); + let mut obj: &[u8] = &data.encode(); + let decoded = ::decode(&mut obj); + match decoded { + Ok(object) => { + if object != original { + println!("original object: {:?}", original); + println!("decoded object: {:?}", object); + panic!("Original object differs from decoded object") + } + } + Err(e) => { + println!("original object: {:?}", original); + println!("decoding error: {:?}", e); + panic!("Failed to decode the encoded object"); + } } } +macro_rules! fuzz_encoding { + () => { + fuzz_encoder! { + u8, + u16, + u32, + u64, + u128, + Compact, + Compact, + Compact, + Compact, + Compact, + String, + Vec, + Vec>, + Option>, + Vec, + LinkedList, + BTreeMap>, + BTreeMap, + BTreeSet, + VecDeque, + BinaryHeapWrapper, + MockStruct, + MockEnum, + BitVecWrapper, + BitVecWrapper, + Duration, + } + }; +} + fn main() { loop { - fuzz!(|data: &[u8]| { fuzz_one_input(data); }); + fuzz!(|data: &[u8]| { fuzz_decode(data); }); + fuzz_encoding!(); } } - - diff --git a/src/compact.rs b/src/compact.rs index ced22fcd..1b9d6752 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -19,6 +19,8 @@ use arrayvec::ArrayVec; use crate::alloc::vec::Vec; use crate::codec::{Encode, Decode, Input, Output, EncodeAsRef, Error}; use crate::encode_like::EncodeLike; +#[cfg(feature = "fuzz")] +use arbitrary::Arbitrary; struct ArrayVecWrapper(ArrayVec); @@ -75,6 +77,7 @@ pub trait CompactLen { /// Compact-encoded variant of T. This is more space-efficient but less compute-efficient. #[derive(Eq, PartialEq, Clone, Copy, Ord, PartialOrd)] +#[cfg_attr(feature = "fuzz", derive(Arbitrary))] pub struct Compact(pub T); impl From for Compact { From 6a6035003a42d34dadd31b06685a571eca2b5267 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 12 May 2020 19:02:56 +0200 Subject: [PATCH 016/286] Add decode length for tuple (#209) * decode_length for tuple' * add test * refactor --- src/codec.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/codec.rs b/src/codec.rs index ffebf6a2..65303b6d 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -1017,6 +1017,12 @@ macro_rules! tuple_impl { } } + impl<$one: DecodeLength> DecodeLength for ($one,) { + fn len(self_encoded: &[u8]) -> Result { + $one::len(self_encoded) + } + } + impl<$one: EncodeLike<$extra>, $extra: Encode> crate::EncodeLike<($extra,)> for ($one,) {} }; (($first:ident, $fextra:ident), $( ( $rest:ident, $rextra:ident ), )+) => { @@ -1060,6 +1066,12 @@ macro_rules! tuple_impl { $($rest: EncodeLike<$rextra>, $rextra: Encode),+> crate::EncodeLike<($fextra, $( $rextra ),+)> for ($first, $($rest),+) {} + impl<$first: DecodeLength, $($rest),+> DecodeLength for ($first, $($rest),+) { + fn len(self_encoded: &[u8]) -> Result { + $first::len(self_encoded) + } + } + tuple_impl!( $( ($rest, $rextra), )+ ); } } @@ -1288,6 +1300,8 @@ mod tests { let mut ll = LinkedList::new(); ll.push_back(1); ll.push_back(2); + let t1: (Vec<_>,) = (vector.clone(),); + let t2: (Vec<_>, u32) = (vector.clone(), 3u32); test_encode_length(&vector, 10); test_encode_length(&btree_map, 2); @@ -1295,6 +1309,8 @@ mod tests { test_encode_length(&vd, 2); test_encode_length(&bh, 2); test_encode_length(&ll, 2); + test_encode_length(&t1, 10); + test_encode_length(&t2, 10); } #[test] From 353db2cf1e417e1d0216e882dc0fb74c769f4a56 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 30 May 2020 19:48:37 -0400 Subject: [PATCH 017/286] Use proper span when emitting 'self' identifier (#210) Normally, the span of a field has the same hygiene context as `Span::call_site`. However, it's possible for a struct definition to be 'constructed' via a `macro_rules` macro such that the field has a different hygiene context. This will cause the expanded code to be unable to resolve any references to `self`, resulting in a compilation error. This pull request uses `quote!` instead of `quote_spanned!` when emitting a 'self' identifier. `quote_spanned!` is still used for everything else in the emitted method, meaning that error messages will still point to the proper field. I've included a test case which triggers this issue on Rust 1.43.1. It's current difficult to hit this issue other than in this artificial case, but that will change once rust-lang/rust#72622 is re-landed. --- derive/src/encode.rs | 9 ++++++--- tests/mod.rs | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/derive/src/encode.rs b/derive/src/encode.rs index 834d389b..d55b87c6 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -70,16 +70,19 @@ fn encode_single_field( } }; + // This may have different hygiene than the field span + let i_self = quote! { self }; + quote_spanned! { field.span() => - fn encode_to(&self, dest: &mut EncOut) { + fn encode_to(&#i_self, dest: &mut EncOut) { _parity_scale_codec::Encode::encode_to(&#final_field_variable, dest) } - fn encode(&self) -> _parity_scale_codec::alloc::vec::Vec { + fn encode(&#i_self) -> _parity_scale_codec::alloc::vec::Vec { _parity_scale_codec::Encode::encode(&#final_field_variable) } - fn using_encoded R>(&self, f: F) -> R { + fn using_encoded R>(&#i_self, f: F) -> R { _parity_scale_codec::Encode::using_encoded(&#final_field_variable, f) } } diff --git a/tests/mod.rs b/tests/mod.rs index f60064f2..1de00f31 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -526,3 +526,18 @@ fn crafted_input_for_vec_t() { ); } +#[test] +fn weird_derive() { + // Tests that compilation succeeds when the macro invocation + // hygiene context is different from the field hygiene context. + macro_rules! make_struct { + (#[$attr:meta]) => ( + #[$attr] + pub struct MyStruct { + field: u8 + } + ) + } + + make_struct!(#[derive(Encode, Decode)]); +} From 9e761dbc500ad39878e158083813af8ba0917dec Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 3 Jun 2020 10:09:13 +0200 Subject: [PATCH 018/286] BitVec decode can allocate unbounded vector on wrong input. (#211) * fix * better impl --- src/bit_vec.rs | 11 ++++++++--- src/codec.rs | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/bit_vec.rs b/src/bit_vec.rs index ce3efcc8..22a95a61 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -19,7 +19,7 @@ use core::mem; use bitvec::{vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox}; use byte_slice_cast::{AsByteSlice, ToByteSlice, FromByteSlice, Error as FromByteSliceError}; -use crate::codec::{Encode, Decode, Input, Output, Error}; +use crate::codec::{Encode, Decode, Input, Output, Error, read_vec_u8}; use crate::compact::Compact; use crate::EncodeLike; @@ -60,9 +60,9 @@ impl Decode for BitVec { fn decode(input: &mut I) -> Result { >::decode(input).and_then(move |Compact(bits)| { let bits = bits as usize; + let required_bytes = required_bytes::(bits); - let mut vec = vec![0; required_bytes::(bits)]; - input.read(&mut vec)?; + let vec = read_vec_u8(input, required_bytes)?; let mut result = Self::from_slice(T::from_byte_slice(&vec)?); assert!(bits <= result.len()); @@ -96,6 +96,7 @@ fn required_bytes(bits: usize) -> usize { mod tests { use super::*; use bitvec::{bitvec, order::Msb0}; + use crate::codec::MAX_PREALLOCATION; macro_rules! test_data { ($inner_type:ident) => ( @@ -123,6 +124,10 @@ mod tests { bitvec![Msb0, $inner_type; 0; 63], bitvec![Msb0, $inner_type; 1; 64], bitvec![Msb0, $inner_type; 0; 65], + bitvec![Msb0, $inner_type; 1; MAX_PREALLOCATION * 8 + 1], + bitvec![Msb0, $inner_type; 0; MAX_PREALLOCATION * 9], + bitvec![Msb0, $inner_type; 1; MAX_PREALLOCATION * 32 + 1], + bitvec![Msb0, $inner_type; 0; MAX_PREALLOCATION * 33], ] ) } diff --git a/src/codec.rs b/src/codec.rs index 65303b6d..2ff28fb8 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -50,7 +50,7 @@ use crate::alloc::{ use crate::compact::Compact; use crate::encode_like::EncodeLike; -const MAX_PREALLOCATION: usize = 4 * 1024; +pub(crate) const MAX_PREALLOCATION: usize = 4 * 1024; const A_BILLION: u32 = 1_000_000_000; /// Descriptive error type @@ -775,7 +775,7 @@ impl Encode for [T] { } /// Read an `u8` vector from the given input. -fn read_vec_u8(input: &mut I, len: usize) -> Result, Error> { +pub(crate) fn read_vec_u8(input: &mut I, len: usize) -> Result, Error> { let input_len = input.remaining_len()?; // If there is input len and it cannot be pre-allocated then return directly. From e8cd17dd1fac20c35c6433cc598d649ea330dc44 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 3 Jun 2020 15:26:43 +0200 Subject: [PATCH 019/286] IoReader suppose Seek impl to be of fixed len, substrate usage is otherwise (#212) Seek trait doesn't ensure that the length is fixed, thus our usage in IoReader is wrong. Now fixed. --- src/codec.rs | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index 2ff28fb8..3b8962c2 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -177,29 +177,14 @@ impl From for Error { } } -/// Wrapper that implements Input for any `Read` and `Seek` type. +/// Wrapper that implements Input for any `Read` type. #[cfg(feature = "std")] -pub struct IoReader(pub R); +pub struct IoReader(pub R); #[cfg(feature = "std")] -impl Input for IoReader { +impl Input for IoReader { fn remaining_len(&mut self) -> Result, Error> { - use std::convert::TryInto; - use std::io::SeekFrom; - - let old_pos = self.0.seek(SeekFrom::Current(0))?; - let len = self.0.seek(SeekFrom::End(0))?; - - // Avoid seeking a third time when we were already at the end of the - // stream. The branch is usually way cheaper than a seek operation. - if old_pos != len { - self.0.seek(SeekFrom::Start(old_pos))?; - } - - len.saturating_sub(old_pos) - .try_into() - .map_err(|_| "Input cannot fit into usize length".into()) - .map(Some) + Ok(None) } fn read(&mut self, into: &mut [u8]) -> Result<(), Error> { @@ -1407,21 +1392,15 @@ mod tests { #[test] fn io_reader() { - use std::io::{Seek, SeekFrom}; - let mut io_reader = IoReader(std::io::Cursor::new(&[1u8, 2, 3][..])); - assert_eq!(io_reader.0.seek(SeekFrom::Current(0)).unwrap(), 0); - assert_eq!(io_reader.remaining_len().unwrap().unwrap(), 3); - - assert_eq!(io_reader.read_byte().unwrap(), 1); - assert_eq!(io_reader.0.seek(SeekFrom::Current(0)).unwrap(), 1); - assert_eq!(io_reader.remaining_len().unwrap().unwrap(), 2); + let mut v = [0; 2]; + io_reader.read(&mut v[..]).unwrap(); + assert_eq!(v, [1, 2]); - assert_eq!(io_reader.read_byte().unwrap(), 2); assert_eq!(io_reader.read_byte().unwrap(), 3); - assert_eq!(io_reader.0.seek(SeekFrom::Current(0)).unwrap(), 3); - assert_eq!(io_reader.remaining_len().unwrap().unwrap(), 0); + + assert_eq!(io_reader.read_byte(), Err("io error: UnexpectedEof".into())); } #[test] From 50c50b3fd7c93d9b98b65219208793d4ecb82acd Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Fri, 19 Jun 2020 17:35:48 +0200 Subject: [PATCH 020/286] Decode with depth limit (#214) --- src/codec.rs | 24 +++++++++- src/decode_all.rs | 2 +- src/depth_limit.rs | 108 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 +- 4 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 src/depth_limit.rs diff --git a/src/codec.rs b/src/codec.rs index 3b8962c2..916f3880 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -131,6 +131,18 @@ pub trait Input { self.read(&mut buf[..])?; Ok(buf[0]) } + + /// Descend into nested reference when decoding. + /// This is called when decoding a new refence-based instance, + /// such as `Vec` or `Box`. Currently all such types are + /// allocated on the heap. + fn descend_ref(&mut self) -> Result<(), Error> { + Ok(()) + } + + /// Ascend to previous structure level when decoding. + /// This is called when decoding reference-based type is finished. + fn ascend_ref(&mut self) {} } impl<'a> Input for &'a [u8] { @@ -405,7 +417,10 @@ impl Decode for X where X: WrapperTypeDecode, { fn decode(input: &mut I) -> Result { - Ok(T::decode(input)?.into()) + input.descend_ref()?; + let result = Ok(T::decode(input)?.into()); + input.ascend_ref(); + result } } @@ -831,9 +846,11 @@ impl Decode for Vec { .checked_div(mem::size_of::()) .unwrap_or(0); let mut r = Vec::with_capacity(input_capacity.min(len)); + input.descend_ref()?; for _ in 0..len { r.push(T::decode(input)?); } + input.ascend_ref(); Ok(r) }, } @@ -867,7 +884,10 @@ macro_rules! impl_codec_through_iterator { { fn decode(input: &mut I) -> Result { >::decode(input).and_then(move |Compact(len)| { - Result::from_iter((0..len).map(|_| Decode::decode(input))) + input.descend_ref()?; + let result = Result::from_iter((0..len).map(|_| Decode::decode(input))); + input.ascend_ref(); + result }) } } diff --git a/src/decode_all.rs b/src/decode_all.rs index 1407aa2d..9ac65a9c 100644 --- a/src/decode_all.rs +++ b/src/decode_all.rs @@ -15,7 +15,7 @@ use crate::codec::{Error, Decode}; /// The error message returned when `decode_all` fails. -const DECODE_ALL_ERR_MSG: &str = "Input buffer has still data left after decoding!"; +pub(crate) const DECODE_ALL_ERR_MSG: &str = "Input buffer has still data left after decoding!"; /// Extension trait to [`Decode`] that ensures that the given input data is consumed completly while /// decoding. diff --git a/src/depth_limit.rs b/src/depth_limit.rs new file mode 100644 index 00000000..55d8d649 --- /dev/null +++ b/src/depth_limit.rs @@ -0,0 +1,108 @@ +// Copyright 2017, 2018 Parity Technologies +// +// 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 crate::codec::{Error, Decode, Input}; + +/// The error message returned when depth limit is reached. +const DECODE_MAX_DEPTH_MSG: &str = "Maximum recursion depth reached when decoding"; + +/// Extension trait to [`Decode`] that ensures that the given input data is consumed completly while +/// decoding. +pub trait DecodeLimit: Sized { + /// Decode `Self` with given maximum recursion depth. + /// is returned. + fn decode_with_depth_limit(limit: u32, input: &[u8]) -> Result; + /// Decode `Self` and consume all of the given input data. If not all data is consumed, an error + /// is returned. + fn decode_all_with_depth_limit(limit: u32, input: &[u8]) -> Result; +} + + +struct DepthTrackingInput<'a, I> { + input: &'a mut I, + depth: u32, + max_depth: u32, +} + +impl<'a, I:Input> Input for DepthTrackingInput<'a, I> { + fn remaining_len(&mut self) -> Result, Error> { + self.input.remaining_len() + } + + fn read(&mut self, into: &mut [u8]) -> Result<(), Error> { + self.input.read(into) + } + + fn read_byte(&mut self) -> Result { + self.input.read_byte() + } + + fn descend_ref(&mut self) -> Result<(), Error> { + self.input.descend_ref()?; + self.depth += 1; + if self.depth > self.max_depth { + Err(DECODE_MAX_DEPTH_MSG.into()) + } else { + Ok(()) + } + } + + fn ascend_ref(&mut self) { + self.input.ascend_ref(); + self.depth -= 1; + } +} + +impl DecodeLimit for T { + fn decode_all_with_depth_limit(limit: u32, input: &[u8]) -> Result { + let mut input = DepthTrackingInput { + input: &mut &input[..], + depth: 0, + max_depth: limit, + }; + let res = T::decode(&mut input)?; + + if input.input.is_empty() { + Ok(res) + } else { + Err(crate::decode_all::DECODE_ALL_ERR_MSG.into()) + } + } + + fn decode_with_depth_limit(limit: u32, input: &[u8]) -> Result { + let mut input = DepthTrackingInput { + input: &mut &input[..], + depth: 0, + max_depth: limit, + }; + T::decode(&mut input) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::Encode; + + #[test] + fn decode_limit_works() { + type NestedVec = Vec>>>; + let nested: NestedVec = vec![vec![vec![vec![1]]]]; + let encoded = nested.encode(); + + let decoded = NestedVec::decode_with_depth_limit(3, &encoded).unwrap(); + assert_eq!(decoded, nested); + assert!(NestedVec::decode_with_depth_limit(2, &encoded).is_err()); + } +} diff --git a/src/lib.rs b/src/lib.rs index 536ac18f..31381087 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -270,12 +270,13 @@ mod bit_vec; #[cfg(feature = "generic-array")] mod generic_array; mod decode_all; +mod depth_limit; mod encode_append; mod encode_like; pub use self::codec::{ Input, Output, Error, Decode, Encode, Codec, EncodeAsRef, WrapperTypeEncode, - WrapperTypeDecode, OptionBool, DecodeLength, FullCodec, FullEncode, + OptionBool, DecodeLength, FullCodec, FullEncode, }; #[cfg(feature = "std")] pub use self::codec::IoReader; @@ -283,5 +284,6 @@ pub use self::compact::{Compact, HasCompact, CompactAs, CompactLen}; pub use self::joiner::Joiner; pub use self::keyedvec::KeyedVec; pub use self::decode_all::DecodeAll; +pub use self::depth_limit::DecodeLimit; pub use self::encode_append::EncodeAppend; pub use self::encode_like::{EncodeLike, Ref}; From a54a3dd86407953162d5f4b65a45fe6f7d69f789 Mon Sep 17 00:00:00 2001 From: kaichao Date: Tue, 7 Jul 2020 17:11:37 +0800 Subject: [PATCH 021/286] fix docs link (#215) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f755f124..a3fe3548 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The encoded data does not include this contextual information. To get a better understanding of how the encoding is done for different types, take a look at the -[low-level data formats overview page at the Substrate docs site](https://substrate.dev/docs/en/overview/low-level-data-format). +[low-level data formats overview page at the Substrate docs site](https://substrate.dev/docs/en/knowledgebase/advanced/codec). ## Implementation @@ -45,7 +45,7 @@ Returns an `Err` if the decoding fails. ### CompactAs The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes them even more space/memory efficient. -The compact encoding is described [here](https://substrate.dev/docs/en/overview/low-level-data-format#compactgeneral-integers). +The compact encoding is described [here](https://substrate.dev/docs/en/knowledgebase/advanced/codec#compactgeneral-integers). * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. The type `As` is defined in the same trait and its implementation should be compact encode-able. From 3a0dbc3235933db16e9df11429d84b159996d4f5 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Thu, 10 Sep 2020 11:13:30 +0200 Subject: [PATCH 022/286] Fix name conflict in derive macros (#222) --- derive/src/decode.rs | 24 +++++++++++++----------- derive/src/encode.rs | 11 +++++++---- derive/src/lib.rs | 6 +++--- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/derive/src/decode.rs b/derive/src/decode.rs index f807519f..f3d1c4a1 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -55,7 +55,7 @@ pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream ); quote_spanned! { v.span() => - x if x == #index as u8 => { + __codec_x_edqy if __codec_x_edqy == #index as u8 => { #create }, } @@ -65,7 +65,7 @@ pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream quote! { match #input.read_byte()? { #( #recurse )* - x => Err(#err_msg.into()), + _ => Err(#err_msg.into()), } } @@ -79,6 +79,8 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt let compact = utils::get_enable_compact(field); let skip = utils::get_skip(&field.attrs).is_some(); + let res = quote!(__codec_res_edqy); + if encoded_as.is_some() as u8 + compact as u8 + skip as u8 > 1 { return Error::new( field.span(), @@ -92,22 +94,22 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt let field_type = &field.ty; quote_spanned! { field.span() => { - let res = < + let #res = < <#field_type as _parity_scale_codec::HasCompact>::Type as _parity_scale_codec::Decode >::decode(#input); - match res { + match #res { Err(_) => return Err(#err_msg.into()), - Ok(a) => a.into(), + Ok(#res) => #res.into(), } } } } else if let Some(encoded_as) = encoded_as { quote_spanned! { field.span() => { - let res = <#encoded_as as _parity_scale_codec::Decode>::decode(#input); - match res { + let #res = <#encoded_as as _parity_scale_codec::Decode>::decode(#input); + match #res { Err(_) => return Err(#err_msg.into()), - Ok(a) => a.into(), + Ok(#res) => #res.into(), } } } @@ -116,10 +118,10 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt } else { quote_spanned! { field.span() => { - let res = _parity_scale_codec::Decode::decode(#input); - match res { + let #res = _parity_scale_codec::Decode::decode(#input); + match #res { Err(_) => return Err(#err_msg.into()), - Ok(a) => a, + Ok(#res) => #res, } } } diff --git a/derive/src/encode.rs b/derive/src/encode.rs index d55b87c6..ba55a40f 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -74,8 +74,11 @@ fn encode_single_field( let i_self = quote! { self }; quote_spanned! { field.span() => - fn encode_to(&#i_self, dest: &mut EncOut) { - _parity_scale_codec::Encode::encode_to(&#final_field_variable, dest) + fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output>( + &#i_self, + __codec_dest_edqy: &mut __CodecOutputEdqy + ) { + _parity_scale_codec::Encode::encode_to(&#final_field_variable, __codec_dest_edqy) } fn encode(&#i_self) -> _parity_scale_codec::alloc::vec::Vec { @@ -176,7 +179,7 @@ fn try_impl_encode_single_field_optimisation(data: &Data) -> Option fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { let self_ = quote!(self); - let dest = "e!(dest); + let dest = "e!(__codec_dest_edqy); let encoding = match *data { Data::Struct(ref data) => { match data.fields { @@ -285,7 +288,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { }; quote! { - fn encode_to(&#self_, #dest: &mut EncOut) { + fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output>(&#self_, #dest: &mut __CodecOutputEdqy) { #encoding } } diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 087a3685..3a0fbc15 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -195,13 +195,13 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let name = &input.ident; let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - let input_ = quote!(input); + let input_ = quote!(__codec_input_edqy); let decoding = decode::quote(&input.data, name, &input_); let impl_block = quote! { impl #impl_generics _parity_scale_codec::Decode for #name #ty_generics #where_clause { - fn decode( - #input_: &mut DecIn + fn decode<__CodecInputEdqy: _parity_scale_codec::Input>( + #input_: &mut __CodecInputEdqy ) -> core::result::Result { #decoding } From 6f8f5422c82033fd47b5802d441db8bc2c22cacb Mon Sep 17 00:00:00 2001 From: Vladislav Date: Fri, 25 Sep 2020 15:55:30 +0300 Subject: [PATCH 023/286] Export `WrapperTypeDecode` from lib.rs (#223) --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 31381087..af581489 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -275,7 +275,7 @@ mod encode_append; mod encode_like; pub use self::codec::{ - Input, Output, Error, Decode, Encode, Codec, EncodeAsRef, WrapperTypeEncode, + Input, Output, Error, Decode, Encode, Codec, EncodeAsRef, WrapperTypeEncode, WrapperTypeDecode, OptionBool, DecodeLength, FullCodec, FullEncode, }; #[cfg(feature = "std")] From e456502fd79c35ce187b6566f4d479d588bd13f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Tue, 6 Oct 2020 13:43:45 +0100 Subject: [PATCH 024/286] fix typo in error message (#225) --- src/codec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codec.rs b/src/codec.rs index 916f3880..c75b3540 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -558,7 +558,7 @@ impl Decode for Option { match input.read_byte()? { 0 => Ok(None), 1 => Ok(Some(T::decode(input)?)), - _ => Err("unexpecded first byte decoding Option".into()), + _ => Err("unexpected first byte decoding Option".into()), } } } From c860966ec0b2123eaf4169251c5702963a073d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 6 Oct 2020 14:43:56 +0200 Subject: [PATCH 025/286] Implement Encode and Decode for empty arrays (#224) --- src/codec.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/codec.rs b/src/codec.rs index c75b3540..ef8229d9 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -328,6 +328,8 @@ impl FullCodec for S {} /// Such types should not carry any additional information /// that would require to be encoded, because the encoding /// is assumed to be the same as the wrapped type. +/// +/// The wrapped type that is referred to is the [`Deref::Target`]. pub trait WrapperTypeEncode: Deref {} impl WrapperTypeEncode for Box {} @@ -665,7 +667,7 @@ macro_rules! impl_array { } impl_array!( - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, @@ -1567,4 +1569,12 @@ mod tests { let obj = ::decode(&mut bytes); assert!(obj.is_err()); } + + #[test] + fn empty_array_encode_and_decode() { + let data: [u32; 0] = []; + let encoded = data.encode(); + assert!(encoded.is_empty()); + <[u32; 0]>::decode(&mut &encoded[..]).unwrap(); + } } From 783a96014dfdc4cf9747ada84ec7ec98e9a31b3b Mon Sep 17 00:00:00 2001 From: stephaneyfx Date: Thu, 8 Oct 2020 02:02:50 -0700 Subject: [PATCH 026/286] Always implement Display for Error (#226) This makes it easier to write code that uses `Error` with or without `std`. --- src/codec.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index ef8229d9..0a032b04 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -14,8 +14,7 @@ //! Serialisation. -#[cfg(feature = "std")] -use std::fmt; +use core::fmt; use core::{mem, ops::Deref, marker::PhantomData, iter::FromIterator, convert::TryFrom, time::Duration}; use core::num::{ NonZeroI8, @@ -84,12 +83,19 @@ impl Error { } #[cfg(feature = "std")] -impl std::fmt::Display for Error { +impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) } } +#[cfg(not(feature = "std"))] +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Error") + } +} + #[cfg(feature = "std")] impl std::error::Error for Error { fn description(&self) -> &str { @@ -501,8 +507,8 @@ impl Decode for Result { #[derive(Eq, PartialEq, Clone, Copy)] pub struct OptionBool(pub Option); -impl core::fmt::Debug for OptionBool { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { +impl fmt::Debug for OptionBool { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } From 9b9a8f600acb7ef15c2a3c2c3ee48cb2e4f8ea60 Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Fri, 16 Oct 2020 16:42:08 +0200 Subject: [PATCH 027/286] change (ci): new CI image; target caching (#213) --- .gitlab-ci.yml | 107 ++++++++++++++++++++----------------------------- 1 file changed, 44 insertions(+), 63 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9c7405e3..92d6d9ff 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,24 +5,14 @@ stages: - test - build - -image: parity/rust-builder:latest - variables: GIT_STRATEGY: fetch - CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_JOB_NAME}" - SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache" CARGO_INCREMENTAL: 0 + GIT_DEPTH: 3 + CARGO_TARGET_DIR: "/ci-cache/${CI_PROJECT_NAME}/targets/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" CI_SERVER_NAME: "GitLab CI" - -#### stage: test - -test-rust-stable: - stage: test - script: - - time cargo test --verbose --all --features bit-vec,generic-array,derive - - sccache -s +.only: &only only: - triggers - tags @@ -30,94 +20,85 @@ test-rust-stable: - schedules - web - /^[0-9]+$/ + +.docker-env: &docker-env + image: paritytech/ci-linux:production + before_script: + - cargo -vV + - rustc -vV + - rustup show + - cargo --version + - sccache -s + dependencies: [] + interruptible: true + retry: + max: 2 + when: + - runner_system_failure + - unknown_failure + - api_failure tags: - linux-docker +#### stage: test + +test-rust-stable: + stage: test + <<: *only + <<: *docker-env + script: + - time cargo test --verbose --all --features bit-vec,generic-array,derive + - sccache -s + test-rust-stable-no_derive: stage: test + <<: *only + <<: *docker-env script: - time cargo test --verbose --features bit-vec,generic-array - sccache -s - only: - - triggers - - tags - - master - - schedules - - web - - /^[0-9]+$/ - tags: - - linux-docker check-rust-stable-no_derive_no_std_full: stage: test + <<: *only + <<: *docker-env script: - time cargo check --verbose --no-default-features --features bit-vec,generic-array,full - sccache -s - only: - - triggers - - tags - - master - - schedules - - web - - /^[0-9]+$/ - tags: - - linux-docker check-rust-stable-no_derive_no_std: stage: test + <<: *only + <<: *docker-env script: - time cargo check --verbose --no-default-features --features bit-vec,generic-array - sccache -s - only: - - triggers - - tags - - master - - schedules - - web - - /^[0-9]+$/ - tags: - - linux-docker check-rust-stable-no_derive_full: stage: test + <<: *only + <<: *docker-env script: - time cargo check --verbose --features bit-vec,generic-array,full - sccache -s - only: - - triggers - - tags - - master - - schedules - - web - - /^[0-9]+$/ - tags: - - linux-docker bench-rust-nightly: stage: test + <<: *only + <<: *docker-env script: - time cargo +nightly bench --features bit-vec,generic-array,derive - sccache -s - only: - - triggers - - tags - - master - - schedules - - web - - /^[0-9]+$/ - tags: - - linux-docker #### stage: build build-linux-ubuntu-amd64: stage: build - script: - - cargo build --verbose --release --features bit-vec,generic-array,derive - - sccache -s + <<: *docker-env only: - master - tags - web - tags: - - linux-docker + script: + - cargo build --verbose --release --features bit-vec,generic-array,derive + - sccache -s From 934bc35a902e4fdf9496ededb5af7a7f0e8e1fe3 Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Fri, 16 Oct 2020 17:04:13 +0200 Subject: [PATCH 028/286] Fix typo in unknown io error variant (#227) --- src/codec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codec.rs b/src/codec.rs index 0a032b04..c7309ea8 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -190,7 +190,7 @@ impl From for Error { Interrupted => "io error: Interrupted".into(), Other => "io error: Other".into(), UnexpectedEof => "io error: UnexpectedEof".into(), - _ => "io error: Unkown".into(), + _ => "io error: Unknown".into(), } } } From e28160a101d6b914238e1b1c34b4ff4f785a512e Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Fri, 16 Oct 2020 17:15:49 +0200 Subject: [PATCH 029/286] CI improvements (#228) * change (CI): cache pre-population script; use of cargo home and cargo target caches; rules instead only * fix (CI): wrong pasta * fix (CI): persimmons to the pre_pop script --- .gitlab-ci.yml | 44 ++++++++++++++++++++++---------------------- scripts/pre_cache.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 22 deletions(-) create mode 100755 scripts/pre_cache.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 92d6d9ff..8ee741b3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,19 +7,16 @@ stages: variables: GIT_STRATEGY: fetch - CARGO_INCREMENTAL: 0 - GIT_DEPTH: 3 + GIT_DEPTH: "100" + CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" CARGO_TARGET_DIR: "/ci-cache/${CI_PROJECT_NAME}/targets/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" + CARGO_INCREMENTAL: 0 CI_SERVER_NAME: "GitLab CI" -.only: &only - only: - - triggers - - tags - - master - - schedules - - web - - /^[0-9]+$/ +workflow: + rules: + - if: $CI_COMMIT_TAG + - if: $CI_COMMIT_BRANCH .docker-env: &docker-env image: paritytech/ci-linux:production @@ -27,9 +24,17 @@ variables: - cargo -vV - rustc -vV - rustup show - - cargo --version + - bash --version + - ./scripts/pre_cache.sh - sccache -s - dependencies: [] + rules: + - if: $CI_PIPELINE_SOURCE == "trigger" + - if: $CI_PIPELINE_SOURCE == "web" + - if: $CI_PIPELINE_SOURCE == "schedule" + - if: $CI_COMMIT_REF_NAME == "master" + - if: $CI_COMMIT_REF_NAME == "tags" + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 interruptible: true retry: max: 2 @@ -44,7 +49,6 @@ variables: test-rust-stable: stage: test - <<: *only <<: *docker-env script: - time cargo test --verbose --all --features bit-vec,generic-array,derive @@ -52,7 +56,6 @@ test-rust-stable: test-rust-stable-no_derive: stage: test - <<: *only <<: *docker-env script: - time cargo test --verbose --features bit-vec,generic-array @@ -60,7 +63,6 @@ test-rust-stable-no_derive: check-rust-stable-no_derive_no_std_full: stage: test - <<: *only <<: *docker-env script: - time cargo check --verbose --no-default-features --features bit-vec,generic-array,full @@ -68,7 +70,6 @@ check-rust-stable-no_derive_no_std_full: check-rust-stable-no_derive_no_std: stage: test - <<: *only <<: *docker-env script: - time cargo check --verbose --no-default-features --features bit-vec,generic-array @@ -76,7 +77,6 @@ check-rust-stable-no_derive_no_std: check-rust-stable-no_derive_full: stage: test - <<: *only <<: *docker-env script: - time cargo check --verbose --features bit-vec,generic-array,full @@ -84,7 +84,6 @@ check-rust-stable-no_derive_full: bench-rust-nightly: stage: test - <<: *only <<: *docker-env script: - time cargo +nightly bench --features bit-vec,generic-array,derive @@ -95,10 +94,11 @@ bench-rust-nightly: build-linux-ubuntu-amd64: stage: build <<: *docker-env - only: - - master - - tags - - web + rules: + - if: $CI_PIPELINE_SOURCE == "web" + - if: $CI_PIPELINE_SOURCE == "schedule" + - if: $CI_COMMIT_REF_NAME == "master" + - if: $CI_COMMIT_REF_NAME == "tags" script: - cargo build --verbose --release --features bit-vec,generic-array,derive - sccache -s diff --git a/scripts/pre_cache.sh b/scripts/pre_cache.sh new file mode 100755 index 00000000..b6074a5c --- /dev/null +++ b/scripts/pre_cache.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -u + +# if there is no directory for this $CI_COMMIT_REF_NAME/$CI_JOB_NAME +# create such directory and +# copy recursively all the files from the newest dir which has $CI_JOB_NAME, if it exists + +# caches are in /ci-cache/${CI_PROJECT_NAME}/${2}/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME} + +function prepopulate { + if [[ ! -d $1 ]]; then + mkdir -p "/ci-cache/$CI_PROJECT_NAME/$2/$CI_COMMIT_REF_NAME"; + FRESH_CACHE=$(find "/ci-cache/$CI_PROJECT_NAME/$2" -mindepth 2 -maxdepth 2 \ + -type d -name "$CI_JOB_NAME" -exec stat --printf="%Y\t%n\n" {} \; |sort -n -r |head -1 |cut -f2); + if [[ -d $FRESH_CACHE ]]; then + echo "____Using" "$FRESH_CACHE" "to prepopulate the cache____"; + time cp -r "$FRESH_CACHE" "$1"; + else + echo "_____No such $2 dir, proceeding from scratch_____"; + fi + else + echo "____No need to prepopulate $2 cache____"; + fi +} + +# CARGO_HOME cache was moved to the same "project/cache_type/branch_name/job_name" level as +# CARGO_TARGET_DIR because of frequent weird data-race issues. This just means that the same cache that +# would have been used for the entire pipeline will be duplicated for the each job. +prepopulate "$CARGO_HOME" cargo +prepopulate "$CARGO_TARGET_DIR" targets From 9e966cb30c391fbdbc31796ec14d1c1aafa61034 Mon Sep 17 00:00:00 2001 From: Shirshak Date: Thu, 12 Nov 2020 03:41:35 -0500 Subject: [PATCH 030/286] [docs] update broken link (#229) --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index af581489..22273f21 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ //! //! To get a better understanding of how the encoding is done for different types, //! take a look at the -//! [low-level data formats overview page at the Substrate docs site](https://substrate.dev/docs/en/overview/low-level-data-format). +//! [SCALE Code page at the Substrate Knowledge Base](https://substrate.dev/docs/en/knowledgebase/advanced/codec). //! //! ## Implementation //! @@ -60,7 +60,7 @@ //! ### CompactAs //! //! The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes them even more space/memory efficient. -//! The compact encoding is described [here](https://substrate.dev/docs/en/overview/low-level-data-format#compact-general-integers). +//! The compact encoding is described [here](https://substrate.dev/docs/en/knowledgebase/advanced/codec#compactgeneral-integers). //! //! * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. //! The type `As` is defined in the same trait and its implementation should be compact encode-able. From 02c93d30398ac31178821eb8014b662d832351d2 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 4 Jan 2021 09:59:08 +0000 Subject: [PATCH 031/286] Docs and cleanup for utils (#233) --- derive/src/decode.rs | 8 ++--- derive/src/encode.rs | 12 +++---- derive/src/lib.rs | 8 ++--- derive/src/trait_bounds.rs | 37 +++++++-------------- derive/src/utils.rs | 66 ++++++++++++++++++++++++-------------- 5 files changed, 68 insertions(+), 63 deletions(-) diff --git a/derive/src/decode.rs b/derive/src/decode.rs index f3d1c4a1..8eeab77b 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -35,7 +35,7 @@ pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream }, }, Data::Enum(ref data) => { - let data_variants = || data.variants.iter().filter(|variant| crate::utils::get_skip(&variant.attrs).is_none()); + let data_variants = || data.variants.iter().filter(|variant| !utils::should_skip(&variant.attrs)); if data_variants().count() > 256 { return Error::new( @@ -46,7 +46,7 @@ pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream let recurse = data_variants().enumerate().map(|(i, v)| { let name = &v.ident; - let index = utils::index(v, i); + let index = utils::variant_index(v, i); let create = create_instance( quote! { #type_name :: #name }, @@ -76,8 +76,8 @@ pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); - let compact = utils::get_enable_compact(field); - let skip = utils::get_skip(&field.attrs).is_some(); + let compact = utils::is_compact(field); + let skip = utils::should_skip(&field.attrs); let res = quote!(__codec_res_edqy); diff --git a/derive/src/encode.rs b/derive/src/encode.rs index ba55a40f..18bdd673 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -32,9 +32,9 @@ fn encode_single_field( field_name: TokenStream, ) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); - let compact = utils::get_enable_compact(field); + let compact = utils::is_compact(field); - if utils::get_skip(&field.attrs).is_some() { + if utils::should_skip(&field.attrs) { return Error::new( Span::call_site(), "Internal error: cannot encode single field optimisation if skipped" @@ -101,8 +101,8 @@ fn encode_fields( let recurse = fields.iter().enumerate().map(|(i, f)| { let field = field_name(i, &f.ident); let encoded_as = utils::get_encoded_as_type(f); - let compact = utils::get_enable_compact(f); - let skip = utils::get_skip(&f.attrs).is_some(); + let compact = utils::is_compact(f); + let skip = utils::should_skip(&f.attrs); if encoded_as.is_some() as u8 + compact as u8 + skip as u8 > 1 { return Error::new( @@ -200,7 +200,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { } }, Data::Enum(ref data) => { - let data_variants = || data.variants.iter().filter(|variant| crate::utils::get_skip(&variant.attrs).is_none()); + let data_variants = || data.variants.iter().filter(|variant| !utils::should_skip(&variant.attrs)); if data_variants().count() > 256 { return Error::new( @@ -216,7 +216,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { let recurse = data_variants().enumerate().map(|(i, f)| { let name = &f.ident; - let index = utils::index(f, i); + let index = utils::variant_index(f, i); match f.fields { Fields::Named(ref fields) => { diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 3a0fbc15..0b2a0746 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -146,7 +146,7 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream &input.data, parse_quote!(_parity_scale_codec::Encode), None, - utils::get_dumb_trait_bound(&input.attrs), + utils::has_dumb_trait_bound(&input.attrs), ) { return e.to_compile_error().into(); } @@ -187,7 +187,7 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream &input.data, parse_quote!(_parity_scale_codec::Decode), Some(parse_quote!(Default)), - utils::get_dumb_trait_bound(&input.attrs), + utils::has_dumb_trait_bound(&input.attrs), ) { return e.to_compile_error().into(); } @@ -242,7 +242,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr &input.data, parse_quote!(_parity_scale_codec::CompactAs), None, - utils::get_dumb_trait_bound(&input.attrs), + utils::has_dumb_trait_bound(&input.attrs), ) { return e.to_compile_error().into(); } @@ -251,7 +251,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); fn val_or_default(field: &Field) -> proc_macro2::TokenStream { - let skip = utils::get_skip(&field.attrs).is_some(); + let skip = utils::should_skip(&field.attrs); if skip { quote_spanned!(field.span()=> Default::default()) } else { diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index 0cf39883..c6303f4f 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -21,6 +21,8 @@ use syn::{ Generics, Result, Type, TypePath, }; +use crate::utils; + /// Visits the ast and checks if one of the given idents is found. struct ContainIdents<'a> { result: bool, @@ -118,14 +120,15 @@ pub fn add( let codec_types = get_types_to_add_trait_bound(input_ident, data, &ty_params, dumb_trait_bounds)?; - let compact_types = collect_types(&data, needs_has_compact_bound, variant_not_skipped)? + let compact_types = collect_types(&data, utils::is_compact)? .into_iter() // Only add a bound if the type uses a generic .filter(|ty| type_contain_idents(ty, &ty_params)) .collect::>(); let skip_types = if codec_skip_bound.is_some() { - collect_types(&data, needs_default_bound, variant_not_skipped)? + let needs_default_bound = |f: &syn::Field| utils::should_skip(&f.attrs); + collect_types(&data, needs_default_bound)? .into_iter() // Only add a bound if the type uses a generic .filter(|ty| type_contain_idents(ty, &ty_params)) @@ -171,11 +174,14 @@ fn get_types_to_add_trait_bound( if dumb_trait_bound { Ok(ty_params.iter().map(|t| parse_quote!( #t )).collect()) } else { - let res = collect_types(&data, needs_codec_bound, variant_not_skipped)? + let needs_codec_bound = |f: &syn::Field| !utils::is_compact(f) + && utils::get_encoded_as_type(f).is_none() + && !utils::should_skip(&f.attrs); + let res = collect_types(&data, needs_codec_bound)? .into_iter() // Only add a bound if the type uses a generic .filter(|ty| type_contain_idents(ty, &ty_params)) - // If a struct is cotaining itself as field type, we can not add this type into the where clause. + // If a struct contains itself as field type, we can not add this type into the where clause. // This is required to work a round the following compiler bug: https://github.com/rust-lang/rust/issues/47032 .flat_map(|ty| { find_type_paths_not_start_or_contain_ident(&ty, input_ident) @@ -183,7 +189,7 @@ fn get_types_to_add_trait_bound( .map(|ty| Type::Path(ty.clone())) // Remove again types that do not contain any of our generic parameters .filter(|ty| type_contain_idents(ty, &ty_params)) - // Add back the original type, as we don't want to loose him. + // Add back the original type, as we don't want to loose it. .chain(iter::once(ty)) }) // Remove all remaining types that start/contain the input ident to not have them in the where clause. @@ -194,28 +200,9 @@ fn get_types_to_add_trait_bound( } } -fn needs_codec_bound(field: &syn::Field) -> bool { - !crate::utils::get_enable_compact(field) - && crate::utils::get_encoded_as_type(field).is_none() - && crate::utils::get_skip(&field.attrs).is_none() -} - -fn needs_has_compact_bound(field: &syn::Field) -> bool { - crate::utils::get_enable_compact(field) -} - -fn needs_default_bound(field: &syn::Field) -> bool { - crate::utils::get_skip(&field.attrs).is_some() -} - -fn variant_not_skipped(variant: &syn::Variant) -> bool { - crate::utils::get_skip(&variant.attrs).is_none() -} - fn collect_types( data: &syn::Data, type_filter: fn(&syn::Field) -> bool, - variant_filter: fn(&syn::Variant) -> bool, ) -> Result> { use syn::*; @@ -233,7 +220,7 @@ fn collect_types( }, Data::Enum(ref data) => data.variants.iter() - .filter(|variant| variant_filter(variant)) + .filter(|variant| !utils::should_skip(&variant.attrs)) .flat_map(|variant| { match &variant.fields { | Fields::Named(FieldsNamed { named: fields , .. }) diff --git a/derive/src/utils.rs b/derive/src/utils.rs index f5cc509b..7d96b0ce 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -1,4 +1,4 @@ -// Copyright 2018 Parity Technologies +// Copyright 2018-2020 Parity Technologies // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,11 +14,12 @@ //! Various internal utils. //! -//! NOTE: attributes finder must be checked using check_attribute first, otherwise macro can panic. +//! NOTE: attributes finder must be checked using check_attribute first, +//! otherwise the macro can panic. use std::str::FromStr; -use proc_macro2::{TokenStream, Span}; +use proc_macro2::TokenStream; use syn::{ spanned::Spanned, Meta, NestedMeta, Lit, Attribute, Variant, Field, DeriveInput, Fields, Data, FieldsUnnamed, @@ -42,8 +43,10 @@ fn find_meta_item<'a, F, R, I>(itr: I, pred: F) -> Option where }).next() } -pub fn index(v: &Variant, i: usize) -> TokenStream { - // look for an index in attributes +/// Look for a `#[scale(index = $int)]` attribute on a variant. If no attribute +/// is found, fall back to the discriminant or just the variant index. +pub fn variant_index(v: &Variant, i: usize) -> TokenStream { + // first look for an attribute let index = find_meta_item(v.attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::NameValue(ref nv)) = meta { if nv.path.is_ident("index") { @@ -67,9 +70,10 @@ pub fn index(v: &Variant, i: usize) -> TokenStream { ) } -pub fn get_encoded_as_type(field_entry: &Field) -> Option { - // look for an encoded_as in attributes - find_meta_item(field_entry.attrs.iter(), |meta| { +/// Look for a `#[codec(encoded_as = "SomeType")]` outer attribute on the given +/// `Field`. +pub fn get_encoded_as_type(field: &Field) -> Option { + find_meta_item(field.attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::NameValue(ref nv)) = meta { if nv.path.is_ident("encoded_as") { if let Lit::Str(ref s) = nv.lit { @@ -85,9 +89,9 @@ pub fn get_encoded_as_type(field_entry: &Field) -> Option { }) } -pub fn get_enable_compact(field_entry: &Field) -> bool { - // look for `encode(compact)` in the attributes - find_meta_item(field_entry.attrs.iter(), |meta| { +/// Look for a `#[codec(compact)]` outer attribute on the given `Field`. +pub fn is_compact(field: &Field) -> bool { + find_meta_item(field.attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("compact") { return Some(()); @@ -98,9 +102,8 @@ pub fn get_enable_compact(field_entry: &Field) -> bool { }).is_some() } -// return span of skip if found -pub fn get_skip(attrs: &[Attribute]) -> Option { - // look for `skip` in the attributes +/// Look for a `#[codec(skip)]` in the given attributes. +pub fn should_skip(attrs: &[Attribute]) -> bool { find_meta_item(attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("skip") { @@ -109,11 +112,11 @@ pub fn get_skip(attrs: &[Attribute]) -> Option { } None - }) + }).is_some() } -/// Returns if the `dumb_trait_bound` attribute is given in `attrs`. -pub fn get_dumb_trait_bound(attrs: &[Attribute]) -> bool { +/// Look for a `#[codec(dumb_trait_bound)]`in the given attributes. +pub fn has_dumb_trait_bound(attrs: &[Attribute]) -> bool { find_meta_item(attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("dumb_trait_bound") { @@ -125,17 +128,32 @@ pub fn get_dumb_trait_bound(attrs: &[Attribute]) -> bool { }).is_some() } +/// Given a set of named fields, return an iterator of `Field` where all fields +/// marked `#[codec(skip)]` are filtered out. pub fn filter_skip_named<'a>(fields: &'a syn::FieldsNamed) -> impl Iterator + 'a { fields.named.iter() - .filter(|f| get_skip(&f.attrs).is_none()) + .filter(|f| !should_skip(&f.attrs)) } +/// Given a set of unnamed fields, return an iterator of `(index, Field)` where all fields +/// marked `#[codec(skip)]` are filtered out. pub fn filter_skip_unnamed<'a>(fields: &'a syn::FieldsUnnamed) -> impl Iterator + 'a { fields.unnamed.iter() .enumerate() - .filter(|(_, f)| get_skip(&f.attrs).is_none()) + .filter(|(_, f)| !should_skip(&f.attrs)) } +/// Ensure attributes are correctly applied. This *must* be called before using +/// any of the attribute finder methods or the macro may panic if it encounters +/// misapplied attributes. +/// `#[codec(dumb_trait_bound)]` is the only accepted top attribute. +/// Fields can have the following attributes: +/// * `#[codec(skip)]` +/// * `#[codec(compact)]` +/// * `#[codec(encoded_as = "$EncodeAs")]` with $EncodedAs a valid TokenStream +/// Variants can have the following attributes: +/// * `#[codec(skip)]` +/// * `#[codec(index = $int)]` pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> { for attr in &input.attrs { check_top_attribute(attr)?; @@ -170,7 +188,7 @@ pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> { Ok(()) } -// Is accepted only: +// Ensure a field is decorated only with the following attributes: // * `#[codec(skip)]` // * `#[codec(compact)]` // * `#[codec(encoded_as = "$EncodeAs")]` with $EncodedAs a valid TokenStream @@ -181,7 +199,7 @@ fn check_field_attribute(attr: &Attribute) -> syn::Result<()> { if attr.path.is_ident("codec") { match attr.parse_meta()? { Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { - match meta_list.nested.first().unwrap() { + match meta_list.nested.first().expect("Just checked that there is one item; qed") { NestedMeta::Meta(Meta::Path(path)) if path.get_ident().map_or(false, |i| i == "skip") => Ok(()), @@ -203,7 +221,7 @@ fn check_field_attribute(attr: &Attribute) -> syn::Result<()> { } } -// Is accepted only: +// Ensure a field is decorated only with the following attributes: // * `#[codec(skip)]` // * `#[codec(index = $int)]` fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { @@ -213,7 +231,7 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { if attr.path.is_ident("codec") { match attr.parse_meta()? { Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { - match meta_list.nested.first().unwrap() { + match meta_list.nested.first().expect("Just checked that there is one item; qed") { NestedMeta::Meta(Meta::Path(path)) if path.get_ident().map_or(false, |i| i == "skip") => Ok(()), @@ -239,7 +257,7 @@ fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { if attr.path.is_ident("codec") { match attr.parse_meta()? { Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { - match meta_list.nested.first().unwrap() { + match meta_list.nested.first().expect("Just checked that there is one item; qed") { NestedMeta::Meta(Meta::Path(path)) if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => Ok(()), From 1a78b578508b851868e20c03789acee75bf6c6b5 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Wed, 6 Jan 2021 13:37:57 +0100 Subject: [PATCH 032/286] Fix Vec::decode as reported by Brian and endianness (#231) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cheme Co-authored-by: Brian Anderson Co-authored-by: Bastian Köcher Co-authored-by: David --- benches/benches.rs | 27 ++++++++ src/bit_vec.rs | 78 ++++++++++++++++++++-- src/codec.rs | 155 ++++++++++++++++++++++++++++--------------- src/encode_append.rs | 39 +++++------ src/generic_array.rs | 2 +- 5 files changed, 222 insertions(+), 79 deletions(-) diff --git a/benches/benches.rs b/benches/benches.rs index dee68ffb..c35bea86 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -61,6 +61,18 @@ fn vec_extend_from_slice(b: &mut Bencher) { }); } +struct NoLimitInput<'a>(&'a [u8]); + +impl<'a> Input for NoLimitInput<'a> { + fn remaining_len(&mut self) -> Result, Error> { + Ok(None) + } + + fn read(&mut self, into: &mut [u8]) -> Result<(), Error> { + self.0.read(into) + } +} + #[derive(Encode, Decode)] enum Event { ComplexEvent(Vec, u32, i32, u128, i8), @@ -126,6 +138,21 @@ fn encode_decode_vec + Codec>(c: &mut Criterion) where T::Error: let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); }) }, vec![1, 2, 5, 32, 1024, 2048, 16384]); + + c.bench_function_over_inputs(&format!("vec_decode_no_limit_{}", type_name::()), |b, &vec_size| { + let vec: Vec = (0..=127u8) + .cycle() + .take(vec_size) + .map(|v| v.try_into().unwrap()) + .collect(); + + let vec = vec.encode(); + + let vec = black_box(vec); + b.iter(|| { + let _: Vec = Decode::decode(&mut NoLimitInput(&vec[..])).unwrap(); + }) + }, vec![16384, 131072]); } fn encode_decode_complex_type(c: &mut Criterion) { diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 22a95a61..7cfb8789 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -15,11 +15,12 @@ //! `BitVec` specific serialization. use core::mem; +use crate::alloc::vec::Vec; use bitvec::{vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox}; use byte_slice_cast::{AsByteSlice, ToByteSlice, FromByteSlice, Error as FromByteSliceError}; -use crate::codec::{Encode, Decode, Input, Output, Error, read_vec_u8}; +use crate::codec::{Encode, Decode, Input, Output, Error, read_vec_from_u8s}; use crate::compact::Compact; use crate::EncodeLike; @@ -42,6 +43,22 @@ impl Encode for BitSlice { } } +/// Reverse bytes of element for element of size `size_of_t`. +/// +/// E.g. if size is 2 `[1, 2, 3, 4]` is changed to `[2, 1, 4, 3]`. +fn reverse_endian(vec_u8: &mut [u8], size_of_t: usize) { + for i in 0..vec_u8.len() / size_of_t { + for j in 0..size_of_t / 2 { + vec_u8.swap(i * size_of_t + j, i * size_of_t + (size_of_t - 1) - j); + } + } +} + +/// # WARNING +/// +/// In bitvec v0.17.4 the only implementations of BitStore are u8, u16, u32, u64, and usize. +/// This implementation actually only support u8, u16, u32 and u64, as encoding of uszie +/// is inconsistent between platforms. impl Encode for BitVec { fn encode_to(&self, dest: &mut W) { let len = self.len(); @@ -50,21 +67,48 @@ impl Encode for BitVec { "Attempted to serialize a collection with too many elements.", ); Compact(len as u32).encode_to(dest); - dest.write(self.as_slice().as_byte_slice()); + + let byte_slice: &[u8] = self.as_slice().as_byte_slice(); + + if cfg!(target_endian = "big") && mem::size_of::() > 1 { + let mut vec_u8: Vec = byte_slice.into(); + reverse_endian(&mut vec_u8[..], mem::size_of::()); + dest.write(&vec_u8); + } else { + dest.write(byte_slice); + } } } impl EncodeLike for BitVec {} +/// # WARNING +/// +/// In bitvec v0.17.4 the only implementations of BitStore are u8, u16, u32, u64, and usize. +/// This implementation actually only support u8, u16, u32 and u64, as encoding of usize +/// is inconsistent between platforms. impl Decode for BitVec { fn decode(input: &mut I) -> Result { >::decode(input).and_then(move |Compact(bits)| { let bits = bits as usize; let required_bytes = required_bytes::(bits); - let vec = read_vec_u8(input, required_bytes)?; + let mut vec_u8 = read_vec_from_u8s::(input, required_bytes)?; + + if cfg!(target_endian = "big") && mem::size_of::() > 1 { + reverse_endian(&mut vec_u8[..], mem::size_of::()); + } + + let mut aligned_vec: Vec = vec![0u8.into(); required_bytes / mem::size_of::()]; - let mut result = Self::from_slice(T::from_byte_slice(&vec)?); + unsafe { + let aligned_u8_ptr = aligned_vec.as_mut_ptr() as *mut u8; + for (i, v) in vec_u8.iter().enumerate() { + *aligned_u8_ptr.add(i) = *v; + } + } + + let mut result = Self::from_vec(aligned_vec); assert!(bits <= result.len()); unsafe { result.set_len(bits); } Ok(result) @@ -160,6 +204,7 @@ mod tests { } #[test] + #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitvec_u8() { for v in &test_data!(u8) { let encoded = v.encode(); @@ -168,6 +213,7 @@ mod tests { } #[test] + #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitvec_u16() { for v in &test_data!(u16) { let encoded = v.encode(); @@ -176,6 +222,7 @@ mod tests { } #[test] + #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitvec_u32() { for v in &test_data!(u32) { let encoded = v.encode(); @@ -184,6 +231,7 @@ mod tests { } #[test] + #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitvec_u64() { for v in &test_data!(u64) { let encoded = dbg!(v.encode()); @@ -192,6 +240,7 @@ mod tests { } #[test] + #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitslice() { let data: &[u8] = &[0x69]; let slice = BitSlice::::from_slice(data); @@ -208,4 +257,25 @@ mod tests { let decoded = BitBox::::decode(&mut &encoded[..]).unwrap(); assert_eq!(bb, decoded); } + + #[test] + fn reverse_endian_works() { + let data = vec![1, 2, 3, 4, 5, 6, 7, 8]; + + let mut data_to_u8 = data.clone(); + reverse_endian(&mut data_to_u8[..], mem::size_of::()); + assert_eq!(data_to_u8, data); + + let mut data_to_u16 = data.clone(); + reverse_endian(&mut data_to_u16[..], mem::size_of::()); + assert_eq!(data_to_u16, vec![2, 1, 4, 3, 6, 5, 8, 7]); + + let mut data_to_u32 = data.clone(); + reverse_endian(&mut data_to_u32[..], mem::size_of::()); + assert_eq!(data_to_u32, vec![4, 3, 2, 1, 8, 7, 6, 5]); + + let mut data_to_u64 = data.clone(); + reverse_endian(&mut data_to_u64[..], mem::size_of::()); + assert_eq!(data_to_u64, vec![8, 7, 6, 5, 4, 3, 2, 1]); + } } diff --git a/src/codec.rs b/src/codec.rs index c7309ea8..474f277e 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -30,7 +30,7 @@ use core::num::{ }; use arrayvec::ArrayVec; -use byte_slice_cast::{AsByteSlice, IntoVecOf}; +use byte_slice_cast::{AsByteSlice, AsMutByteSlice, ToMutByteSlice}; #[cfg(any(feature = "std", feature = "full"))] use crate::alloc::{ @@ -635,8 +635,14 @@ macro_rules! impl_array { $dest.write(&typed) }}; ( $ty:ty, $self:ident, $dest:ident ) => {{ - let typed = unsafe { mem::transmute::<&[T], &[$ty]>(&$self[..]) }; - $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed)) + if cfg!(target_endian = "little") { + let typed = unsafe { mem::transmute::<&[T], &[$ty]>(&$self[..]) }; + $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed)) + } else { + for item in $self.iter() { + item.encode_to($dest); + } + } }}; } @@ -765,8 +771,14 @@ impl Encode for [T] { $dest.write(&typed) }}; ( $ty:ty, $self:ident, $dest:ident ) => {{ - let typed = unsafe { mem::transmute::<&[T], &[$ty]>($self) }; - $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed)) + if cfg!(target_endian = "little") { + let typed = unsafe { mem::transmute::<&[T], &[$ty]>($self) }; + $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed)) + } else { + for item in $self { + item.encode_to($dest); + } + } }}; } @@ -782,36 +794,67 @@ impl Encode for [T] { } } -/// Read an `u8` vector from the given input. -pub(crate) fn read_vec_u8(input: &mut I, len: usize) -> Result, Error> { +/// Create a `Vec` by casting directly from a buffer of read `u8`s +/// +/// The encoding of `T` must be equal to its binary representation, and size of `T` must be less or +/// equal to [`MAX_PREALLOCATION`]. +pub(crate) fn read_vec_from_u8s(input: &mut I, items_len: usize) -> Result, Error> +where + I: Input, + T: ToMutByteSlice + Default + Clone, +{ + debug_assert!(MAX_PREALLOCATION >= mem::size_of::(), "Invalid precondition"); + + let byte_len = items_len.checked_mul(mem::size_of::()) + .ok_or_else(|| "Item is too big and cannot be allocated")?; + let input_len = input.remaining_len()?; // If there is input len and it cannot be pre-allocated then return directly. - if input_len.map(|l| l < len).unwrap_or(false) { + if input_len.map(|l| l < byte_len).unwrap_or(false) { return Err("Not enough data to decode vector".into()) } + // In both these branches we're going to be creating and resizing a Vec, + // but casting it to a &mut [u8] for reading. + // Note: we checked that if input_len is some then it can preallocated. - let r = if input_len.is_some() || len < MAX_PREALLOCATION { + let r = if input_len.is_some() || byte_len < MAX_PREALLOCATION { // Here we pre-allocate the whole buffer. - let mut r = vec![0; len]; - input.read(&mut r)?; + let mut items: Vec = vec![Default::default(); items_len]; + let mut bytes_slice = items.as_mut_byte_slice(); + input.read(&mut bytes_slice)?; - r + items } else { + // An allowed number of preallocated item. + // Note: `MAX_PREALLOCATION` is expected to be more or equal to size of `T`, precondition. + let max_preallocated_items = MAX_PREALLOCATION / mem::size_of::(); + // Here we pre-allocate only the maximum pre-allocation - let mut r = vec![]; - - let mut remains = len; - while remains != 0 { - let len_read = MAX_PREALLOCATION.min(remains); - let len_filled = r.len(); - r.resize(len_filled + len_read, 0); - input.read(&mut r[len_filled..])?; - remains -= len_read; + let mut items: Vec = vec![]; + + let mut items_remains = items_len; + + while items_remains > 0 { + let items_len_read = max_preallocated_items.min(items_remains); + + let items_len_filled = items.len(); + let items_new_size = items_len_filled + items_len_read; + + items.reserve_exact(items_len_read); + unsafe { + items.set_len(items_new_size); + } + + let bytes_slice = items.as_mut_byte_slice(); + let bytes_len_filled = items_len_filled * mem::size_of::(); + input.read(&mut bytes_slice[bytes_len_filled..])?; + + items_remains = items_remains.saturating_sub(items_len_read); } - r + items }; Ok(r) @@ -827,21 +870,31 @@ impl Decode for Vec { >::decode(input).and_then(move |Compact(len)| { let len = len as usize; + fn decode_unoptimized( + input: &mut I, + items_len: usize, + ) -> Result, Error> { + let input_capacity = input.remaining_len()? + .unwrap_or(MAX_PREALLOCATION) + .checked_div(mem::size_of::()) + .unwrap_or(0); + let mut r = Vec::with_capacity(input_capacity.min(items_len)); + input.descend_ref()?; + for _ in 0..items_len { + r.push(T::decode(input)?); + } + input.ascend_ref(); + Ok(r) + } + macro_rules! decode { - ( u8, $input:ident, $len:ident ) => {{ - let vec = read_vec_u8($input, $len)?; - Ok(unsafe { mem::transmute::, Vec>(vec) }) - }}; - ( i8, $input:ident, $len:ident ) => {{ - let vec = read_vec_u8($input, $len)?; - Ok(unsafe { mem::transmute::, Vec>(vec) }) - }}; ( $ty:ty, $input:ident, $len:ident ) => {{ - let vec = read_vec_u8($input, $len * mem::size_of::<$ty>())?; - let typed = vec.into_vec_of::<$ty>() - .map_err(|_| "Failed to convert from `Vec` to typed vec")?; - - Ok(unsafe { mem::transmute::, Vec>(typed) }) + if cfg!(target_endian = "little") || mem::size_of::() == 1 { + let vec = read_vec_from_u8s::<_, $ty>($input, $len)?; + Ok(unsafe { mem::transmute::, Vec>(vec) }) + } else { + decode_unoptimized($input, $len) + } }}; } @@ -849,17 +902,7 @@ impl Decode for Vec { ::TYPE_INFO, decode(input, len), { - let input_capacity = input.remaining_len()? - .unwrap_or(MAX_PREALLOCATION) - .checked_div(mem::size_of::()) - .unwrap_or(0); - let mut r = Vec::with_capacity(input_capacity.min(len)); - input.descend_ref()?; - for _ in 0..len { - r.push(T::decode(input)?); - } - input.ascend_ref(); - Ok(r) + decode_unoptimized(input, len) }, } }) @@ -936,13 +979,19 @@ impl Encode for VecDeque { macro_rules! encode_to { ( $ty:ty, $self:ident, $dest:ident ) => {{ - let slices = $self.as_slices(); - let typed = unsafe { - core::mem::transmute::<(&[T], &[T]), (&[$ty], &[$ty])>(slices) - }; - - $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.0)); - $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.1)); + if cfg!(target_endian = "little") || mem::size_of::() == 1 { + let slices = $self.as_slices(); + let typed = unsafe { + core::mem::transmute::<(&[T], &[T]), (&[$ty], &[$ty])>(slices) + }; + + $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.0)); + $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.1)); + } else { + for item in $self { + item.encode_to($dest); + } + } }}; } diff --git a/src/encode_append.rs b/src/encode_append.rs index 5a33ed95..4b696101 100644 --- a/src/encode_append.rs +++ b/src/encode_append.rs @@ -88,7 +88,7 @@ fn extract_length_data(data: &[u8], input_len: usize) -> Result<(u32, usize, usi let len = u32::from(Compact::::decode(&mut &data[..])?); let new_len = len .checked_add(input_len as u32) - .ok_or_else(|| "New vec length greater than `u32::max_value()`.")?; + .ok_or_else(|| "New vec length greater than `u32::TEST_VALUE()`.")?; let encoded_len = Compact::::compact_len(&len); let encoded_new_len = Compact::::compact_len(&new_len); @@ -155,28 +155,31 @@ mod tests { use crate::{Input, Encode, EncodeLike}; use std::collections::VecDeque; + const TEST_VALUE: u32 = { + #[cfg(not(miri))] + { 1_000_000 } + #[cfg(miri)] + { 1_000 } + }; + #[test] fn vec_encode_append_works() { - let max_value = 1_000_000; - - let encoded = (0..max_value).fold(Vec::new(), |encoded, v| { + let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| { as EncodeAppend>::append_or_new(encoded, std::iter::once(&v)).unwrap() }); let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); - assert_eq!(decoded, (0..max_value).collect::>()); + assert_eq!(decoded, (0..TEST_VALUE).collect::>()); } #[test] fn vec_encode_append_multiple_items_works() { - let max_value = 1_000_000u32; - - let encoded = (0..max_value).fold(Vec::new(), |encoded, v| { + let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| { as EncodeAppend>::append_or_new(encoded, &[v, v, v, v]).unwrap() }); let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); - let expected = (0..max_value).fold(Vec::new(), |mut vec, i| { + let expected = (0..TEST_VALUE).fold(Vec::new(), |mut vec, i| { vec.append(&mut vec![i, i, i, i]); vec }); @@ -185,26 +188,22 @@ mod tests { #[test] fn vecdeque_encode_append_works() { - let max_value = 1_000_000; - - let encoded = (0..max_value).fold(Vec::new(), |encoded, v| { + let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| { as EncodeAppend>::append_or_new(encoded, std::iter::once(&v)).unwrap() }); let decoded = VecDeque::::decode(&mut &encoded[..]).unwrap(); - assert_eq!(decoded, (0..max_value).collect::>()); + assert_eq!(decoded, (0..TEST_VALUE).collect::>()); } #[test] fn vecdeque_encode_append_multiple_items_works() { - let max_value = 1_000_000u32; - - let encoded = (0..max_value).fold(Vec::new(), |encoded, v| { + let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| { as EncodeAppend>::append_or_new(encoded, &[v, v, v, v]).unwrap() }); let decoded = VecDeque::::decode(&mut &encoded[..]).unwrap(); - let expected = (0..max_value).fold(Vec::new(), |mut vec, i| { + let expected = (0..TEST_VALUE).fold(Vec::new(), |mut vec, i| { vec.append(&mut vec![i, i, i, i]); vec }); @@ -240,13 +239,11 @@ mod tests { #[test] fn vec_encode_like_append_works() { - let max_value = 1_000_000; - - let encoded = (0..max_value).fold(Vec::new(), |encoded, v| { + let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| { as EncodeAppend>::append_or_new(encoded, std::iter::once(Box::new(v as u32))).unwrap() }); let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); - assert_eq!(decoded, (0..max_value).collect::>()); + assert_eq!(decoded, (0..TEST_VALUE).collect::>()); } } diff --git a/src/generic_array.rs b/src/generic_array.rs index 2dcfdf84..0d1f060f 100644 --- a/src/generic_array.rs +++ b/src/generic_array.rs @@ -44,7 +44,7 @@ impl> Decode for generic_array::Gene #[cfg(test)] mod tests { use super::*; - use generic_array::{typenum, GenericArray, arr, arr_impl}; + use generic_array::{typenum, GenericArray, arr}; #[test] fn generic_array() { From c116844e2bdcae92cb9655634359d5a3b2db2532 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Tue, 12 Jan 2021 13:39:20 +0100 Subject: [PATCH 033/286] Bump bitvec, byte slice cast, and refactor a bit (#236) --- Cargo.toml | 6 +- benches/benches.rs | 8 +- fuzzer/Cargo.toml | 2 +- src/bit_vec.rs | 214 ++++++++++++++++--------------------------- src/codec.rs | 189 ++++++++++++++++++-------------------- src/encode_append.rs | 2 +- tests/mod.rs | 9 +- 7 files changed, 182 insertions(+), 248 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 08ed2fbb..c357530d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,9 @@ edition = "2018" arrayvec = { version = "0.5.1", default-features = false, features = ["array-sizes-33-128", "array-sizes-129-255"] } serde = { version = "1.0.102", optional = true } parity-scale-codec-derive = { path = "derive", version = "1.2.0", default-features = false, optional = true } -bitvec = { version = "0.17.4", default-features = false, features = ["alloc"], optional = true } -byte-slice-cast = { version = "0.3.4", default-features = false, features = ["alloc"] } -generic-array = { version = "0.13.2", optional = true } +bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } +byte-slice-cast = { version = "1.0.0", default-features = false } +generic-array = { version = "0.14.4", optional = true } arbitrary = { version = "0.4.1", features = ["derive"], optional = true } [dev-dependencies] diff --git a/benches/benches.rs b/benches/benches.rs index c35bea86..242b8bd4 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -15,7 +15,7 @@ use std::{time::Duration, any::type_name, convert::{TryFrom, TryInto}}; #[cfg(feature = "bit-vec")] -use bitvec::vec::BitVec; +use bitvec::{vec::BitVec, order::Lsb0}; use criterion::{Criterion, black_box, Bencher, criterion_group, criterion_main}; use parity_scale_codec::*; use parity_scale_codec_derive::{Encode, Decode}; @@ -203,7 +203,7 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { #[cfg(feature = "bit-vec")] c.bench_function_over_inputs("bitvec_u8_encode - BitVec", |b, &size| { - let vec: BitVec = [true, false] + let vec: BitVec = [true, false] .iter() .cloned() .cycle() @@ -216,7 +216,7 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { #[cfg(feature = "bit-vec")] c.bench_function_over_inputs("bitvec_u8_decode - BitVec", |b, &size| { - let vec: BitVec = [true, false] + let vec: BitVec = [true, false] .iter() .cloned() .cycle() @@ -227,7 +227,7 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { let vec = black_box(vec); b.iter(|| { - let _: BitVec = Decode::decode(&mut &vec[..]).unwrap(); + let _: BitVec = Decode::decode(&mut &vec[..]).unwrap(); }) }, vec![1, 2, 5, 32, 1024]); } diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 51e48050..1b7125bd 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -9,4 +9,4 @@ publish = false parity-scale-codec = { path = "../", features = [ "derive", "bit-vec", "fuzz" ] } honggfuzz = "0.5.47" arbitrary = { version = "0.4.1", features = ["derive"] } -bitvec = { version = "0.17.4", features = ["alloc"] } +bitvec = { version = "0.20.1", features = ["alloc"] } diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 7cfb8789..82e255d6 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -14,52 +14,14 @@ //! `BitVec` specific serialization. -use core::mem; -use crate::alloc::vec::Vec; - -use bitvec::{vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox}; -use byte_slice_cast::{AsByteSlice, ToByteSlice, FromByteSlice, Error as FromByteSliceError}; - -use crate::codec::{Encode, Decode, Input, Output, Error, read_vec_from_u8s}; +use bitvec::{ + vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox, mem::BitMemory +}; +use crate::codec::{Encode, Decode, Input, Output, Error, decode_vec_with_len, encode_slice_no_len}; use crate::compact::Compact; use crate::EncodeLike; -impl From for Error { - fn from(e: FromByteSliceError) -> Error { - match e { - FromByteSliceError::AlignmentMismatch {..} => - "failed to cast from byte slice: alignment mismatch".into(), - FromByteSliceError::LengthMismatch {..} => - "failed to cast from byte slice: length mismatch".into(), - FromByteSliceError::CapacityMismatch {..} => - "failed to cast from byte slice: capacity mismatch".into(), - } - } -} - -impl Encode for BitSlice { - fn encode_to(&self, dest: &mut W) { - self.to_vec().encode_to(dest) - } -} - -/// Reverse bytes of element for element of size `size_of_t`. -/// -/// E.g. if size is 2 `[1, 2, 3, 4]` is changed to `[2, 1, 4, 3]`. -fn reverse_endian(vec_u8: &mut [u8], size_of_t: usize) { - for i in 0..vec_u8.len() / size_of_t { - for j in 0..size_of_t / 2 { - vec_u8.swap(i * size_of_t + j, i * size_of_t + (size_of_t - 1) - j); - } - } -} - -/// # WARNING -/// -/// In bitvec v0.17.4 the only implementations of BitStore are u8, u16, u32, u64, and usize. -/// This implementation actually only support u8, u16, u32 and u64, as encoding of uszie -/// is inconsistent between platforms. -impl Encode for BitVec { +impl Encode for BitSlice { fn encode_to(&self, dest: &mut W) { let len = self.len(); assert!( @@ -68,72 +30,75 @@ impl Encode for BitVec { ); Compact(len as u32).encode_to(dest); - let byte_slice: &[u8] = self.as_slice().as_byte_slice(); + // NOTE: doc of `BitSlice::as_slice`: + // > The returned slice handle views all elements touched by self + // + // Thus we are sure the slice doesn't contain unused elements at the end. + let slice = self.as_slice(); - if cfg!(target_endian = "big") && mem::size_of::() > 1 { - let mut vec_u8: Vec = byte_slice.into(); - reverse_endian(&mut vec_u8[..], mem::size_of::()); - dest.write(&vec_u8); - } else { - dest.write(byte_slice); - } + encode_slice_no_len(slice, dest) } } -impl EncodeLike for BitVec {} - -/// # WARNING -/// -/// In bitvec v0.17.4 the only implementations of BitStore are u8, u16, u32, u64, and usize. -/// This implementation actually only support u8, u16, u32 and u64, as encoding of usize -/// is inconsistent between platforms. -impl Decode for BitVec { - fn decode(input: &mut I) -> Result { - >::decode(input).and_then(move |Compact(bits)| { - let bits = bits as usize; - let required_bytes = required_bytes::(bits); - - let mut vec_u8 = read_vec_from_u8s::(input, required_bytes)?; +impl Encode for BitVec { + fn encode_to(&self, dest: &mut W) { + self.as_bitslice().encode_to(dest) + } +} - if cfg!(target_endian = "big") && mem::size_of::() > 1 { - reverse_endian(&mut vec_u8[..], mem::size_of::()); - } +impl EncodeLike for BitVec {} - let mut aligned_vec: Vec = vec![0u8.into(); required_bytes / mem::size_of::()]; +/// Equivalent of `BitStore::MAX_BITS` on 32bit machine. +const ARCH32BIT_BITSLICE_MAX_BITS: usize = 0x1fff_ffff; - unsafe { - let aligned_u8_ptr = aligned_vec.as_mut_ptr() as *mut u8; - for (i, v) in vec_u8.iter().enumerate() { - *aligned_u8_ptr.add(i) = *v; - } +impl Decode for BitVec { + fn decode(input: &mut I) -> Result { + >::decode(input).and_then(move |Compact(bits)| { + // Otherwise it is impossible to store it on 32bit machine. + if bits as usize > ARCH32BIT_BITSLICE_MAX_BITS { + return Err("Attempt to decode a bitvec with too many bits".into()); } - - let mut result = Self::from_vec(aligned_vec); - assert!(bits <= result.len()); - unsafe { result.set_len(bits); } + let required_elements = required_elements::(bits)? as usize; + let vec = decode_vec_with_len(input, required_elements)?; + + let mut result = Self::try_from_vec(vec) + .map_err(|_| { + Error::from("UNEXPECTED ERROR: `bits` is less or equal to + `ARCH32BIT_BITSLICE_MAX_BITS`; So BitVec must be able to handle the number of + segment needed for `bits` to be represented; qed") + })?; + + assert!(bits as usize <= result.len()); + result.truncate(bits as usize); Ok(result) }) } } -impl Encode for BitBox { +impl Encode for BitBox { fn encode_to(&self, dest: &mut W) { self.as_bitslice().encode_to(dest) } } -impl EncodeLike for BitBox {} +impl EncodeLike for BitBox {} -impl Decode for BitBox { +impl Decode for BitBox { fn decode(input: &mut I) -> Result { Ok(Self::from_bitslice(BitVec::::decode(input)?.as_bitslice())) } } -// Calculates bytes required to store given amount of `bits` as if they were stored in the array of `T`. -fn required_bytes(bits: usize) -> usize { - let element_bits = mem::size_of::() * 8; - (bits + element_bits - 1) / element_bits * mem::size_of::() +/// Calculates the number of element `T` required to store given amount of `bits` as if they were +/// stored in `BitVec<_, T>` +/// +/// Returns an error if the number of bits + number of bits in element overflow u32 capacity. +/// NOTE: this should never happen if `bits` is already checked to be less than +/// `BitStore::MAX_BITS`. +fn required_elements(bits: u32) -> Result { + let element_bits = T::Mem::BITS as u32; + let error = Error::from("Attempt to decode bitvec with too many bits"); + Ok((bits.checked_add(element_bits).ok_or_else(|| error)? - 1) / element_bits) } #[cfg(test)] @@ -177,34 +142,33 @@ mod tests { } #[test] - fn required_bytes_test() { - assert_eq!(0, required_bytes::(0)); - assert_eq!(1, required_bytes::(1)); - assert_eq!(1, required_bytes::(7)); - assert_eq!(1, required_bytes::(8)); - assert_eq!(2, required_bytes::(9)); - - assert_eq!(0, required_bytes::(0)); - assert_eq!(2, required_bytes::(1)); - assert_eq!(2, required_bytes::(15)); - assert_eq!(2, required_bytes::(16)); - assert_eq!(4, required_bytes::(17)); - - assert_eq!(0, required_bytes::(0)); - assert_eq!(4, required_bytes::(1)); - assert_eq!(4, required_bytes::(31)); - assert_eq!(4, required_bytes::(32)); - assert_eq!(8, required_bytes::(33)); - - assert_eq!(0, required_bytes::(0)); - assert_eq!(8, required_bytes::(1)); - assert_eq!(8, required_bytes::(63)); - assert_eq!(8, required_bytes::(64)); - assert_eq!(16, required_bytes::(65)); + fn required_items_test() { + assert_eq!(Ok(0), required_elements::(0)); + assert_eq!(Ok(1), required_elements::(1)); + assert_eq!(Ok(1), required_elements::(7)); + assert_eq!(Ok(1), required_elements::(8)); + assert_eq!(Ok(2), required_elements::(9)); + + assert_eq!(Ok(0), required_elements::(0)); + assert_eq!(Ok(1), required_elements::(1)); + assert_eq!(Ok(1), required_elements::(15)); + assert_eq!(Ok(1), required_elements::(16)); + assert_eq!(Ok(2), required_elements::(17)); + + assert_eq!(Ok(0), required_elements::(0)); + assert_eq!(Ok(1), required_elements::(1)); + assert_eq!(Ok(1), required_elements::(31)); + assert_eq!(Ok(1), required_elements::(32)); + assert_eq!(Ok(2), required_elements::(33)); + + assert_eq!(Ok(0), required_elements::(0)); + assert_eq!(Ok(1), required_elements::(1)); + assert_eq!(Ok(1), required_elements::(63)); + assert_eq!(Ok(1), required_elements::(64)); + assert_eq!(Ok(2), required_elements::(65)); } #[test] - #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitvec_u8() { for v in &test_data!(u8) { let encoded = v.encode(); @@ -213,7 +177,6 @@ mod tests { } #[test] - #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitvec_u16() { for v in &test_data!(u16) { let encoded = v.encode(); @@ -222,7 +185,6 @@ mod tests { } #[test] - #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitvec_u32() { for v in &test_data!(u32) { let encoded = v.encode(); @@ -231,7 +193,6 @@ mod tests { } #[test] - #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitvec_u64() { for v in &test_data!(u64) { let encoded = dbg!(v.encode()); @@ -240,10 +201,9 @@ mod tests { } #[test] - #[cfg_attr(miri, ignore)] // BitVec error due to outdated version of bitvec fn bitslice() { let data: &[u8] = &[0x69]; - let slice = BitSlice::::from_slice(data); + let slice = BitSlice::::from_slice(data).unwrap(); let encoded = slice.encode(); let decoded = BitVec::::decode(&mut &encoded[..]).unwrap(); assert_eq!(slice, decoded.as_bitslice()); @@ -252,30 +212,10 @@ mod tests { #[test] fn bitbox() { let data: &[u8] = &[5, 10]; - let bb = BitBox::::from_slice(data); + let slice = BitSlice::::from_slice(data).unwrap(); + let bb = BitBox::::from_bitslice(slice); let encoded = bb.encode(); let decoded = BitBox::::decode(&mut &encoded[..]).unwrap(); assert_eq!(bb, decoded); } - - #[test] - fn reverse_endian_works() { - let data = vec![1, 2, 3, 4, 5, 6, 7, 8]; - - let mut data_to_u8 = data.clone(); - reverse_endian(&mut data_to_u8[..], mem::size_of::()); - assert_eq!(data_to_u8, data); - - let mut data_to_u16 = data.clone(); - reverse_endian(&mut data_to_u16[..], mem::size_of::()); - assert_eq!(data_to_u16, vec![2, 1, 4, 3, 6, 5, 8, 7]); - - let mut data_to_u32 = data.clone(); - reverse_endian(&mut data_to_u32[..], mem::size_of::()); - assert_eq!(data_to_u32, vec![4, 3, 2, 1, 8, 7, 6, 5]); - - let mut data_to_u64 = data.clone(); - reverse_endian(&mut data_to_u64[..], mem::size_of::()); - assert_eq!(data_to_u64, vec![8, 7, 6, 5, 4, 3, 2, 1]); - } } diff --git a/src/codec.rs b/src/codec.rs index 474f277e..0761a6d1 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -601,6 +601,90 @@ macro_rules! impl_for_non_zero { )* } } + +/// Encode the slice without prepending the len. +/// +/// This is equivalent to encoding all the element one by one, but it is optimized for some types. +pub(crate) fn encode_slice_no_len(slice: &[T], dest: &mut W) { + macro_rules! encode_to { + ( u8, $slice:ident, $dest:ident ) => {{ + let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$slice[..]) }; + $dest.write(&typed) + }}; + ( i8, $slice:ident, $dest:ident ) => {{ + // `i8` has the same size as `u8`. We can just convert it here and write to the + // dest buffer directly. + let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$slice[..]) }; + $dest.write(&typed) + }}; + ( $ty:ty, $slice:ident, $dest:ident ) => {{ + if cfg!(target_endian = "little") { + let typed = unsafe { mem::transmute::<&[T], &[$ty]>(&$slice[..]) }; + $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed)) + } else { + for item in $slice.iter() { + item.encode_to(dest); + } + } + }}; + } + + with_type_info! { + ::TYPE_INFO, + encode_to(slice, dest), + { + for item in slice.iter() { + item.encode_to(dest); + } + }, + } +} + +/// Decode the slice (without prepended the len). +/// +/// This is equivalent to decode all elements one by one, but it is optimized in some +/// situation. +pub(crate) fn decode_vec_with_len( + input: &mut I, + len: usize, +) -> Result, Error> { + fn decode_unoptimized( + input: &mut I, + items_len: usize, + ) -> Result, Error> { + let input_capacity = input.remaining_len()? + .unwrap_or(MAX_PREALLOCATION) + .checked_div(mem::size_of::()) + .unwrap_or(0); + let mut r = Vec::with_capacity(input_capacity.min(items_len)); + input.descend_ref()?; + for _ in 0..items_len { + r.push(T::decode(input)?); + } + input.ascend_ref(); + Ok(r) + } + + macro_rules! decode { + ( $ty:ty, $input:ident, $len:ident ) => {{ + if cfg!(target_endian = "little") || mem::size_of::() == 1 { + let vec = read_vec_from_u8s::<_, $ty>($input, $len)?; + Ok(unsafe { mem::transmute::, Vec>(vec) }) + } else { + decode_unoptimized($input, $len) + } + }}; + } + + with_type_info! { + ::TYPE_INFO, + decode(input, len), + { + decode_unoptimized(input, len) + }, + } +} + impl_for_non_zero! { NonZeroI8, NonZeroI16, @@ -623,38 +707,7 @@ macro_rules! impl_array { } fn encode_to(&self, dest: &mut W) { - macro_rules! encode_to { - ( u8, $self:ident, $dest:ident ) => {{ - let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$self[..]) }; - $dest.write(&typed) - }}; - ( i8, $self:ident, $dest:ident ) => {{ - // `i8` has the same size as `u8`. We can just convert it here and write to the - // dest buffer directly. - let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$self[..]) }; - $dest.write(&typed) - }}; - ( $ty:ty, $self:ident, $dest:ident ) => {{ - if cfg!(target_endian = "little") { - let typed = unsafe { mem::transmute::<&[T], &[$ty]>(&$self[..]) }; - $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed)) - } else { - for item in $self.iter() { - item.encode_to($dest); - } - } - }}; - } - - with_type_info! { - ::TYPE_INFO, - encode_to(self, dest), - { - for item in self.iter() { - item.encode_to(dest); - } - }, - } + encode_slice_no_len(&self[..], dest) } } @@ -742,6 +795,7 @@ impl Decode for String { } } +/// Writes the compact encoding of `len` do `dest`. pub(crate) fn compact_encode_len_to(dest: &mut W, len: usize) -> Result<(), Error> { if len > u32::max_value() as usize { return Err("Attempted to serialize a collection with too many elements.".into()); @@ -759,38 +813,7 @@ impl Encode for [T] { fn encode_to(&self, dest: &mut W) { compact_encode_len_to(dest, self.len()).expect("Compact encodes length"); - macro_rules! encode_to { - ( u8, $self:ident, $dest:ident ) => {{ - let typed = unsafe { mem::transmute::<&[T], &[u8]>($self) }; - $dest.write(&typed) - }}; - ( i8, $self:ident, $dest:ident ) => {{ - // `i8` has the same size as `u8`. We can just convert it here and write to the - // dest buffer directly. - let typed = unsafe { mem::transmute::<&[T], &[u8]>($self) }; - $dest.write(&typed) - }}; - ( $ty:ty, $self:ident, $dest:ident ) => {{ - if cfg!(target_endian = "little") { - let typed = unsafe { mem::transmute::<&[T], &[$ty]>($self) }; - $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed)) - } else { - for item in $self { - item.encode_to($dest); - } - } - }}; - } - - with_type_info! { - ::TYPE_INFO, - encode_to(self, dest), - { - for item in self { - item.encode_to(dest); - } - }, - } + encode_slice_no_len(self, dest) } } @@ -868,43 +891,7 @@ impl, U: Encode> EncodeLike> for &[T] {} impl Decode for Vec { fn decode(input: &mut I) -> Result { >::decode(input).and_then(move |Compact(len)| { - let len = len as usize; - - fn decode_unoptimized( - input: &mut I, - items_len: usize, - ) -> Result, Error> { - let input_capacity = input.remaining_len()? - .unwrap_or(MAX_PREALLOCATION) - .checked_div(mem::size_of::()) - .unwrap_or(0); - let mut r = Vec::with_capacity(input_capacity.min(items_len)); - input.descend_ref()?; - for _ in 0..items_len { - r.push(T::decode(input)?); - } - input.ascend_ref(); - Ok(r) - } - - macro_rules! decode { - ( $ty:ty, $input:ident, $len:ident ) => {{ - if cfg!(target_endian = "little") || mem::size_of::() == 1 { - let vec = read_vec_from_u8s::<_, $ty>($input, $len)?; - Ok(unsafe { mem::transmute::, Vec>(vec) }) - } else { - decode_unoptimized($input, $len) - } - }}; - } - - with_type_info! { - ::TYPE_INFO, - decode(input, len), - { - decode_unoptimized(input, len) - }, - } + decode_vec_with_len(input, len as usize) }) } } diff --git a/src/encode_append.rs b/src/encode_append.rs index 4b696101..0a137fa7 100644 --- a/src/encode_append.rs +++ b/src/encode_append.rs @@ -213,7 +213,7 @@ mod tests { #[test] fn append_non_copyable() { #[derive(Eq, PartialEq, Debug)] - struct NoCopy { data: u32 }; + struct NoCopy { data: u32 } impl EncodeLike for NoCopy {} diff --git a/tests/mod.rs b/tests/mod.rs index 1de00f31..53fae7ab 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -520,9 +520,16 @@ fn crafted_input_for_vec_u8() { #[test] fn crafted_input_for_vec_t() { + let msg = if cfg!(target_endian = "big") { + // use unoptimize decode + "Not enough data to fill buffer" + } else { + "Not enough data to decode vector" + }; + assert_eq!( Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]).err().unwrap().what(), - "Not enough data to decode vector", + msg, ); } From b5d2ea7f06808893b14c3c26d9db8a157c328d41 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Thu, 14 Jan 2021 11:52:06 +0100 Subject: [PATCH 034/286] make `Output` trait object and encode_to allowed on not sized `Output` (#239) --- derive/src/encode.rs | 27 ++++++++++++++++++--------- src/bit_vec.rs | 6 +++--- src/codec.rs | 39 +++++++++++++++++---------------------- src/compact.rs | 16 ++++++++-------- src/generic_array.rs | 2 +- tests/mod.rs | 9 ++++++++- 6 files changed, 55 insertions(+), 44 deletions(-) diff --git a/derive/src/encode.rs b/derive/src/encode.rs index 18bdd673..38fef711 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -74,7 +74,7 @@ fn encode_single_field( let i_self = quote! { self }; quote_spanned! { field.span() => - fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output>( + fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output + ?Sized>( &#i_self, __codec_dest_edqy: &mut __CodecOutputEdqy ) { @@ -117,9 +117,12 @@ fn encode_fields( let field_type = &f.ty; quote_spanned! { f.span() => { - #dest.push( - &<<#field_type as _parity_scale_codec::HasCompact>::Type as - _parity_scale_codec::EncodeAsRef<'_, #field_type>>::RefType::from(#field) + _parity_scale_codec::Encode::encode_to( + &< + <#field_type as _parity_scale_codec::HasCompact>::Type as + _parity_scale_codec::EncodeAsRef<'_, #field_type> + >::RefType::from(#field), + #dest, ); } } @@ -127,9 +130,12 @@ fn encode_fields( let field_type = &f.ty; quote_spanned! { f.span() => { - #dest.push( - &<#encoded_as as - _parity_scale_codec::EncodeAsRef<'_, #field_type>>::RefType::from(#field) + _parity_scale_codec::Encode::encode_to( + &< + #encoded_as as + _parity_scale_codec::EncodeAsRef<'_, #field_type> + >::RefType::from(#field), + #dest, ); } } @@ -139,7 +145,7 @@ fn encode_fields( } } else { quote_spanned! { f.span() => - #dest.push(#field); + _parity_scale_codec::Encode::encode_to(#field, #dest); } } }); @@ -288,7 +294,10 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { }; quote! { - fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output>(&#self_, #dest: &mut __CodecOutputEdqy) { + fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output + ?Sized>( + &#self_, + #dest: &mut __CodecOutputEdqy + ) { #encoding } } diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 82e255d6..05ee64c3 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -22,7 +22,7 @@ use crate::compact::Compact; use crate::EncodeLike; impl Encode for BitSlice { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { let len = self.len(); assert!( len <= u32::max_value() as usize, @@ -41,7 +41,7 @@ impl Encode for BitSlice { } impl Encode for BitVec { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.as_bitslice().encode_to(dest) } } @@ -76,7 +76,7 @@ impl Decode for BitVec { } impl Encode for BitBox { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.as_bitslice().encode_to(dest) } } diff --git a/src/codec.rs b/src/codec.rs index 0761a6d1..9b4b8bd0 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -211,7 +211,7 @@ impl Input for IoReader { } /// Trait that allows writing of data. -pub trait Output: Sized { +pub trait Output { /// Write to the output. fn write(&mut self, bytes: &[u8]); @@ -219,11 +219,6 @@ pub trait Output: Sized { fn push_byte(&mut self, byte: u8) { self.write(&[byte]); } - - /// Write encoding of given value to the output. - fn push(&mut self, value: &V) { - value.encode_to(self); - } } #[cfg(not(feature = "std"))] @@ -280,7 +275,7 @@ pub trait Encode { } /// Convert self to a slice and append it to the destination. - fn encode_to(&self, dest: &mut T) { + fn encode_to(&self, dest: &mut T) { self.using_encoded(|buf| dest.write(buf)); } @@ -396,7 +391,7 @@ impl Encode for X where (&**self).encode() } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { (&**self).encode_to(dest) } } @@ -471,7 +466,7 @@ impl Encode for Result { } } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { match *self { Ok(ref t) => { dest.push_byte(0); @@ -550,7 +545,7 @@ impl Encode for Option { } } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { match *self { Some(ref t) => { dest.push_byte(1); @@ -579,7 +574,7 @@ macro_rules! impl_for_non_zero { self.get().size_hint() } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.get().encode_to(dest) } @@ -605,7 +600,7 @@ macro_rules! impl_for_non_zero { /// Encode the slice without prepending the len. /// /// This is equivalent to encoding all the element one by one, but it is optimized for some types. -pub(crate) fn encode_slice_no_len(slice: &[T], dest: &mut W) { +pub(crate) fn encode_slice_no_len(slice: &[T], dest: &mut W) { macro_rules! encode_to { ( u8, $slice:ident, $dest:ident ) => {{ let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$slice[..]) }; @@ -706,7 +701,7 @@ macro_rules! impl_array { mem::size_of::() * $n } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { encode_slice_no_len(&self[..], dest) } } @@ -755,7 +750,7 @@ impl Encode for str { self.as_bytes().size_hint() } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { self.as_bytes().encode_to(dest) } @@ -779,7 +774,7 @@ impl<'a, T: ToOwned + ?Sized> Decode for Cow<'a, T> impl EncodeLike for PhantomData {} impl Encode for PhantomData { - fn encode_to(&self, _dest: &mut W) {} + fn encode_to(&self, _dest: &mut W) {} } impl Decode for PhantomData { @@ -796,7 +791,7 @@ impl Decode for String { } /// Writes the compact encoding of `len` do `dest`. -pub(crate) fn compact_encode_len_to(dest: &mut W, len: usize) -> Result<(), Error> { +pub(crate) fn compact_encode_len_to(dest: &mut W, len: usize) -> Result<(), Error> { if len > u32::max_value() as usize { return Err("Attempted to serialize a collection with too many elements.".into()); } @@ -810,7 +805,7 @@ impl Encode for [T] { mem::size_of::() + mem::size_of::() * self.len() } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { compact_encode_len_to(dest, self.len()).expect("Compact encodes length"); encode_slice_no_len(self, dest) @@ -908,7 +903,7 @@ macro_rules! impl_codec_through_iterator { mem::size_of::() $( + mem::size_of::<$generics>() * self.len() )* } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { compact_encode_len_to(dest, self.len()).expect("Compact encodes length"); for i in self.iter() { @@ -961,7 +956,7 @@ impl Encode for VecDeque { mem::size_of::() + mem::size_of::() * self.len() } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { compact_encode_len_to(dest, self.len()).expect("Compact encodes length"); macro_rules! encode_to { @@ -1003,7 +998,7 @@ impl Decode for VecDeque { impl EncodeLike for () {} impl Encode for () { - fn encode_to(&self, _dest: &mut W) { + fn encode_to(&self, _dest: &mut W) { } fn using_encoded R>(&self, f: F) -> R { @@ -1044,7 +1039,7 @@ macro_rules! tuple_impl { self.0.size_hint() } - fn encode_to(&self, dest: &mut T) { + fn encode_to(&self, dest: &mut T) { self.0.encode_to(dest); } @@ -1085,7 +1080,7 @@ macro_rules! tuple_impl { $( + $rest.size_hint() )+ } - fn encode_to(&self, dest: &mut T) { + fn encode_to(&self, dest: &mut T) { let ( ref $first, $(ref $rest),+ diff --git a/src/compact.rs b/src/compact.rs index 1b9d6752..38845161 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -113,7 +113,7 @@ where CompactRef(&self.0).size_hint() } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { CompactRef(&self.0).encode_to(dest) } @@ -141,7 +141,7 @@ where CompactRef(self.0.encode_as()).size_hint() } - fn encode_to(&self, dest: &mut Out) { + fn encode_to(&self, dest: &mut Out) { CompactRef(self.0.encode_as()).encode_to(dest) } @@ -234,7 +234,7 @@ impl HasCompact for T where } impl<'a> Encode for CompactRef<'a, ()> { - fn encode_to(&self, _dest: &mut W) { + fn encode_to(&self, _dest: &mut W) { } fn using_encoded R>(&self, f: F) -> R { @@ -251,7 +251,7 @@ impl<'a> Encode for CompactRef<'a, u8> { Compact::compact_len(self.0) } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { match self.0 { 0..=0b0011_1111 => dest.push_byte(self.0 << 2), _ => ((u16::from(*self.0) << 2) | 0b01).encode_to(dest), @@ -279,7 +279,7 @@ impl<'a> Encode for CompactRef<'a, u16> { Compact::compact_len(self.0) } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { match self.0 { 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2), 0..=0b0011_1111_1111_1111 => ((*self.0 << 2) | 0b01).encode_to(dest), @@ -309,7 +309,7 @@ impl<'a> Encode for CompactRef<'a, u32> { Compact::compact_len(self.0) } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { match self.0 { 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2), 0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest), @@ -344,7 +344,7 @@ impl<'a> Encode for CompactRef<'a, u64> { Compact::compact_len(self.0) } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { match self.0 { 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2), 0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest), @@ -388,7 +388,7 @@ impl<'a> Encode for CompactRef<'a, u128> { Compact::compact_len(self.0) } - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { match self.0 { 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2), 0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest), diff --git a/src/generic_array.rs b/src/generic_array.rs index 0d1f060f..8b2b1400 100644 --- a/src/generic_array.rs +++ b/src/generic_array.rs @@ -17,7 +17,7 @@ use crate::codec::{Encode, Decode, Input, Output, Error}; use crate::encode_like::EncodeLike; impl> Encode for generic_array::GenericArray { - fn encode_to(&self, dest: &mut W) { + fn encode_to(&self, dest: &mut W) { for item in self.iter() { item.encode_to(dest); } diff --git a/tests/mod.rs b/tests/mod.rs index 53fae7ab..0650c5d4 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -14,7 +14,9 @@ #[cfg(not(feature="derive"))] use parity_scale_codec_derive::{Encode, Decode}; -use parity_scale_codec::{Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error}; +use parity_scale_codec::{ + Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error, Output, +}; use serde_derive::{Serialize, Deserialize}; #[derive(Debug, PartialEq, Encode, Decode)] @@ -548,3 +550,8 @@ fn weird_derive() { make_struct!(#[derive(Encode, Decode)]); } + +#[test] +fn output_trait_object() { + let _: Box; +} From adcde4608f0f1593a5ca7e980636d9b5c094c2bf Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Fri, 15 Jan 2021 17:35:13 +0100 Subject: [PATCH 035/286] CI: add miri test; chore (#240) * CI: add miri test; new phase; remoe CARGO_HOME cache * add miri and falgs to test * Update .gitlab-ci.yml Co-authored-by: Guillaume Thiolliere --- .gitlab-ci.yml | 43 +++++++++++++++++++++++++++---------------- scripts/pre_cache.sh | 6 +----- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8ee741b3..2709b0e9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,13 +2,13 @@ # stages: + - check - test - build variables: GIT_STRATEGY: fetch GIT_DEPTH: "100" - CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" CARGO_TARGET_DIR: "/ci-cache/${CI_PROJECT_NAME}/targets/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" CARGO_INCREMENTAL: 0 CI_SERVER_NAME: "GitLab CI" @@ -19,7 +19,7 @@ workflow: - if: $CI_COMMIT_BRANCH .docker-env: &docker-env - image: paritytech/ci-linux:production + image: paritytech/ink-ci-linux:production before_script: - cargo -vV - rustc -vV @@ -45,41 +45,43 @@ workflow: tags: - linux-docker -#### stage: test +#### stage: check -test-rust-stable: - stage: test +check-rust-stable-no_derive_no_std_full: + stage: check <<: *docker-env script: - - time cargo test --verbose --all --features bit-vec,generic-array,derive + - time cargo +stable check --verbose --no-default-features --features bit-vec,generic-array,full - sccache -s -test-rust-stable-no_derive: - stage: test +check-rust-stable-no_derive_no_std: + stage: check <<: *docker-env script: - - time cargo test --verbose --features bit-vec,generic-array + - time cargo +stable check --verbose --no-default-features --features bit-vec,generic-array - sccache -s -check-rust-stable-no_derive_no_std_full: - stage: test +check-rust-stable-no_derive_full: + stage: check <<: *docker-env script: - - time cargo check --verbose --no-default-features --features bit-vec,generic-array,full + - time cargo +stable check --verbose --features bit-vec,generic-array,full - sccache -s -check-rust-stable-no_derive_no_std: +#### stage: test + +test-rust-stable: stage: test <<: *docker-env script: - - time cargo check --verbose --no-default-features --features bit-vec,generic-array + - time cargo +stable test --verbose --all --features bit-vec,generic-array,derive - sccache -s -check-rust-stable-no_derive_full: +test-rust-stable-no_derive: stage: test <<: *docker-env script: - - time cargo check --verbose --features bit-vec,generic-array,full + - time cargo +stable test --verbose --features bit-vec,generic-array - sccache -s bench-rust-nightly: @@ -89,6 +91,15 @@ bench-rust-nightly: - time cargo +nightly bench --features bit-vec,generic-array,derive - sccache -s +miri: + stage: test + <<: *docker-env + variables: + RUST_BACKTRACE: 1 + MIRIFLAGS: "-Zmiri-disable-isolation" + script: + - time cargo +nightly miri test --features bit-vec,generic-array,arbitrary --release + #### stage: build build-linux-ubuntu-amd64: diff --git a/scripts/pre_cache.sh b/scripts/pre_cache.sh index b6074a5c..532d1ef7 100755 --- a/scripts/pre_cache.sh +++ b/scripts/pre_cache.sh @@ -6,7 +6,7 @@ set -u # create such directory and # copy recursively all the files from the newest dir which has $CI_JOB_NAME, if it exists -# caches are in /ci-cache/${CI_PROJECT_NAME}/${2}/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME} +# cache lives in /ci-cache/${CI_PROJECT_NAME}/${2}/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME} function prepopulate { if [[ ! -d $1 ]]; then @@ -24,8 +24,4 @@ function prepopulate { fi } -# CARGO_HOME cache was moved to the same "project/cache_type/branch_name/job_name" level as -# CARGO_TARGET_DIR because of frequent weird data-race issues. This just means that the same cache that -# would have been used for the entire pipeline will be duplicated for the each job. -prepopulate "$CARGO_HOME" cargo prepopulate "$CARGO_TARGET_DIR" targets From 1dc22f6f7e5658544f0f3509210f3fe54657ebe7 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Fri, 22 Jan 2021 11:28:49 +0100 Subject: [PATCH 036/286] Improve Decode trait, without improving implementations (#243) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher Co-authored-by: David --- src/codec.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/codec.rs b/src/codec.rs index 9b4b8bd0..115c62fd 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -307,7 +307,25 @@ pub trait Decode: Sized { const TYPE_INFO: TypeInfo = TypeInfo::Unknown; /// Attempt to deserialise the value from input. - fn decode(value: &mut I) -> Result; + fn decode(input: &mut I) -> Result; + + /// Attempt to skip the encoded value from input. + /// + /// The default implementation of this function is just calling [`Decode::decode`]. + /// When possible, an implementation should provided a specialized implementation. + fn skip(input: &mut I) -> Result<(), Error> { + Self::decode(input).map(|_| ()) + } + + /// Returns the fixed encoded size of the type. + /// + /// If it returns `Some(size)` then all possible values of this + /// type have the given size (in bytes) when encoded. + /// + /// NOTE: A type with a fixed encoded size may return `None`. + fn encoded_fixed_size() -> Option { + None + } } /// Trait that allows zero-copy read/write of value-references to/from slices in LE format. From 5f7145dba66ca9a156571f9d5a73097a2f16193d Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Fri, 22 Jan 2021 11:29:25 +0100 Subject: [PATCH 037/286] Remove unrequired bounds in HasCompact (#219) --- src/compact.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/compact.rs b/src/compact.rs index 38845161..6ce05b1a 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -205,21 +205,10 @@ impl<'de, T> serde::Deserialize<'de> for Compact where T: serde::Deserialize< } } -#[cfg(feature = "std")] -pub trait MaybeDebugSerde: core::fmt::Debug + serde::Serialize + for<'a> serde::Deserialize<'a> {} -#[cfg(feature = "std")] -impl MaybeDebugSerde for T where T: core::fmt::Debug + serde::Serialize + for<'a> serde::Deserialize<'a> {} - -#[cfg(not(feature = "std"))] -pub trait MaybeDebugSerde {} -#[cfg(not(feature = "std"))] -impl MaybeDebugSerde for T {} - /// Trait that tells you if a given type can be encoded/decoded in a compact way. pub trait HasCompact: Sized { /// The compact type; this can be - type Type: for<'a> EncodeAsRef<'a, Self> + Decode + From + Into + Clone + - PartialEq + Eq + MaybeDebugSerde; + type Type: for<'a> EncodeAsRef<'a, Self> + Decode + From + Into; } impl<'a, T: 'a> EncodeAsRef<'a, T> for Compact where CompactRef<'a, T>: Encode + From<&'a T> { @@ -227,8 +216,7 @@ impl<'a, T: 'a> EncodeAsRef<'a, T> for Compact where CompactRef<'a, T>: Encod } impl HasCompact for T where - Compact: for<'a> EncodeAsRef<'a, T> + Decode + From + Into + Clone + - PartialEq + Eq + MaybeDebugSerde, + Compact: for<'a> EncodeAsRef<'a, T> + Decode + From + Into { type Type = Compact; } From 33cb920b6e811bc3d9deb7612eab1c7396967b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 25 Jan 2021 15:27:15 +0100 Subject: [PATCH 038/286] Fix some docs (#246) --- src/decode_all.rs | 5 +++-- src/depth_limit.rs | 14 ++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/decode_all.rs b/src/decode_all.rs index 9ac65a9c..8219cee8 100644 --- a/src/decode_all.rs +++ b/src/decode_all.rs @@ -20,8 +20,9 @@ pub(crate) const DECODE_ALL_ERR_MSG: &str = "Input buffer has still data left af /// Extension trait to [`Decode`] that ensures that the given input data is consumed completly while /// decoding. pub trait DecodeAll: Sized { - /// Decode `Self` and consume all of the given input data. If not all data is consumed, an error - /// is returned. + /// Decode `Self` and consume all of the given input data. + /// + /// If not all data is consumed, an error is returned. fn decode_all(input: &[u8]) -> Result; } diff --git a/src/depth_limit.rs b/src/depth_limit.rs index 55d8d649..7d93eb8e 100644 --- a/src/depth_limit.rs +++ b/src/depth_limit.rs @@ -17,14 +17,16 @@ use crate::codec::{Error, Decode, Input}; /// The error message returned when depth limit is reached. const DECODE_MAX_DEPTH_MSG: &str = "Maximum recursion depth reached when decoding"; -/// Extension trait to [`Decode`] that ensures that the given input data is consumed completly while -/// decoding. +/// Extension trait to [`Decode`] for decoding with a maximum recursion depth. pub trait DecodeLimit: Sized { - /// Decode `Self` with given maximum recursion depth. - /// is returned. + /// Decode `Self` with the given maximum recursion depth. + /// + /// If `limit` is hit, an error is returned. fn decode_with_depth_limit(limit: u32, input: &[u8]) -> Result; - /// Decode `Self` and consume all of the given input data. If not all data is consumed, an error - /// is returned. + + /// Decode `Self` and consume all of the given input data. + /// + /// If not all data is consumed or `limit` is hit, an error is returned. fn decode_all_with_depth_limit(limit: u32, input: &[u8]) -> Result; } From e2365be32a5e7cb4d3cfd12a634990c7e40be578 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Mon, 25 Jan 2021 15:46:46 +0100 Subject: [PATCH 039/286] Implement chaining error (#242) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Andronik Ordian Co-authored-by: Bastian Köcher --- .gitlab-ci.yml | 7 +++ Cargo.toml | 6 +- derive/src/decode.rs | 38 ++++++++---- src/bit_vec.rs | 7 ++- src/codec.rs | 99 +++++++++--------------------- src/compact.rs | 3 +- src/decode_all.rs | 7 ++- src/depth_limit.rs | 2 +- src/encode_append.rs | 2 +- src/error.rs | 139 +++++++++++++++++++++++++++++++++++++++++++ src/generic_array.rs | 2 +- src/lib.rs | 4 +- tests/chain-error.rs | 99 ++++++++++++++++++++++++++++++ tests/mod.rs | 25 ++++---- 14 files changed, 333 insertions(+), 107 deletions(-) create mode 100644 src/error.rs create mode 100644 tests/chain-error.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2709b0e9..84d2a3ef 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -61,6 +61,13 @@ check-rust-stable-no_derive_no_std: - time cargo +stable check --verbose --no-default-features --features bit-vec,generic-array - sccache -s +check-rust-stable-no_std-chain-error: + stage: check + <<: *docker-env + script: + - time cargo +stable check --verbose --no-default-features --features chain-error + - sccache -s + check-rust-stable-no_derive_full: stage: check <<: *docker-env diff --git a/Cargo.toml b/Cargo.toml index c357530d..aa177ed1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,10 +33,14 @@ bench = false [features] default = ["std"] derive = ["parity-scale-codec-derive"] -std = ["serde", "bitvec/std", "byte-slice-cast/std"] +std = ["serde", "bitvec/std", "byte-slice-cast/std", "chain-error"] bit-vec = ["bitvec"] fuzz = ["std", "arbitrary"] +# Make error fully descriptive with chaining error message. +# Should not be used in a constrained environment. +chain-error = [] + # WARNING: DO _NOT_ USE THIS FEATURE IF YOU ARE WORKING ON CONSENSUS CODE!* # # Provides implementations for more data structures than just Vec and Box. diff --git a/derive/src/decode.rs b/derive/src/decode.rs index 8eeab77b..fc25b172 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -25,6 +25,7 @@ pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream Data::Struct(ref data) => match data.fields { Fields::Named(_) | Fields::Unnamed(_) => create_instance( quote! { #type_name }, + &type_name.to_string(), input, &data.fields, ), @@ -50,6 +51,7 @@ pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream let create = create_instance( quote! { #type_name :: #name }, + &format!("{}::{}", type_name, name), input, &v.fields, ); @@ -61,11 +63,20 @@ pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream } }); - let err_msg = format!("No such variant in enum {}", type_name); + let read_byte_err_msg = format!( + "Could not decode `{}`, failed to read variant byte", + type_name, + ); + let invalid_variant_err_msg = format!( + "Could not decode `{}`, variant doesn't exist", + type_name, + ); quote! { - match #input.read_byte()? { + match #input.read_byte() + .map_err(|e| e.chain(#read_byte_err_msg))? + { #( #recurse )* - _ => Err(#err_msg.into()), + _ => Err(#invalid_variant_err_msg.into()), } } @@ -88,7 +99,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt ).to_compile_error(); } - let err_msg = format!("Error decoding field {}", name); + let err_msg = format!("Could not decode `{}`", name); if compact { let field_type = &field.ty; @@ -98,7 +109,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt <#field_type as _parity_scale_codec::HasCompact>::Type as _parity_scale_codec::Decode >::decode(#input); match #res { - Err(_) => return Err(#err_msg.into()), + Err(e) => return Err(e.chain(#err_msg)), Ok(#res) => #res.into(), } } @@ -108,7 +119,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt { let #res = <#encoded_as as _parity_scale_codec::Decode>::decode(#input); match #res { - Err(_) => return Err(#err_msg.into()), + Err(e) => return Err(e.chain(#err_msg)), Ok(#res) => #res.into(), } } @@ -120,7 +131,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt { let #res = _parity_scale_codec::Decode::decode(#input); match #res { - Err(_) => return Err(#err_msg.into()), + Err(e) => return Err(e.chain(#err_msg)), Ok(#res) => #res, } } @@ -130,6 +141,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt fn create_instance( name: TokenStream, + name_str: &str, input: &TokenStream, fields: &Fields ) -> TokenStream { @@ -137,11 +149,11 @@ fn create_instance( Fields::Named(ref fields) => { let recurse = fields.named.iter().map(|f| { let name_ident = &f.ident; - let field = match name_ident { - Some(a) => format!("{}.{}", name, a), - None => format!("{}", name), + let field_name = match name_ident { + Some(a) => format!("{}::{}", name_str, a), + None => format!("{}", name_str), // Should never happen, fields are named. }; - let decode = create_decode_expr(f, &field, input); + let decode = create_decode_expr(f, &field_name, input); quote_spanned! { f.span() => #name_ident: #decode @@ -156,9 +168,9 @@ fn create_instance( }, Fields::Unnamed(ref fields) => { let recurse = fields.unnamed.iter().enumerate().map(|(i, f) | { - let name = format!("{}.{}", name, i); + let field_name = format!("{}.{}", name_str, i); - create_decode_expr(f, &name, input) + create_decode_expr(f, &field_name, input) }); quote_spanned! { fields.span() => diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 05ee64c3..053a6031 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -17,9 +17,10 @@ use bitvec::{ vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox, mem::BitMemory }; -use crate::codec::{Encode, Decode, Input, Output, Error, decode_vec_with_len, encode_slice_no_len}; -use crate::compact::Compact; -use crate::EncodeLike; +use crate::{ + EncodeLike, Encode, Decode, Input, Output, Error, Compact, + codec::{decode_vec_with_len, encode_slice_no_len}, +}; impl Encode for BitSlice { fn encode_to(&self, dest: &mut W) { diff --git a/src/codec.rs b/src/codec.rs index 115c62fd..8892d954 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -48,73 +48,11 @@ use crate::alloc::{ }; use crate::compact::Compact; use crate::encode_like::EncodeLike; +use crate::Error; pub(crate) const MAX_PREALLOCATION: usize = 4 * 1024; const A_BILLION: u32 = 1_000_000_000; -/// Descriptive error type -#[cfg(feature = "std")] -#[derive(PartialEq, Eq, Clone, Debug)] -pub struct Error(&'static str); - -/// Undescriptive error type when compiled for no std -#[cfg(not(feature = "std"))] -#[derive(PartialEq, Eq, Clone, Debug)] -pub struct Error; - -impl Error { - #[cfg(feature = "std")] - /// Error description - /// - /// This function returns an actual error str when running in `std` - /// environment, but `""` on `no_std`. - pub fn what(&self) -> &'static str { - self.0 - } - - #[cfg(not(feature = "std"))] - /// Error description - /// - /// This function returns an actual error str when running in `std` - /// environment, but `""` on `no_std`. - pub fn what(&self) -> &'static str { - "" - } -} - -#[cfg(feature = "std")] -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) - } -} - -#[cfg(not(feature = "std"))] -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("Error") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for Error { - fn description(&self) -> &str { - self.0 - } -} - -impl From<&'static str> for Error { - #[cfg(feature = "std")] - fn from(s: &'static str) -> Error { - Error(s) - } - - #[cfg(not(feature = "std"))] - fn from(_s: &'static str) -> Error { - Error - } -} - /// Trait that allows reading of data into a slice. pub trait Input { /// Should return the remaining length of the input data. If no information about the input @@ -508,9 +446,15 @@ where impl Decode for Result { fn decode(input: &mut I) -> Result { - match input.read_byte()? { - 0 => Ok(Ok(T::decode(input)?)), - 1 => Ok(Err(E::decode(input)?)), + match input.read_byte() + .map_err(|e| e.chain("Could not result variant byte for `Result`"))? + { + 0 => Ok( + Ok(T::decode(input).map_err(|e| e.chain("Could not Decode `Result::Ok(T)`"))?) + ), + 1 => Ok( + Err(E::decode(input).map_err(|e| e.chain("Could not decode `Result::Error(E)`"))?) + ), _ => Err("unexpected first byte decoding Result".into()), } } @@ -576,9 +520,13 @@ impl Encode for Option { impl Decode for Option { fn decode(input: &mut I) -> Result { - match input.read_byte()? { + match input.read_byte() + .map_err(|e| e.chain("Could not decode variant byte for `Option`"))? + { 0 => Ok(None), - 1 => Ok(Some(T::decode(input)?)), + 1 => Ok( + Some(T::decode(input).map_err(|e| e.chain("Could not decode `Option::Some(T)`"))?) + ), _ => Err("unexpected first byte decoding Option".into()), } } @@ -1242,9 +1190,10 @@ impl Encode for Duration { impl Decode for Duration { fn decode(input: &mut I) -> Result { - let (secs, nanos) = <(u64, u32)>::decode(input)?; + let (secs, nanos) = <(u64, u32)>::decode(input) + .map_err(|e| e.chain("Could not decode `Duration(u64, u32)`"))?; if nanos >= A_BILLION { - Err("Number of nanoseconds should not be higher than 10^9.".into()) + Err("Could not decode `Duration`: Number of nanoseconds should not be higher than 10^9.".into()) } else { Ok(Duration::new(secs, nanos)) } @@ -1508,10 +1457,16 @@ mod tests { assert_eq!(>::decode(&mut NoLimit(&i[..])).unwrap(), vec![0u8; len]); let i = Compact(len as u32).encode(); - assert_eq!(>::decode(&mut NoLimit(&i[..])).err().unwrap().what(), "Not enough data to fill buffer"); + assert_eq!( + >::decode(&mut NoLimit(&i[..])).err().unwrap().to_string(), + "Not enough data to fill buffer", + ); let i = Compact(1000u32).encode(); - assert_eq!(>::decode(&mut NoLimit(&i[..])).err().unwrap().what(), "Not enough data to fill buffer"); + assert_eq!( + >::decode(&mut NoLimit(&i[..])).err().unwrap().to_string(), + "Not enough data to fill buffer", + ); } #[test] diff --git a/src/compact.rs b/src/compact.rs index 6ce05b1a..073a84a0 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -17,8 +17,9 @@ use arrayvec::ArrayVec; use crate::alloc::vec::Vec; -use crate::codec::{Encode, Decode, Input, Output, EncodeAsRef, Error}; +use crate::codec::{Encode, Decode, Input, Output, EncodeAsRef}; use crate::encode_like::EncodeLike; +use crate::Error; #[cfg(feature = "fuzz")] use arbitrary::Arbitrary; diff --git a/src/decode_all.rs b/src/decode_all.rs index 8219cee8..64f8df6d 100644 --- a/src/decode_all.rs +++ b/src/decode_all.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::codec::{Error, Decode}; +use crate::{Error, Decode}; /// The error message returned when `decode_all` fails. pub(crate) const DECODE_ALL_ERR_MSG: &str = "Input buffer has still data left after decoding!"; @@ -56,7 +56,10 @@ mod tests { ); encoded.extend(&[1, 2, 3, 4, 5, 6]); - assert_eq!(<$type>::decode_all(&encoded).unwrap_err().what(), DECODE_ALL_ERR_MSG); + assert_eq!( + <$type>::decode_all(&encoded).unwrap_err().to_string(), + "Input buffer has still data left after decoding!", + ); } )* }; diff --git a/src/depth_limit.rs b/src/depth_limit.rs index 7d93eb8e..cc0cf22e 100644 --- a/src/depth_limit.rs +++ b/src/depth_limit.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::codec::{Error, Decode, Input}; +use crate::{Error, Decode, Input}; /// The error message returned when depth limit is reached. const DECODE_MAX_DEPTH_MSG: &str = "Maximum recursion depth reached when decoding"; diff --git a/src/encode_append.rs b/src/encode_append.rs index 0a137fa7..11fbf1cb 100644 --- a/src/encode_append.rs +++ b/src/encode_append.rs @@ -15,7 +15,7 @@ use core::{iter::ExactSizeIterator, mem}; use crate::alloc::vec::Vec; -use crate::codec::{Encode, Decode, Error}; +use crate::{Encode, Decode, Error}; use crate::compact::{Compact, CompactLen}; use crate::encode_like::EncodeLike; diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 00000000..37dc2411 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,139 @@ +// Copyright 2021 Parity Technologies +// +// 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. + +//! Error type, descriptive or undescriptive depending on features. + +use crate::alloc::borrow::Cow; +#[cfg(feature = "chain-error")] +use crate::alloc::boxed::Box; + +/// Error type. +/// +/// Descriptive on `std` environment, with chaining error on `chain-error` environment, +/// underscriptive otherwise. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct Error { + #[cfg(feature = "chain-error")] + cause: Option>, + #[cfg(feature = "chain-error")] + desc: Cow<'static, str>, +} + +impl Error { + /// Chain error message with description. + /// + /// When compiled with `chain-error` feature, the description is chained, otherwise the + /// description is ditched. + pub fn chain(self, desc: impl Into>) -> Self { + #[cfg(feature = "chain-error")] + { + Self { desc: desc.into(), cause: Some(Box::new(self)) } + } + + #[cfg(not(feature = "chain-error"))] + { + let _ = desc; + self + } + } + + /// Display error with indentation. + #[cfg(feature = "chain-error")] + fn display_with_indent(&self, indent: u32, f: &mut core::fmt::Formatter) -> core::fmt::Result { + for _ in 0..indent { + f.write_str("\t")?; + } + f.write_str(&self.desc)?; + if let Some(cause) = &self.cause { + f.write_str(":")?; + f.write_str("\n")?; + cause.display_with_indent(indent + 1, f) + } else { + // Only return to new line if the error has been displayed with some indent, + // i.e. if the error has some causes. + if indent != 0 { + f.write_str("\n")?; + } + Ok(()) + } + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + #[cfg(feature = "chain-error")] + { + self.display_with_indent(0, f) + } + + #[cfg(not(feature = "chain-error"))] + { + f.write_str("Codec error") + } + } +} + +impl From<&'static str> for Error { + fn from(desc: &'static str) -> Error { + #[cfg(feature = "chain-error")] + { + Error { desc: desc.into(), cause: None } + } + + #[cfg(not(feature = "chain-error"))] + { + let _ = desc; + Error {} + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + #[cfg(feature = "chain-error")] + { + self.cause.as_ref().map(|e| e as &(dyn std::error::Error + 'static)) + } + + #[cfg(not(feature = "chain-error"))] + { + None + } + } +} + +#[cfg(test)] +mod tests { + use crate::Error; + + #[test] + fn test_full_error() { + let msg: &str = "final type:\n\twrap cause:\n\t\troot cause\n"; + + let error = Error::from("root cause").chain("wrap cause").chain("final type"); + + assert_eq!(&error.to_string(), msg); + } + + #[test] + fn impl_std_error() { + use std::error::Error as _; + + let error = Error::from("root cause").chain("wrap cause").chain("final type"); + let s = error.source().unwrap(); + + assert_eq!(&s.to_string(), "wrap cause:\n\troot cause\n"); + } +} diff --git a/src/generic_array.rs b/src/generic_array.rs index 8b2b1400..a346b355 100644 --- a/src/generic_array.rs +++ b/src/generic_array.rs @@ -13,7 +13,7 @@ // limitations under the License. use crate::alloc::vec::Vec; -use crate::codec::{Encode, Decode, Input, Output, Error}; +use crate::{Encode, Decode, Input, Output, Error}; use crate::encode_like::EncodeLike; impl> Encode for generic_array::GenericArray { diff --git a/src/lib.rs b/src/lib.rs index 22273f21..ca0d8c7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -273,9 +273,11 @@ mod decode_all; mod depth_limit; mod encode_append; mod encode_like; +mod error; +pub use self::error::Error; pub use self::codec::{ - Input, Output, Error, Decode, Encode, Codec, EncodeAsRef, WrapperTypeEncode, WrapperTypeDecode, + Input, Output, Decode, Encode, Codec, EncodeAsRef, WrapperTypeEncode, WrapperTypeDecode, OptionBool, DecodeLength, FullCodec, FullEncode, }; #[cfg(feature = "std")] diff --git a/tests/chain-error.rs b/tests/chain-error.rs new file mode 100644 index 00000000..d06f3582 --- /dev/null +++ b/tests/chain-error.rs @@ -0,0 +1,99 @@ +// Copyright 2021 Parity Technologies +// +// 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="derive"))] +use parity_scale_codec_derive::Decode; +use parity_scale_codec::Decode; + +#[derive(Decode, Debug)] +struct Wrapper(T); + +#[derive(Decode, Debug)] +struct StructNamed { + foo: u16 +} + +#[derive(Decode, Debug)] +struct StructUnnamed(u16); + +#[derive(Decode, Debug)] +enum E { + VariantNamed { foo: u16, }, + VariantUnnamed(u16), +} + +#[test] +fn full_error_struct_named() { + let encoded = vec![0]; + let err = r#"Could not decode `Wrapper.0`: + Could not decode `StructNamed::foo`: + Not enough data to fill buffer +"#; + + assert_eq!( + Wrapper::::decode(&mut &encoded[..]).unwrap_err().to_string(), + String::from(err), + ); +} + +#[test] +fn full_error_struct_unnamed() { + let encoded = vec![0]; + let err = r#"Could not decode `Wrapper.0`: + Could not decode `StructUnnamed.0`: + Not enough data to fill buffer +"#; + + assert_eq!( + Wrapper::::decode(&mut &encoded[..]).unwrap_err().to_string(), + String::from(err), + ); +} + +#[test] +fn full_error_enum_unknown_variant() { + let encoded = vec![2]; + let err = r#"Could not decode `E`, variant doesn't exist"#; + + assert_eq!( + E::decode(&mut &encoded[..]).unwrap_err().to_string(), + String::from(err), + ); +} + +#[test] +fn full_error_enum_named_field() { + let encoded = vec![0, 0]; + let err = r#"Could not decode `E::VariantNamed::foo`: + Not enough data to fill buffer +"#; + + assert_eq!( + E::decode(&mut &encoded[..]).unwrap_err().to_string(), + String::from(err), + ); +} + +#[test] +fn full_error_enum_unnamed_field() { + let encoded = vec![1, 0]; + let err = r#"Could not decode `E::VariantUnnamed.0`: + Not enough data to fill buffer +"#; + + assert_eq!( + E::decode(&mut &encoded[..]).unwrap_err().to_string(), + String::from(err), + ); +} diff --git a/tests/mod.rs b/tests/mod.rs index 0650c5d4..2d74ec59 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -197,35 +197,35 @@ fn should_work_for_indexed() { } #[test] -#[should_panic(expected = "Error decoding field Indexed.0")] +#[should_panic(expected = "Not enough data to fill buffer")] fn correct_error_for_indexed_0() { let mut wrong: &[u8] = b"\x08"; Indexed::decode(&mut wrong).unwrap(); } #[test] -#[should_panic(expected = "Error decoding field Indexed.1")] +#[should_panic(expected = "Not enough data to fill buffer")] fn correct_error_for_indexed_1() { let mut wrong: &[u8] = b"\0\0\0\0\x01"; Indexed::decode(&mut wrong).unwrap(); } #[test] -#[should_panic(expected = "Error decoding field EnumType :: B.0")] +#[should_panic(expected = "Not enough data to fill buffer")] fn correct_error_for_enumtype() { let mut wrong: &[u8] = b"\x01"; EnumType::decode(&mut wrong).unwrap(); } #[test] -#[should_panic(expected = "Error decoding field Struct.a")] +#[should_panic(expected = "Not enough data to fill buffer")] fn correct_error_for_named_struct_1() { let mut wrong: &[u8] = b"\x01"; Struct::::decode(&mut wrong).unwrap(); } #[test] -#[should_panic(expected = "Error decoding field Struct.b")] +#[should_panic(expected = "Not enough data to fill buffer")] fn correct_error_for_named_struct_2() { let mut wrong: &[u8] = b"\0\0\0\0\x01"; Struct::::decode(&mut wrong).unwrap(); @@ -481,7 +481,10 @@ fn encode_decode_empty_enum() { fn impls_encode_decode() {} impls_encode_decode::(); - assert_eq!(EmptyEnumDerive::decode(&mut &[1, 2, 3][..]), Err("No such variant in enum EmptyEnumDerive".into())); + assert_eq!( + EmptyEnumDerive::decode(&mut &[1, 2, 3][..]), + Err("Could not decode `EmptyEnumDerive`, variant doesn't exist".into()) + ); } #[test] @@ -515,22 +518,22 @@ fn recursive_type() { #[test] fn crafted_input_for_vec_u8() { assert_eq!( - Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]).err().unwrap().what(), + Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]).err().unwrap().to_string(), "Not enough data to decode vector", ); } #[test] fn crafted_input_for_vec_t() { - let msg = if cfg!(target_endian = "big") { + let msg: String = if cfg!(target_endian = "big") { // use unoptimize decode - "Not enough data to fill buffer" + "Not enough data to fill buffer".into() } else { - "Not enough data to decode vector" + "Not enough data to decode vector".into() }; assert_eq!( - Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]).err().unwrap().what(), + Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]).err().unwrap().to_string(), msg, ); } From a5c229319a15455fcf602d4a5b288de57a533c72 Mon Sep 17 00:00:00 2001 From: laizy Date: Mon, 25 Jan 2021 22:47:29 +0800 Subject: [PATCH 040/286] add EncodedSize that calculates the encoded size more efficiently. (#245) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Guillaume Thiolliere Co-authored-by: Bastian Köcher --- src/codec.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/codec.rs b/src/codec.rs index 8892d954..1db43ee4 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -228,6 +228,35 @@ pub trait Encode { fn using_encoded R>(&self, f: F) -> R { f(&self.encode()) } + + /// Calculates the encoded size. + /// + /// Should be used when the encoded data isn't required. + /// + /// # Note + /// + /// This works by using a special [`Output`] that only tracks the size. So, there are no allocations inside the + /// output. However, this can not prevent allocations that some types are doing inside their own encoding. + fn encoded_size(&self) -> usize { + let mut size_tracker = SizeTracker { written: 0 }; + self.encode_to(&mut size_tracker); + size_tracker.written + } +} + +// Implements `Output` and only keeps track of the number of written bytes +struct SizeTracker { + written: usize, +} + +impl Output for SizeTracker { + fn write(&mut self, bytes: &[u8]) { + self.written += bytes.len(); + } + + fn push_byte(&mut self, _byte: u8) { + self.written += 1; + } } /// Trait that allows the length of a collection to be read, without having @@ -1587,4 +1616,41 @@ mod tests { assert!(encoded.is_empty()); <[u32; 0]>::decode(&mut &encoded[..]).unwrap(); } + + fn test_encoded_size(val: impl Encode) { + let length = val.using_encoded(|v| v.len()); + + assert_eq!(length, val.encoded_size()); + } + + struct TestStruct { + data: Vec, + other: u8, + compact: Compact, + } + + impl Encode for TestStruct { + fn encode_to(&self, dest: &mut W) { + self.data.encode_to(dest); + self.other.encode_to(dest); + self.compact.encode_to(dest); + } + } + + #[test] + fn encoded_size_works() { + test_encoded_size(120u8); + test_encoded_size(30u16); + test_encoded_size(1u32); + test_encoded_size(2343545u64); + test_encoded_size(34358394245459854u128); + test_encoded_size(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10u32]); + test_encoded_size(Compact(32445u32)); + test_encoded_size(Compact(34353454453545u128)); + test_encoded_size(TestStruct { + data: vec![1, 2, 4, 5, 6], + other: 45, + compact: Compact(123234545), + }); + } } From 5593ee726f3f7b03ef20e1bb9e3ae8b9ef029b9e Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Tue, 26 Jan 2021 15:33:27 +0100 Subject: [PATCH 041/286] new release 2.0 (#247) --- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ Cargo.toml | 6 +++--- derive/Cargo.toml | 4 ++-- 3 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..e2c3f94d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog +All notable changes to this crate will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [2.0.0] - 2021-01-26 + +### Added +- `Decode::skip` is introduced, allowing to skip some encoded types. +- `Decode::encoded_fixed_size` is introduced, allowing to get the fixed encoded size of a type. +- `Error` now contains a chain of causes. This full error description can also be activated on + no std using the feature `chain-error`. +- `Encode::encoded_size` is introduced, allowing to get the encoded size of a type more efficiently. + +### Changed +- `CompactAs::decode_from` now returns result. This allow for decoding to fail from their compact + form. +- derive macro use literal index e.g. `#[codec(index = 15)]` instead of `#[codec(index = "15")]` +- Version of crates `bitvec` and `generic-array` is updated. +- `Encode::encode_to` now bounds the generic `W: Output + ?Sized` instead of `W: Output`. +- `Output` can now be used as a trait object. + +### Removed +- `EncodeAppend::append` is removed in favor of `EncodeAppend::append_or_new`. +- `Output::push` is removed in favor of `Encode::encode_to`. +- Some bounds on `HasCompact::Type` are removed. +- `Error::what` is removed in favor of `Error::to_string` (implemented through trait `Display`). +- `Error::description` is removed in favor of `Error::to_string` (implemented through trait `Display`). diff --git a/Cargo.toml b/Cargo.toml index aa177ed1..1c9948ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "1.3.0" +version = "2.0.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,7 +11,7 @@ edition = "2018" [dependencies] arrayvec = { version = "0.5.1", default-features = false, features = ["array-sizes-33-128", "array-sizes-129-255"] } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "1.2.0", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "2.0.0", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } @@ -20,7 +20,7 @@ arbitrary = { version = "0.4.1", features = ["derive"], optional = true } [dev-dependencies] criterion = "0.3.0" serde_derive = { version = "1.0" } -parity-scale-codec-derive = { path = "derive", version = "^1.0.2", default-features = false } +parity-scale-codec-derive = { path = "derive", version = "2.0.0", default-features = false } quickcheck = "0.9" [[bench]] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index cdb2a4f2..a11d534e 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "1.2.0" +version = "2.0.0" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" @@ -16,4 +16,4 @@ proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" [dev-dependencies] -parity-scale-codec = { path = "..", version = "1.1.0" } +parity-scale-codec = { path = "..", version = "2.0.0" } From d7ed5038af70ba3f581021f2654f5d58544eec3c Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Tue, 26 Jan 2021 17:52:01 +0100 Subject: [PATCH 042/286] changelog wording (#248) Co-authored-by: David --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2c3f94d..45540e07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # Changelog -All notable changes to this crate will be documented in this file. +All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). @@ -7,11 +7,11 @@ and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h ## [2.0.0] - 2021-01-26 ### Added -- `Decode::skip` is introduced, allowing to skip some encoded types. -- `Decode::encoded_fixed_size` is introduced, allowing to get the fixed encoded size of a type. +- `Decode::skip` allows to skip some encoded types. Pr #243 +- `Decode::encoded_fixed_size` allows to get the fixed encoded size of a type. PR #243 - `Error` now contains a chain of causes. This full error description can also be activated on - no std using the feature `chain-error`. -- `Encode::encoded_size` is introduced, allowing to get the encoded size of a type more efficiently. + no std using the feature `chain-error`. PR #242 +- `Encode::encoded_size` allows to get the encoded size of a type more efficiently. PR #245 ### Changed - `CompactAs::decode_from` now returns result. This allow for decoding to fail from their compact From 1beac25dff792f52a7173ee34db88cf89cf6b8ef Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Fri, 26 Feb 2021 10:59:13 +0100 Subject: [PATCH 043/286] Fix type inference in derive decode (#254) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- CHANGELOG.md | 9 +- Cargo.lock | 912 ++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 +- derive/Cargo.toml | 4 +- derive/src/decode.rs | 20 +- derive/src/lib.rs | 3 +- tests/type_inference.rs | 35 ++ 7 files changed, 976 insertions(+), 11 deletions(-) create mode 100644 Cargo.lock create mode 100644 tests/type_inference.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 45540e07..bf08712b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,14 +4,19 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.1] - 2021-02-26 + +### Fix +- Fix type inference issue in `Decode` derive macro. Pr #254 + ## [2.0.0] - 2021-01-26 ### Added - `Decode::skip` allows to skip some encoded types. Pr #243 - `Decode::encoded_fixed_size` allows to get the fixed encoded size of a type. PR #243 - `Error` now contains a chain of causes. This full error description can also be activated on - no std using the feature `chain-error`. PR #242 -- `Encode::encoded_size` allows to get the encoded size of a type more efficiently. PR #245 + no std using the feature `chain-error`. PR #242 +- `Encode::encoded_size` allows to get the encoded size of a type more efficiently. PR #245 ### Changed - `CompactAs::decode_from` now returns result. This allow for decoding to fail from their compact diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..d36efcb1 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,912 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + +[[package]] +name = "arbitrary" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb544f1057eaaff4b34f8c4dcf56fc3cd04debd291998405d135017a7c3c0f4" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bitvec" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5011ffc90248764d7005b0e10c7294f5aa1bd87d9dd7248f4ad475b347c294d" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "bstr" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f07aa6688c702439a1be0307b6a94dffe1168569e45b9500c1372bc580740d59" + +[[package]] +name = "byte-slice-cast" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c1bf4a04a88c54f589125563643d773f3254b5c38571395e2b591c693bbc81" + +[[package]] +name = "byteorder" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" + +[[package]] +name = "cast" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + +[[package]] +name = "codec-fuzzer" +version = "0.1.0" +dependencies = [ + "arbitrary", + "bitvec", + "honggfuzz", + "parity-scale-codec", +] + +[[package]] +name = "const_fn" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" + +[[package]] +name = "criterion" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools 0.10.0", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" +dependencies = [ + "cast", + "itertools 0.9.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" +dependencies = [ + "cfg-if 1.0.0", + "const_fn", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "csv" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d58633299b24b515ac72a3f869f8b91306a3cec616a602843a383acd6f9e97" +dependencies = [ + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + +[[package]] +name = "derive_arbitrary" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b43185d3e7ce7dcd44a23ca761ec026359753ebf480283a571e6463853d2ef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", +] + +[[package]] +name = "half" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" + +[[package]] +name = "hermit-abi" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +dependencies = [ + "libc", +] + +[[package]] +name = "honggfuzz" +version = "0.5.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f085725a5828d7e959f014f624773094dfe20acc91be310ef106923c30594bc" +dependencies = [ + "arbitrary", + "lazy_static", + "memmap", +] + +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "js-sys" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10" + +[[package]] +name = "log" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2" +dependencies = [ + "cfg-if 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "memoffset" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "parity-scale-codec" +version = "2.0.1" +dependencies = [ + "arbitrary", + "arrayvec", + "bitvec", + "byte-slice-cast", + "criterion", + "generic-array", + "parity-scale-codec-derive", + "quickcheck", + "serde", + "serde_derive", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "2.0.1" +dependencies = [ + "parity-scale-codec", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "plotters" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" + +[[package]] +name = "plotters-svg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quickcheck" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" +dependencies = [ + "env_logger", + "log", + "rand", + "rand_core", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e006811e1fdd12672b0820a7f44c18dde429f367d50cec003d22aa9b3c8ddc" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rayon" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "regex" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-automata" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" +dependencies = [ + "byteorder", +] + +[[package]] +name = "regex-syntax" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" + +[[package]] +name = "serde_cbor" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e" + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thread_local" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8208a331e1cb318dd5bd76951d2b8fc48ca38a69f5f4e4af1b6a9f8c6236915" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tinytemplate" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2ada8616fad06a2d0c455adc530de4ef57605a8120cc65da9653e0e9623ca74" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasm-bindgen" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64" + +[[package]] +name = "web-sys" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" diff --git a/Cargo.toml b/Cargo.toml index 1c9948ac..bb708f85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.0.0" +version = "2.0.1" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,7 +11,7 @@ edition = "2018" [dependencies] arrayvec = { version = "0.5.1", default-features = false, features = ["array-sizes-33-128", "array-sizes-129-255"] } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "2.0.0", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "2.0.1", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index a11d534e..4816eaf2 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.0.0" +version = "2.0.1" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" @@ -16,4 +16,4 @@ proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" [dev-dependencies] -parity-scale-codec = { path = "..", version = "2.0.0" } +parity-scale-codec = { path = "..", version = "2.0.1" } diff --git a/derive/src/decode.rs b/derive/src/decode.rs index fc25b172..57429de1 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -20,11 +20,22 @@ use syn::{ use crate::utils; -pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream { +/// Generate function block for function `Decode::decode`. +/// +/// * data: data info of the type, +/// * type_name: name of the type, +/// * type_generics: the generics of the type in turbofish format, without bounds, e.g. `::` +/// * input: the variable name for the argument of function `decode`. +pub fn quote( + data: &Data, + type_name: &Ident, + type_generics: &TokenStream, + input: &TokenStream, +) -> TokenStream { match *data { Data::Struct(ref data) => match data.fields { Fields::Named(_) | Fields::Unnamed(_) => create_instance( - quote! { #type_name }, + quote! { #type_name #type_generics }, &type_name.to_string(), input, &data.fields, @@ -50,7 +61,7 @@ pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream let index = utils::variant_index(v, i); let create = create_instance( - quote! { #type_name :: #name }, + quote! { #type_name #type_generics :: #name }, &format!("{}::{}", type_name, name), input, &v.fields, @@ -127,9 +138,10 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt } else if skip { quote_spanned! { field.span() => Default::default() } } else { + let field_type = &field.ty; quote_spanned! { field.span() => { - let #res = _parity_scale_codec::Decode::decode(#input); + let #res = <#field_type as _parity_scale_codec::Decode>::decode(#input); match #res { Err(e) => return Err(e.chain(#err_msg)), Ok(#res) => #res, diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 0b2a0746..bed08ba4 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -194,9 +194,10 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let name = &input.ident; let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let ty_gen_turbofish = ty_generics.as_turbofish(); let input_ = quote!(__codec_input_edqy); - let decoding = decode::quote(&input.data, name, &input_); + let decoding = decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_); let impl_block = quote! { impl #impl_generics _parity_scale_codec::Decode for #name #ty_generics #where_clause { diff --git a/tests/type_inference.rs b/tests/type_inference.rs new file mode 100644 index 00000000..acc12e04 --- /dev/null +++ b/tests/type_inference.rs @@ -0,0 +1,35 @@ +// Copyright 2021 Parity Technologies +// +// 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. + +//! Test for type inference issue in decode. + +#[cfg(not(feature = "derive"))] +use parity_scale_codec_derive::Decode; +use parity_scale_codec::Decode; + +pub trait Trait { + type Value; + type AccountId: Decode; +} + +#[derive(Decode)] +pub enum A { + _C( + (T::AccountId, T::AccountId), + Vec<(T::Value, T::Value)>, + ), +} + +#[derive(Decode)] +pub struct B((T::AccountId, T::AccountId), Vec<(T::Value, T::Value)>); From 1a0a11dc207f125c6439c2768b488b7f7c855a28 Mon Sep 17 00:00:00 2001 From: Slesarew <33295157+Slesarew@users.noreply.github.com> Date: Mon, 29 Mar 2021 15:01:00 +0300 Subject: [PATCH 044/286] Docs: Update README.md (#260) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a3fe3548..c4925497 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Following are some examples to demonstrate usage of the codec. ```rust use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec_derive::{Encode, Decode}; #[derive(Debug, PartialEq, Encode, Decode)] enum EnumType { @@ -117,6 +118,7 @@ assert_eq!(EnumType::decode(&mut dz).ok(), None); ```rust use parity_scale_codec::{Encode, Decode, Compact, HasCompact}; +use parity_scale_codec_derive::{Encode, Decode}; #[derive(Debug, PartialEq, Encode, Decode)] struct Test1CompactHasCompact { From ab18de2477cc2a3421cd647092ebfe76b362cbd7 Mon Sep 17 00:00:00 2001 From: Austin Abell Date: Tue, 6 Apr 2021 10:26:36 -0400 Subject: [PATCH 045/286] Switch array impls to const generics (#261) * Switch array impls to const generics * addr comments --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/codec.rs | 64 +++++++++++++++----------------------------------- src/compact.rs | 18 +++++++------- 4 files changed, 31 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d36efcb1..1a02a31b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +checksum = "5a2f58b0bb10c380af2b26e57212856b8c9a59e0925b4c20f4a174a49734eaf7" [[package]] name = "atty" diff --git a/Cargo.toml b/Cargo.toml index bb708f85..16336913 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ categories = ["encoding"] edition = "2018" [dependencies] -arrayvec = { version = "0.5.1", default-features = false, features = ["array-sizes-33-128", "array-sizes-129-255"] } +arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } parity-scale-codec-derive = { path = "derive", version = "2.0.1", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } diff --git a/src/codec.rs b/src/codec.rs index 1db43ee4..54fe4c97 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -688,57 +688,31 @@ impl_for_non_zero! { NonZeroU128, } -macro_rules! impl_array { - ( $( $n:expr, )* ) => { - $( - impl Encode for [T; $n] { - fn size_hint(&self) -> usize { - mem::size_of::() * $n - } - - fn encode_to(&self, dest: &mut W) { - encode_slice_no_len(&self[..], dest) - } - } +impl Encode for [T; N] { + fn size_hint(&self) -> usize { + mem::size_of::() * N + } - impl Decode for [T; $n] { - fn decode(input: &mut I) -> Result { - let mut r = ArrayVec::new(); - for _ in 0..$n { - r.push(T::decode(input)?); - } - let i = r.into_inner(); + fn encode_to(&self, dest: &mut W) { + encode_slice_no_len(&self[..], dest) + } +} - match i { - Ok(a) => Ok(a), - Err(_) => Err("failed to get inner array from ArrayVec".into()), - } - } - } +impl Decode for [T; N] { + fn decode(input: &mut I) -> Result { + let mut array = ArrayVec::new(); + for _ in 0..N { + array.push(T::decode(input)?); + } - impl, U: Encode> EncodeLike<[U; $n]> for [T; $n] {} - )* + match array.into_inner() { + Ok(a) => Ok(a), + Err(_) => panic!("We decode `N` elements; qed"), + } } } -impl_array!( - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768, -); +impl, U: Encode, const N: usize> EncodeLike<[U; N]> for [T; N] {} impl Encode for str { fn size_hint(&self) -> usize { diff --git a/src/compact.rs b/src/compact.rs index 073a84a0..4af468c7 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -23,9 +23,9 @@ use crate::Error; #[cfg(feature = "fuzz")] use arbitrary::Arbitrary; -struct ArrayVecWrapper(ArrayVec); +struct ArrayVecWrapper(ArrayVec); -impl> Output for ArrayVecWrapper { +impl Output for ArrayVecWrapper { fn write(&mut self, bytes: &[u8]) { let old_len = self.0.len(); let new_len = old_len + bytes.len(); @@ -248,7 +248,7 @@ impl<'a> Encode for CompactRef<'a, u8> { } fn using_encoded R>(&self, f: F) -> R { - let mut r = ArrayVecWrapper(ArrayVec::<[u8; 2]>::new()); + let mut r = ArrayVecWrapper(ArrayVec::::new()); self.encode_to(&mut r); f(&r.0) } @@ -277,7 +277,7 @@ impl<'a> Encode for CompactRef<'a, u16> { } fn using_encoded R>(&self, f: F) -> R { - let mut r = ArrayVecWrapper(ArrayVec::<[u8; 4]>::new()); + let mut r = ArrayVecWrapper(ArrayVec::::new()); self.encode_to(&mut r); f(&r.0) } @@ -311,7 +311,7 @@ impl<'a> Encode for CompactRef<'a, u32> { } fn using_encoded R>(&self, f: F) -> R { - let mut r = ArrayVecWrapper(ArrayVec::<[u8; 5]>::new()); + let mut r = ArrayVecWrapper(ArrayVec::::new()); self.encode_to(&mut r); f(&r.0) } @@ -353,7 +353,7 @@ impl<'a> Encode for CompactRef<'a, u64> { } fn using_encoded R>(&self, f: F) -> R { - let mut r = ArrayVecWrapper(ArrayVec::<[u8; 9]>::new()); + let mut r = ArrayVecWrapper(ArrayVec::::new()); self.encode_to(&mut r); f(&r.0) } @@ -397,7 +397,7 @@ impl<'a> Encode for CompactRef<'a, u128> { } fn using_encoded R>(&self, f: F) -> R { - let mut r = ArrayVecWrapper(ArrayVec::<[u8; 17]>::new()); + let mut r = ArrayVecWrapper(ArrayVec::::new()); self.encode_to(&mut r); f(&r.0) } @@ -813,13 +813,13 @@ mod tests { #[test] #[should_panic] fn array_vec_output_oob() { - let mut v = ArrayVecWrapper(ArrayVec::<[u8; 4]>::new()); + let mut v = ArrayVecWrapper(ArrayVec::::new()); v.write(&[1, 2, 3, 4, 5]); } #[test] fn array_vec_output() { - let mut v = ArrayVecWrapper(ArrayVec::<[u8; 4]>::new()); + let mut v = ArrayVecWrapper(ArrayVec::::new()); v.write(&[1, 2, 3, 4]); } From 46c19554513d94f592014d034db4f17724e1657e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 6 Apr 2021 19:23:59 +0200 Subject: [PATCH 046/286] Adds support for custom where bounds (#263) * Adds support for custom where bounds The user can now specify a custom where bound when using the derive macros: - `#[codec(encode_bound(T: Encode))]` for `Encode` - `#[codec(decode_bound(T: Encode))]` for `Decode` If nothing is specified (`encode_bound()`) the where bounds will be empty. * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Gavin Wood --- CHANGELOG.md | 7 ++++ Cargo.toml | 2 +- derive/Cargo.toml | 2 +- derive/src/lib.rs | 12 ++++-- derive/src/utils.rs | 92 ++++++++++++++++++++++++++++++++------------- tests/mod.rs | 50 ++++++++++++++++++------ 6 files changed, 123 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf08712b..39704935 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.1.0] - 2021-04-06 + +### Fix +- Add support for custom where bounds `codec(encode_bound(T: Encode))` and `codec(decode_bound(T: Decode))` when +deriving the traits. Pr #262 +- Switch to const generics for array implementations. Pr #261 + ## [2.0.1] - 2021-02-26 ### Fix diff --git a/Cargo.toml b/Cargo.toml index 16336913..c14eb647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.0.1" +version = "2.1.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 4816eaf2..c13e8b33 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.0.1" +version = "2.1.0" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" diff --git a/derive/src/lib.rs b/derive/src/lib.rs index bed08ba4..1ce8d1a5 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -80,6 +80,8 @@ fn wrap_with_dummy_const(impl_block: proc_macro2::TokenStream) -> proc_macro::To /// type must implement `parity_scale_codec::EncodeAsRef<'_, $FieldType>` with $FieldType the /// type of the field with the attribute. This is intended to be used for types implementing /// `HasCompact` as shown in the example. +/// * `#[codec(encode_bound(T: Encode))]`: a custom where bound that will be used when deriving the `Encode` trait. +/// * `#[codec(decode_bound(T: Encode))]`: a custom where bound that will be used when deriving the `Decode` trait. /// /// ``` /// # use parity_scale_codec_derive::Encode; @@ -89,7 +91,7 @@ fn wrap_with_dummy_const(impl_block: proc_macro2::TokenStream) -> proc_macro::To /// #[codec(skip)] /// a: u32, /// #[codec(compact)] -/// b: u32, +/// b: u32, /// #[codec(encoded_as = "::Type")] /// c: u32, /// } @@ -140,7 +142,9 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream return e.to_compile_error().into(); } - if let Err(e) = trait_bounds::add( + if let Some(custom_bound) = utils::custom_encode_trait_bound(&input.attrs) { + input.generics.make_where_clause().predicates.extend(custom_bound); + } else if let Err(e) = trait_bounds::add( &input.ident, &mut input.generics, &input.data, @@ -181,7 +185,9 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream return e.to_compile_error().into(); } - if let Err(e) = trait_bounds::add( + if let Some(custom_bound) = utils::custom_decode_trait_bound(&input.attrs) { + input.generics.make_where_clause().predicates.extend(custom_bound); + } else if let Err(e) = trait_bounds::add( &input.ident, &mut input.generics, &input.data, diff --git a/derive/src/utils.rs b/derive/src/utils.rs index 7d96b0ce..cf50316a 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -23,24 +23,15 @@ use proc_macro2::TokenStream; use syn::{ spanned::Spanned, Meta, NestedMeta, Lit, Attribute, Variant, Field, DeriveInput, Fields, Data, FieldsUnnamed, - FieldsNamed, MetaNameValue + FieldsNamed, MetaNameValue, punctuated::Punctuated, token, parse::Parse, }; -fn find_meta_item<'a, F, R, I>(itr: I, pred: F) -> Option where - F: FnMut(&NestedMeta) -> Option + Clone, - I: Iterator +fn find_meta_item<'a, F, R, I, M>(mut itr: I, mut pred: F) -> Option where + F: FnMut(M) -> Option + Clone, + I: Iterator, + M: Parse, { - itr.filter_map(|attr| { - if attr.path.is_ident("codec") { - if let Meta::List(ref meta_list) = attr.parse_meta() - .expect("Internal error, parse_meta must have been checked") - { - return meta_list.nested.iter().filter_map(pred.clone()).next(); - } - } - - None - }).next() + itr.find_map(|attr| attr.path.is_ident("codec").then(|| pred(attr.parse_args().ok()?)).flatten()) } /// Look for a `#[scale(index = $int)]` attribute on a variant. If no attribute @@ -128,6 +119,48 @@ pub fn has_dumb_trait_bound(attrs: &[Attribute]) -> bool { }).is_some() } +/// Trait bounds. +pub type TraitBounds = Punctuated; + +/// Parse `name(T: Bound, N: Bound)` as a custom trait bound. +struct CustomTraitBound { + _name: N, + _paren_token: token::Paren, + bounds: TraitBounds, +} + +impl Parse for CustomTraitBound { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let content; + Ok(Self { + _name: input.parse()?, + _paren_token: syn::parenthesized!(content in input), + bounds: content.parse_terminated(syn::WherePredicate::parse)?, + }) + } +} + +syn::custom_keyword!(encode_bound); +syn::custom_keyword!(decode_bound); + +/// Look for a `#[codec(decode_bound(T: Decode))]`in the given attributes. +/// +/// If found, it should be used as trait bounds when deriving the `Decode` trait. +pub fn custom_decode_trait_bound(attrs: &[Attribute]) -> Option { + find_meta_item(attrs.iter(), |meta: CustomTraitBound| { + Some(meta.bounds) + }) +} + +/// Look for a `#[codec(encode_bound(T: Encode))]`in the given attributes. +/// +/// If found, it should be used as trait bounds when deriving the `Encode` trait. +pub fn custom_encode_trait_bound(attrs: &[Attribute]) -> Option { + find_meta_item(attrs.iter(), |meta: CustomTraitBound| { + Some(meta.bounds) + }) +} + /// Given a set of named fields, return an iterator of `Field` where all fields /// marked `#[codec(skip)]` are filtered out. pub fn filter_skip_named<'a>(fields: &'a syn::FieldsNamed) -> impl Iterator + 'a { @@ -252,19 +285,26 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { // Only `#[codec(dumb_trait_bound)]` is accepted as top attribute fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { - let top_error = "Invalid attribute only `#[codec(dumb_trait_bound)]` is accepted as top \ - attribute"; + let top_error = + "Invalid attribute only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]` or \ + `#[codec(decode_bound(T: Decode))]` are accepted as top attribute"; if attr.path.is_ident("codec") { - match attr.parse_meta()? { - Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { - match meta_list.nested.first().expect("Just checked that there is one item; qed") { - NestedMeta::Meta(Meta::Path(path)) - if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => Ok(()), + if attr.parse_args::>().is_ok() { + return Ok(()) + } else if attr.parse_args::>().is_ok() { + return Ok(()) + } else { + match attr.parse_meta()? { + Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { + match meta_list.nested.first().expect("Just checked that there is one item; qed") { + NestedMeta::Meta(Meta::Path(path)) + if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => Ok(()), - elt @ _ => Err(syn::Error::new(elt.span(), top_error)), - } - }, - meta @ _ => Err(syn::Error::new(meta.span(), top_error)), + elt @ _ => Err(syn::Error::new(elt.span(), top_error)), + } + }, + _ => Err(syn::Error::new(attr.span(), top_error)), + } } } else { Ok(()) diff --git a/tests/mod.rs b/tests/mod.rs index 2d74ec59..41bf9466 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -540,21 +540,49 @@ fn crafted_input_for_vec_t() { #[test] fn weird_derive() { - // Tests that compilation succeeds when the macro invocation - // hygiene context is different from the field hygiene context. - macro_rules! make_struct { - (#[$attr:meta]) => ( - #[$attr] - pub struct MyStruct { - field: u8 - } - ) - } + // Tests that compilation succeeds when the macro invocation + // hygiene context is different from the field hygiene context. + macro_rules! make_struct { + (#[$attr:meta]) => ( + #[$attr] + pub struct MyStruct { + field: u8 + } + ) + } - make_struct!(#[derive(Encode, Decode)]); + make_struct!(#[derive(Encode, Decode)]); } #[test] fn output_trait_object() { let _: Box; } + +#[test] +fn custom_trait_bound() { + #[derive(Encode, Decode)] + #[codec(encode_bound(N: Encode, T: Default))] + #[codec(decode_bound(N: Decode, T: Default))] + struct Something { + hello: Hello, + val: N, + } + + #[derive(Encode, Decode)] + #[codec(encode_bound())] + #[codec(decode_bound())] + struct Hello { + _phantom: std::marker::PhantomData, + } + + #[derive(Default)] + struct NotEncode; + + let encoded = Something:: { + hello: Hello { _phantom: Default::default() }, + val: 32u32, + }.encode(); + + Something::::decode(&mut &encoded[..]).unwrap(); +} From f0341dabb01aa9ff0548558abb6dcc5c31c669a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 12 Apr 2021 13:07:29 +0200 Subject: [PATCH 047/286] Add latest derive crate release as dependency (#265) --- Cargo.lock | 4 ++-- Cargo.toml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a02a31b..347d1435 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,7 +435,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "2.0.1" +version = "2.1.1" dependencies = [ "arbitrary", "arrayvec", @@ -451,7 +451,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "2.0.1" +version = "2.1.0" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index c14eb647..3ef3565f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.1.0" +version = "2.1.1" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,7 +11,7 @@ edition = "2018" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "2.0.1", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "2.1.0", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } @@ -20,7 +20,7 @@ arbitrary = { version = "0.4.1", features = ["derive"], optional = true } [dev-dependencies] criterion = "0.3.0" serde_derive = { version = "1.0" } -parity-scale-codec-derive = { path = "derive", version = "2.0.0", default-features = false } +parity-scale-codec-derive = { path = "derive", version = "2.1.0", default-features = false } quickcheck = "0.9" [[bench]] From 166d748abc1e48d74c528e2456fefe6f3c48f256 Mon Sep 17 00:00:00 2001 From: Caio Date: Wed, 26 May 2021 18:01:01 -0300 Subject: [PATCH 048/286] Impl Decode/Encode for Range/RangeInclusive (#269) * Impl Decode/Encode for Range/RangeInclusive * Typo --- src/codec.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index 54fe4c97..4d3aebaa 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -12,10 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Serialisation. +//! Serialization. use core::fmt; -use core::{mem, ops::Deref, marker::PhantomData, iter::FromIterator, convert::TryFrom, time::Duration}; +use core::{ + convert::TryFrom, + iter::FromIterator, + marker::PhantomData, + mem, + ops::{Deref, Range, RangeInclusive}, + time::Duration, +}; use core::num::{ NonZeroI8, NonZeroI16, @@ -1205,6 +1212,55 @@ impl Decode for Duration { impl EncodeLike for Duration {} +impl Encode for Range +where + T: Encode +{ + fn size_hint(&self) -> usize { + 2 * mem::size_of::() + } + + fn encode(&self) -> Vec { + (&self.start, &self.end).encode() + } +} + +impl Decode for Range +where + T: Decode +{ + fn decode(input: &mut I) -> Result { + let (start, end) = <(T, T)>::decode(input) + .map_err(|e| e.chain("Could not decode `Range`"))?; + Ok(Range { start, end }) + } +} + +impl Encode for RangeInclusive +where + T: Encode +{ + fn size_hint(&self) -> usize { + 2 * mem::size_of::() + } + + fn encode(&self) -> Vec { + (self.start(), self.end()).encode() + } +} + +impl Decode for RangeInclusive +where + T: Decode +{ + fn decode(input: &mut I) -> Result { + let (start, end) = <(T, T)>::decode(input) + .map_err(|e| e.chain("Could not decode `RangeInclusive`"))?; + Ok(RangeInclusive::new(start, end)) + } +} + + #[cfg(test)] mod tests { use super::*; @@ -1627,4 +1683,17 @@ mod tests { compact: Compact(123234545), }); } + + #[test] + fn ranges() { + let range = Range { start: 1, end: 100 }; + let range_bytes = (1, 100).encode(); + assert_eq!(range.encode(), range_bytes); + assert_eq!(Range::decode(&mut &range_bytes[..]), Ok(range)); + + let range_inclusive = RangeInclusive::new(1, 100); + let range_inclusive_bytes = (1, 100).encode(); + assert_eq!(range_inclusive.encode(), range_inclusive_bytes); + assert_eq!(RangeInclusive::decode(&mut &range_inclusive_bytes[..]), Ok(range_inclusive)); + } } From 9ab448321a9ffa850899b8b54f53c83182564f6b Mon Sep 17 00:00:00 2001 From: Qinxuan Chen Date: Sun, 30 May 2021 03:19:07 +0800 Subject: [PATCH 049/286] Bump some dependencies (#270) * Bump proc-macro-crate to v1.0.0 Signed-off-by: koushiro * Bump honggfuzz and arbitrary Signed-off-by: koushiro * Bump quickcheck to v1.0 Signed-off-by: koushiro --- Cargo.lock | 99 +++++++++++++++++++++------------------------- Cargo.toml | 4 +- derive/Cargo.toml | 4 +- derive/src/lib.rs | 5 ++- fuzzer/Cargo.toml | 6 +-- fuzzer/src/main.rs | 4 +- 6 files changed, 57 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 347d1435..1cd712b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "arbitrary" -version = "0.4.5" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb544f1057eaaff4b34f8c4dcf56fc3cd04debd291998405d135017a7c3c0f4" +checksum = "237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691" dependencies = [ "derive_arbitrary", ] @@ -245,9 +245,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "0.4.5" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b43185d3e7ce7dcd44a23ca761ec026359753ebf480283a571e6463853d2ef" +checksum = "5f1281ee141df08871db9fe261ab5312179eac32d1e314134ceaa8dd7c042f5a" dependencies = [ "proc-macro2", "quote", @@ -262,9 +262,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" -version = "0.7.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" dependencies = [ "log", "regex", @@ -288,9 +288,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.16" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if 1.0.0", "libc", @@ -314,9 +314,9 @@ dependencies = [ [[package]] name = "honggfuzz" -version = "0.5.51" +version = "0.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f085725a5828d7e959f014f624773094dfe20acc91be310ef106923c30594bc" +checksum = "bea09577d948a98a5f59b7c891e274c4fb35ad52f67782b3d0cb53b9c05301f1" dependencies = [ "arbitrary", "lazy_static", @@ -488,40 +488,34 @@ dependencies = [ "plotters-backend", ] -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - [[package]] name = "proc-macro-crate" -version = "0.1.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" dependencies = [ + "thiserror", "toml", ] [[package]] name = "proc-macro2" -version = "1.0.19" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" dependencies = [ "unicode-xid", ] [[package]] name = "quickcheck" -version = "0.9.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" dependencies = [ "env_logger", "log", "rand", - "rand_core", ] [[package]] @@ -541,45 +535,22 @@ checksum = "e9e006811e1fdd12672b0820a7f44c18dde429f367d50cec003d22aa9b3c8ddc" [[package]] name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" dependencies = [ - "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" -version = "0.5.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - [[package]] name = "rayon" version = "1.5.0" @@ -717,9 +688,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.38" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" dependencies = [ "proc-macro2", "quote", @@ -741,6 +712,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.2" @@ -806,9 +797,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" diff --git a/Cargo.toml b/Cargo.toml index 3ef3565f..d2b02a39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,13 +15,13 @@ parity-scale-codec-derive = { path = "derive", version = "2.1.0", default-featur bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } -arbitrary = { version = "0.4.1", features = ["derive"], optional = true } +arbitrary = { version = "1.0.1", features = ["derive"], optional = true } [dev-dependencies] criterion = "0.3.0" serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", version = "2.1.0", default-features = false } -quickcheck = "0.9" +quickcheck = "1.0" [[bench]] name = "benches" diff --git a/derive/Cargo.toml b/derive/Cargo.toml index c13e8b33..346e4ccd 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -10,10 +10,10 @@ edition = "2018" proc-macro = true [dependencies] -syn = { version = "1.0.8", features = [ "full", "visit" ] } +syn = { version = "1.0.8", features = ["full", "visit"] } quote = "1.0.2" proc-macro2 = "1.0.6" -proc-macro-crate = "0.1.4" +proc-macro-crate = "1.0.0" [dev-dependencies] parity-scale-codec = { path = "..", version = "2.0.1" } diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 1ce8d1a5..a283bc39 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -24,7 +24,7 @@ extern crate syn; extern crate quote; use proc_macro2::{Ident, Span}; -use proc_macro_crate::crate_name; +use proc_macro_crate::{crate_name, FoundCrate}; use syn::spanned::Spanned; use syn::{Data, Field, Fields, DeriveInput, Error}; @@ -40,7 +40,8 @@ fn include_parity_scale_codec_crate() -> proc_macro2::TokenStream { quote!( extern crate parity_scale_codec as _parity_scale_codec; ) } else { match crate_name("parity-scale-codec") { - Ok(parity_codec_crate) => { + Ok(FoundCrate::Itself) => quote!( extern crate parity_scale_codec as _parity_scale_codec; ), + Ok(FoundCrate::Name(parity_codec_crate)) => { let ident = Ident::new(&parity_codec_crate, Span::call_site()); quote!( extern crate #ident as _parity_scale_codec; ) }, diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 1b7125bd..f2ba7415 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" publish = false [dependencies] -parity-scale-codec = { path = "../", features = [ "derive", "bit-vec", "fuzz" ] } -honggfuzz = "0.5.47" -arbitrary = { version = "0.4.1", features = ["derive"] } +parity-scale-codec = { path = "..", features = ["derive", "bit-vec", "fuzz"] } +honggfuzz = "0.5.54" +arbitrary = { version = "1.0.1", features = ["derive"] } bitvec = { version = "0.20.1", features = ["alloc"] } diff --git a/fuzzer/src/main.rs b/fuzzer/src/main.rs index bacb8f37..dae55189 100644 --- a/fuzzer/src/main.rs +++ b/fuzzer/src/main.rs @@ -15,8 +15,8 @@ pub struct MockStruct{ #[derive(Encode, Decode, Clone, PartialEq, Debug)] pub struct BitVecWrapper(BitVec); -impl Arbitrary for BitVecWrapper { - fn arbitrary(u: &mut Unstructured<'_>) -> ArbResult { +impl<'a, O: 'static + BitOrder, T: 'static + BitStore + Arbitrary<'a>> Arbitrary<'a> for BitVecWrapper { + fn arbitrary(u: &mut Unstructured<'a>) -> ArbResult { let v = Vec::::arbitrary(u)?; Ok(BitVecWrapper(BitVec::::from_vec(v))) } From e71d9c1a73ea6942406691a4fee05bd4973b8ab8 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 8 Jun 2021 22:19:08 +0200 Subject: [PATCH 050/286] improve macro hygiene (#271) --- derive/src/decode.rs | 26 +++++++++++++------------- derive/src/encode.rs | 8 ++++---- derive/src/lib.rs | 6 +++--- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/derive/src/decode.rs b/derive/src/decode.rs index 57429de1..bb1ce34b 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -42,7 +42,7 @@ pub fn quote( ), Fields::Unit => { quote_spanned! { data.fields.span() => - Ok(#type_name) + ::core::result::Result::Ok(#type_name) } }, }, @@ -68,7 +68,7 @@ pub fn quote( ); quote_spanned! { v.span() => - __codec_x_edqy if __codec_x_edqy == #index as u8 => { + __codec_x_edqy if __codec_x_edqy == #index as ::core::primitive::u8 => { #create }, } @@ -87,7 +87,7 @@ pub fn quote( .map_err(|e| e.chain(#read_byte_err_msg))? { #( #recurse )* - _ => Err(#invalid_variant_err_msg.into()), + _ => ::core::result::Result::Err(#invalid_variant_err_msg.into()), } } @@ -120,8 +120,8 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt <#field_type as _parity_scale_codec::HasCompact>::Type as _parity_scale_codec::Decode >::decode(#input); match #res { - Err(e) => return Err(e.chain(#err_msg)), - Ok(#res) => #res.into(), + ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), + ::core::result::Result::Ok(#res) => #res.into(), } } } @@ -130,21 +130,21 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt { let #res = <#encoded_as as _parity_scale_codec::Decode>::decode(#input); match #res { - Err(e) => return Err(e.chain(#err_msg)), - Ok(#res) => #res.into(), + ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), + ::core::result::Result::Ok(#res) => #res.into(), } } } } else if skip { - quote_spanned! { field.span() => Default::default() } + quote_spanned! { field.span() => ::core::default::Default::default() } } else { let field_type = &field.ty; quote_spanned! { field.span() => { let #res = <#field_type as _parity_scale_codec::Decode>::decode(#input); match #res { - Err(e) => return Err(e.chain(#err_msg)), - Ok(#res) => #res, + ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), + ::core::result::Result::Ok(#res) => #res, } } } @@ -173,7 +173,7 @@ fn create_instance( }); quote_spanned! { fields.span() => - Ok(#name { + ::core::result::Result::Ok(#name { #( #recurse, )* }) } @@ -186,14 +186,14 @@ fn create_instance( }); quote_spanned! { fields.span() => - Ok(#name ( + ::core::result::Result::Ok(#name ( #( #recurse, )* )) } }, Fields::Unit => { quote_spanned! { fields.span() => - Ok(#name) + ::core::result::Result::Ok(#name) } }, } diff --git a/derive/src/encode.rs b/derive/src/encode.rs index 38fef711..434d4f3c 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -85,7 +85,7 @@ fn encode_single_field( _parity_scale_codec::Encode::encode(&#final_field_variable) } - fn using_encoded R>(&#i_self, f: F) -> R { + fn using_encoded R>(&#i_self, f: F) -> R { _parity_scale_codec::Encode::using_encoded(&#final_field_variable, f) } } @@ -240,7 +240,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { quote_spanned! { f.span() => #type_name :: #name { #( ref #names, )* } => { - #dest.push_byte(#index as u8); + #dest.push_byte(#index as ::core::primitive::u8); #encode_fields } } @@ -265,7 +265,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { quote_spanned! { f.span() => #type_name :: #name ( #( ref #names, )* ) => { - #dest.push_byte(#index as u8); + #dest.push_byte(#index as ::core::primitive::u8); #encode_fields } } @@ -273,7 +273,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { Fields::Unit => { quote_spanned! { f.span() => #type_name :: #name => { - #dest.push_byte(#index as u8); + #dest.push_byte(#index as ::core::primitive::u8); } } }, diff --git a/derive/src/lib.rs b/derive/src/lib.rs index a283bc39..b14bba0a 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -210,7 +210,7 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream impl #impl_generics _parity_scale_codec::Decode for #name #ty_generics #where_clause { fn decode<__CodecInputEdqy: _parity_scale_codec::Input>( #input_: &mut __CodecInputEdqy - ) -> core::result::Result { + ) -> ::core::result::Result { #decoding } } @@ -312,9 +312,9 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr #inner_field } fn decode_from(x: #inner_ty) - -> core::result::Result<#name #ty_generics, _parity_scale_codec::Error> + -> ::core::result::Result<#name #ty_generics, _parity_scale_codec::Error> { - Ok(#constructor) + ::core::result::Result::Ok(#constructor) } } From 3a552fb8b373a1d47e5a1d91751bb0e7519552b8 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 14 Jun 2021 00:20:31 -0700 Subject: [PATCH 051/286] Allow lint attributes to be passed through to the impl block (#272) --- derive/src/lib.rs | 12 ++++++++---- derive/src/utils.rs | 8 ++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index b14bba0a..4dd1981d 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -28,6 +28,8 @@ use proc_macro_crate::{crate_name, FoundCrate}; use syn::spanned::Spanned; use syn::{Data, Field, Fields, DeriveInput, Error}; +use crate::utils::is_lint_attribute; + mod decode; mod encode; mod utils; @@ -51,8 +53,9 @@ fn include_parity_scale_codec_crate() -> proc_macro2::TokenStream { } /// Wraps the impl block in a "dummy const" -fn wrap_with_dummy_const(impl_block: proc_macro2::TokenStream) -> proc_macro::TokenStream { +fn wrap_with_dummy_const(input: DeriveInput, impl_block: proc_macro2::TokenStream) -> proc_macro::TokenStream { let parity_codec_crate = include_parity_scale_codec_crate(); + let attrs = input.attrs.into_iter().filter(is_lint_attribute); let generated = quote! { const _: () = { @@ -60,6 +63,7 @@ fn wrap_with_dummy_const(impl_block: proc_macro2::TokenStream) -> proc_macro::To #[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))] #[allow(rust_2018_idioms)] #parity_codec_crate + #(#attrs)* #impl_block }; }; @@ -169,7 +173,7 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream impl #impl_generics _parity_scale_codec::EncodeLike for #name #ty_generics #where_clause {} }; - wrap_with_dummy_const(impl_block) + wrap_with_dummy_const(input, impl_block) } /// Derive `parity_scale_codec::Decode` and for struct and enum. @@ -216,7 +220,7 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream } }; - wrap_with_dummy_const(impl_block) + wrap_with_dummy_const(input, impl_block) } /// Derive `parity_scale_codec::Compact` and `parity_scale_codec::CompactAs` for struct with single @@ -327,5 +331,5 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr } }; - wrap_with_dummy_const(impl_block) + wrap_with_dummy_const(input, impl_block) } diff --git a/derive/src/utils.rs b/derive/src/utils.rs index cf50316a..a366fd7b 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -221,6 +221,14 @@ pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> { Ok(()) } +// Check if the attribute is `#[allow(..)]`, `#[deny(..)]`, `#[forbid(..)]` or `#[warn(..)]`. +pub fn is_lint_attribute(attr: &Attribute) -> bool { + attr.path.is_ident("allow") + || attr.path.is_ident("deny") + || attr.path.is_ident("forbid") + || attr.path.is_ident("warn") +} + // Ensure a field is decorated only with the following attributes: // * `#[codec(skip)]` // * `#[codec(compact)]` From 4a6caebd6fe8b7495b23402cee31f341a3a55a00 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 14 Jun 2021 16:28:52 -0700 Subject: [PATCH 052/286] Bump version to 2.1.2 (#273) --- CHANGELOG.md | 5 +++++ Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39704935..6e2a0269 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.1.2] - 2021-06-14 + +### Changed +- Lint attributes now pass through to the derived impls of `Encode`, `Decode` and `CompactAs`. PR #272 + ## [2.1.0] - 2021-04-06 ### Fix diff --git a/Cargo.toml b/Cargo.toml index d2b02a39..85ce2731 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.1.1" +version = "2.1.2" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" From c5d9754374e708e899efa465de7e707d6305e277 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Tue, 15 Jun 2021 15:58:34 -0700 Subject: [PATCH 053/286] Bump version to 2.1.3 (#274) --- CHANGELOG.md | 2 +- Cargo.lock | 4 ++-- Cargo.toml | 6 +++--- derive/Cargo.toml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e2a0269..e9c6c2b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [2.1.2] - 2021-06-14 +## [2.1.3] - 2021-06-14 ### Changed - Lint attributes now pass through to the derived impls of `Encode`, `Decode` and `CompactAs`. PR #272 diff --git a/Cargo.lock b/Cargo.lock index 1cd712b5..b2b23254 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,7 +435,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "2.1.1" +version = "2.1.3" dependencies = [ "arbitrary", "arrayvec", @@ -451,7 +451,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "2.1.0" +version = "2.1.3" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index 85ce2731..64866f74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.1.2" +version = "2.1.3" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,7 +11,7 @@ edition = "2018" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "2.1.0", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "2.1.3", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } @@ -20,7 +20,7 @@ arbitrary = { version = "1.0.1", features = ["derive"], optional = true } [dev-dependencies] criterion = "0.3.0" serde_derive = { version = "1.0" } -parity-scale-codec-derive = { path = "derive", version = "2.1.0", default-features = false } +parity-scale-codec-derive = { path = "derive", version = "2.1.3", default-features = false } quickcheck = "1.0" [[bench]] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 346e4ccd..cd14eb41 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.1.0" +version = "2.1.3" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" From f590442e82f41c9ef28bdf966c9e0da0f409bc8d Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Wed, 23 Jun 2021 12:31:48 +0200 Subject: [PATCH 054/286] Move `MaxEncodedLen` from Substrate (#268) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * move MaxEncodedLen trait from Substrate * Move derive macro and tests from Substrate * only run ui tests when derive feature enabled * reduce note-taking documentation Co-authored-by: Bastian Köcher * Bless trybuild `tests/max_encoded_len_ui/union.rs` test * Update docs (these files are not part of substrate) Co-authored-by: Andronik Ordian * Mention new `MaxEncodedLen` trait in the CHANGELOG.md * Prepare a 2.2.0-rc.1 release This is a pre-release rather than a full release in order to help shape the new `MaxEncodedLen` trait used in Substrate in case some more involved changes are found out to be required. The API did not change since its introduction until now so chances are slim but it's good to leave some leeway. * incorporate changes made to Substrate version of MaxEncodedLen Note: doesn't include the MaxEncodedLen impl for H160, H256, H512. A substrate companion will be necessary to re-add those. * remove redundant no_std * Rewrite fn max_encoded_len_trait for clarity * simplify logic checking for invalid attr Co-authored-by: Bastian Köcher * remove bogus whitespace Co-authored-by: Bastian Köcher * use Path::is_ident() helper Co-authored-by: Bastian Köcher * rm unused import Co-authored-by: Bastian Köcher Co-authored-by: Igor Matuszewski Co-authored-by: Andronik Ordian --- CHANGELOG.md | 7 + Cargo.lock | 53 ++++++- Cargo.toml | 8 +- derive/Cargo.toml | 4 +- derive/src/lib.rs | 9 +- derive/src/max_encoded_len.rs | 131 ++++++++++++++++ derive/src/utils.rs | 86 ++++++++--- src/lib.rs | 108 +++++++++---- src/max_encoded_len.rs | 132 ++++++++++++++++ tests/max_encoded_len.rs | 145 ++++++++++++++++++ tests/max_encoded_len_ui.rs | 24 +++ tests/max_encoded_len_ui/incomplete_attr.rs | 9 ++ .../max_encoded_len_ui/incomplete_attr.stderr | 19 +++ tests/max_encoded_len_ui/list_list_item.rs | 9 ++ .../max_encoded_len_ui/list_list_item.stderr | 19 +++ tests/max_encoded_len_ui/not_encode.rs | 6 + tests/max_encoded_len_ui/not_encode.stderr | 13 ++ tests/max_encoded_len_ui/not_mel.rs | 13 ++ tests/max_encoded_len_ui/not_mel.stderr | 21 +++ tests/max_encoded_len_ui/path_list_item.rs | 9 ++ .../max_encoded_len_ui/path_list_item.stderr | 19 +++ tests/max_encoded_len_ui/union.rs | 9 ++ tests/max_encoded_len_ui/union.stderr | 11 ++ .../max_encoded_len_ui/unsupported_variant.rs | 11 ++ .../unsupported_variant.stderr | 12 ++ 25 files changed, 832 insertions(+), 55 deletions(-) create mode 100644 derive/src/max_encoded_len.rs create mode 100644 src/max_encoded_len.rs create mode 100644 tests/max_encoded_len.rs create mode 100644 tests/max_encoded_len_ui.rs create mode 100644 tests/max_encoded_len_ui/incomplete_attr.rs create mode 100644 tests/max_encoded_len_ui/incomplete_attr.stderr create mode 100644 tests/max_encoded_len_ui/list_list_item.rs create mode 100644 tests/max_encoded_len_ui/list_list_item.stderr create mode 100644 tests/max_encoded_len_ui/not_encode.rs create mode 100644 tests/max_encoded_len_ui/not_encode.stderr create mode 100644 tests/max_encoded_len_ui/not_mel.rs create mode 100644 tests/max_encoded_len_ui/not_mel.stderr create mode 100644 tests/max_encoded_len_ui/path_list_item.rs create mode 100644 tests/max_encoded_len_ui/path_list_item.stderr create mode 100644 tests/max_encoded_len_ui/union.rs create mode 100644 tests/max_encoded_len_ui/union.stderr create mode 100644 tests/max_encoded_len_ui/unsupported_variant.rs create mode 100644 tests/max_encoded_len_ui/unsupported_variant.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index e9c6c2b8..36f44459 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +## [2.2.0-rc.1] - 2021-06-22 + +### Added +- `MaxEncodedLen` trait for items that have a statically known maximum encoded size. ([#268](https://github.com/paritytech/parity-scale-codec/pull/268)) + ## [2.1.3] - 2021-06-14 ### Changed diff --git a/Cargo.lock b/Cargo.lock index b2b23254..56fe8289 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,6 +297,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + [[package]] name = "half" version = "1.7.1" @@ -323,6 +329,17 @@ dependencies = [ "memmap", ] +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5dacb10c5b3bb92d46ba347505a9041e676bb20ad220101326bffb0c93031ee" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "itertools" version = "0.9.0" @@ -435,7 +452,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "2.1.3" +version = "2.2.0-rc.1" dependencies = [ "arbitrary", "arrayvec", @@ -443,15 +460,17 @@ dependencies = [ "byte-slice-cast", "criterion", "generic-array", + "impl-trait-for-tuples", "parity-scale-codec-derive", "quickcheck", "serde", "serde_derive", + "trybuild", ] [[package]] name = "parity-scale-codec-derive" -version = "2.1.3" +version = "2.2.0-rc.1" dependencies = [ "parity-scale-codec", "proc-macro-crate", @@ -653,6 +672,9 @@ name = "serde" version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" +dependencies = [ + "serde_derive", +] [[package]] name = "serde_cbor" @@ -666,9 +688,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.118" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" dependencies = [ "proc-macro2", "quote", @@ -703,6 +725,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e" +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -760,6 +791,20 @@ dependencies = [ "serde", ] +[[package]] +name = "trybuild" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1768998d9a3b179411618e377dbb134c58a88cda284b0aa71c42c40660127d46" +dependencies = [ + "glob", + "lazy_static", + "serde", + "serde_json", + "termcolor", + "toml", +] + [[package]] name = "typenum" version = "1.12.0" diff --git a/Cargo.toml b/Cargo.toml index 64866f74..daf1e2f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.1.3" +version = "2.2.0-rc.1" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,17 +11,19 @@ edition = "2018" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "2.1.3", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "2.2.0-rc.1", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } arbitrary = { version = "1.0.1", features = ["derive"], optional = true } +impl-trait-for-tuples = "0.2.1" [dev-dependencies] criterion = "0.3.0" serde_derive = { version = "1.0" } -parity-scale-codec-derive = { path = "derive", version = "2.1.3", default-features = false } +parity-scale-codec-derive = { path = "derive", version = "2.2.0-rc.1", default-features = false } quickcheck = "1.0" +trybuild = "1.0.42" [[bench]] name = "benches" diff --git a/derive/Cargo.toml b/derive/Cargo.toml index cd14eb41..76788679 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.1.3" +version = "2.2.0-rc.1" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" @@ -16,4 +16,4 @@ proc-macro2 = "1.0.6" proc-macro-crate = "1.0.0" [dev-dependencies] -parity-scale-codec = { path = "..", version = "2.0.1" } +parity-scale-codec = { path = "..", version = "2.2.0-rc.1" } diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 4dd1981d..c95ce27d 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2017-2018 Parity Technologies +// Copyright 2017-2021 Parity Technologies // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ use crate::utils::is_lint_attribute; mod decode; mod encode; +mod max_encoded_len; mod utils; mod trait_bounds; @@ -333,3 +334,9 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr wrap_with_dummy_const(input, impl_block) } + +/// Derive `MaxEncodedLen`. +#[proc_macro_derive(MaxEncodedLen, attributes(max_encoded_len_mod))] +pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + max_encoded_len::derive_max_encoded_len(input) +} diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs new file mode 100644 index 00000000..f8ad7254 --- /dev/null +++ b/derive/src/max_encoded_len.rs @@ -0,0 +1,131 @@ +// Copyright (C) 2021 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 crate::utils::codec_crate_path; +use quote::{quote, quote_spanned}; +use syn::{ + Data, DeriveInput, Fields, GenericParam, Generics, TraitBound, Type, TypeParamBound, + parse_quote, spanned::Spanned, +}; + +/// impl for `#[derive(MaxEncodedLen)]` +pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input: DeriveInput = match syn::parse(input) { + Ok(input) => input, + Err(e) => return e.to_compile_error().into(), + }; + + let mel_trait = match max_encoded_len_trait(&input) { + Ok(mel_trait) => mel_trait, + Err(e) => return e.to_compile_error().into(), + }; + + let name = &input.ident; + let generics = add_trait_bounds(input.generics, mel_trait.clone()); + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let data_expr = data_length_expr(&input.data); + + quote::quote!( + const _: () = { + impl #impl_generics #mel_trait for #name #ty_generics #where_clause { + fn max_encoded_len() -> usize { + #data_expr + } + } + }; + ) + .into() +} + +fn max_encoded_len_trait(input: &DeriveInput) -> syn::Result { + let mel = codec_crate_path(&input.attrs)?; + Ok(parse_quote!(#mel::MaxEncodedLen)) +} + +// Add a bound `T: MaxEncodedLen` to every type parameter T. +fn add_trait_bounds(mut generics: Generics, mel_trait: TraitBound) -> Generics { + for param in &mut generics.params { + if let GenericParam::Type(ref mut type_param) = *param { + type_param.bounds.push(TypeParamBound::Trait(mel_trait.clone())); + } + } + generics +} + +/// generate an expression to sum up the max encoded length from several fields +fn fields_length_expr(fields: &Fields) -> proc_macro2::TokenStream { + let type_iter: Box> = match fields { + Fields::Named(ref fields) => Box::new(fields.named.iter().map(|field| &field.ty)), + Fields::Unnamed(ref fields) => Box::new(fields.unnamed.iter().map(|field| &field.ty)), + Fields::Unit => Box::new(std::iter::empty()), + }; + // expands to an expression like + // + // 0 + // .saturating_add(::max_encoded_len()) + // .saturating_add(::max_encoded_len()) + // + // We match the span of each field to the span of the corresponding + // `max_encoded_len` call. This way, if one field's type doesn't implement + // `MaxEncodedLen`, the compiler's error message will underline which field + // caused the issue. + let expansion = type_iter.map(|ty| { + quote_spanned! { + ty.span() => .saturating_add(<#ty>::max_encoded_len()) + } + }); + quote! { + 0_usize #( #expansion )* + } +} + +// generate an expression to sum up the max encoded length of each field +fn data_length_expr(data: &Data) -> proc_macro2::TokenStream { + match *data { + Data::Struct(ref data) => fields_length_expr(&data.fields), + Data::Enum(ref data) => { + // We need an expression expanded for each variant like + // + // 0 + // .max() + // .max() + // .saturating_add(1) + // + // The 1 derives from the discriminant; see + // https://github.com/paritytech/parity-scale-codec/ + // blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/derive/src/encode.rs#L211-L216 + // + // Each variant expression's sum is computed the way an equivalent struct's would be. + + let expansion = data.variants.iter().map(|variant| { + let variant_expression = fields_length_expr(&variant.fields); + quote! { + .max(#variant_expression) + } + }); + + quote! { + 0_usize #( #expansion )* .saturating_add(1) + } + } + Data::Union(ref data) => { + // https://github.com/paritytech/parity-scale-codec/ + // blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/derive/src/encode.rs#L290-L293 + syn::Error::new(data.union_token.span(), "Union types are not supported") + .to_compile_error() + } + } +} diff --git a/derive/src/utils.rs b/derive/src/utils.rs index a366fd7b..2d393d07 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -19,11 +19,13 @@ use std::str::FromStr; -use proc_macro2::TokenStream; +use proc_macro_crate::{crate_name, FoundCrate}; +use proc_macro2::{Span, Ident, TokenStream}; +use quote::quote; use syn::{ - spanned::Spanned, - Meta, NestedMeta, Lit, Attribute, Variant, Field, DeriveInput, Fields, Data, FieldsUnnamed, - FieldsNamed, MetaNameValue, punctuated::Punctuated, token, parse::Parse, + Attribute, Data, DeriveInput, Error, Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, + MetaNameValue, NestedMeta, parse::Parse, Path, punctuated::Punctuated, + spanned::Spanned, token, Variant, }; fn find_meta_item<'a, F, R, I, M>(mut itr: I, mut pred: F) -> Option where @@ -119,6 +121,48 @@ pub fn has_dumb_trait_bound(attrs: &[Attribute]) -> bool { }).is_some() } +/// Generate the crate access for the crate using 2018 syntax. +fn crate_access() -> syn::Result { + const DEF_CRATE: &str = "parity-scale-codec"; + match crate_name(DEF_CRATE) { + Ok(FoundCrate::Itself) => { + let name = DEF_CRATE.to_string().replace("-", "_"); + Ok(syn::Ident::new(&name, Span::call_site())) + } + Ok(FoundCrate::Name(name)) => Ok(Ident::new(&name, Span::call_site())), + Err(e) => Err(Error::new(Span::call_site(), e)), + } +} + +/// Match `#[codec(crate = ...)]` and return the `...` +fn codec_crate_path_lit(attr: &Attribute) -> Option { + // match `#[codec ...]` + if !attr.path.is_ident("codec") { + return None; + }; + // match `#[codec(crate = ...)]` and return the `...` + match attr.parse_meta() { + Ok(Meta::NameValue(MetaNameValue { path, lit, .. })) if path.is_ident("crate") => { + Some(lit) + } + _ => None, + } +} + +/// Match `#[codec(crate = "...")]` and return the contents as a `Path` +pub fn codec_crate_path(attrs: &[Attribute]) -> syn::Result { + match attrs.iter().find_map(codec_crate_path_lit) { + Some(Lit::Str(lit_str)) => lit_str.parse::(), + Some(lit) => { + Err(Error::new( + lit.span(), + "Expected format: #[codec(crate = \"path::to::codec\")]", + )) + } + None => crate_access().map(|ident| ident.into()), + } +} + /// Trait bounds. pub type TraitBounds = Punctuated; @@ -179,12 +223,20 @@ pub fn filter_skip_unnamed<'a>(fields: &'a syn::FieldsUnnamed) -> impl Iterator< /// Ensure attributes are correctly applied. This *must* be called before using /// any of the attribute finder methods or the macro may panic if it encounters /// misapplied attributes. -/// `#[codec(dumb_trait_bound)]` is the only accepted top attribute. +/// +/// The top level can have the following attributes: +/// +/// * `#[codec(dumb_trait_bound)]` +/// * `#[codec(crate = "path::to::crate")] +/// /// Fields can have the following attributes: +/// /// * `#[codec(skip)]` /// * `#[codec(compact)]` /// * `#[codec(encoded_as = "$EncodeAs")]` with $EncodedAs a valid TokenStream +/// /// Variants can have the following attributes: +/// /// * `#[codec(skip)]` /// * `#[codec(index = $int)]` pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> { @@ -293,26 +345,24 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { // Only `#[codec(dumb_trait_bound)]` is accepted as top attribute fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { - let top_error = - "Invalid attribute only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]` or \ + let top_error = "Invalid attribute: only `#[codec(dumb_trait_bound)]`, \ + `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = \"path::to::crate\")]`, or \ `#[codec(decode_bound(T: Decode))]` are accepted as top attribute"; - if attr.path.is_ident("codec") { - if attr.parse_args::>().is_ok() { - return Ok(()) - } else if attr.parse_args::>().is_ok() { - return Ok(()) - } else { - match attr.parse_meta()? { - Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { - match meta_list.nested.first().expect("Just checked that there is one item; qed") { + if attr.path.is_ident("codec") + && attr.parse_args::>().is_err() + && attr.parse_args::>().is_err() + && codec_crate_path_lit(attr).is_none() + { + match attr.parse_meta()? { + Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { + match meta_list.nested.first().expect("Just checked that there is one item; qed") { NestedMeta::Meta(Meta::Path(path)) if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => Ok(()), elt @ _ => Err(syn::Error::new(elt.span(), top_error)), } - }, - _ => Err(syn::Error::new(attr.span(), top_error)), } + _ => Err(syn::Error::new(attr.span(), top_error)), } } else { Ok(()) diff --git a/src/lib.rs b/src/lib.rs index ca0d8c7a..541a6487 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2017, 2018 Parity Technologies +// Copyright 2017-2021 Parity Technologies // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,8 +21,8 @@ //! suitable for resource-constrained execution environments like blockchain runtimes and low-power, //! low-memory devices. //! -//! It is important to note that the encoding context (knowledge of how the types and data structures look) -//! needs to be known separately at both encoding and decoding ends. +//! It is important to note that the encoding context (knowledge of how the types and data +//! structures look) needs to be known separately at both encoding and decoding ends. //! The encoded data does not include this contextual information. //! //! To get a better understanding of how the encoding is done for different types, @@ -35,46 +35,55 @@ //! //! ### Encode //! -//! The `Encode` trait is used for encoding of data into the SCALE format. The `Encode` trait contains the following functions: +//! The `Encode` trait is used for encoding of data into the SCALE format. The `Encode` trait +//! contains the following functions: +//! //! * `size_hint(&self) -> usize`: Gets the capacity (in bytes) required for the encoded data. //! This is to avoid double-allocation of memory needed for the encoding. //! It can be an estimate and does not need to be an exact number. -//! If the size is not known, even no good maximum, then we can skip this function from the trait implementation. -//! This is required to be a cheap operation, so should not involve iterations etc. -//! * `encode_to(&self, dest: &mut T)`: Encodes the value and appends it to a destination buffer. +//! If the size is not known, even no good maximum, then we can skip this function from the trait +//! implementation. This is required to be a cheap operation, so should not involve iterations etc. +//! * `encode_to(&self, dest: &mut T)`: Encodes the value and appends it to a destination +//! buffer. //! * `encode(&self) -> Vec`: Encodes the type data and returns a slice. -//! * `using_encoded R>(&self, f: F) -> R`: Encodes the type data and executes a closure on the encoded value. +//! * `using_encoded R>(&self, f: F) -> R`: Encodes the type data and +//! executes a closure on the encoded value. //! Returns the result from the executed closure. //! -//! **Note:** Implementations should override `using_encoded` for value types and `encode_to` for allocating types. -//! `size_hint` should be implemented for all types, wherever possible. Wrapper types should override all methods. +//! **Note:** Implementations should override `using_encoded` for value types and `encode_to` for +//! allocating types. `size_hint` should be implemented for all types, wherever possible. Wrapper +//! types should override all methods. //! //! ### Decode //! -//! The `Decode` trait is used for deserialization/decoding of encoded data into the respective types. +//! The `Decode` trait is used for deserialization/decoding of encoded data into the respective +//! types. //! -//! * `fn decode(value: &mut I) -> Result`: Tries to decode the value from SCALE format to the type it is called on. +//! * `fn decode(value: &mut I) -> Result`: Tries to decode the value from +//! SCALE format to the type it is called on. //! Returns an `Err` if the decoding fails. //! //! ### CompactAs //! -//! The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes them even more space/memory efficient. -//! The compact encoding is described [here](https://substrate.dev/docs/en/knowledgebase/advanced/codec#compactgeneral-integers). +//! The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes +//! them even more space/memory efficient. The compact encoding is described [here](https://substrate.dev/docs/en/knowledgebase/advanced/codec#compactgeneral-integers). //! //! * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. //! The type `As` is defined in the same trait and its implementation should be compact encode-able. -//! * `decode_from(_: Self::As) -> Result`: Decodes the type (self) from a compact encode-able type. +//! * `decode_from(_: Self::As) -> Result`: Decodes the type (self) from a compact +//! encode-able type. //! //! ### HasCompact //! -//! The `HasCompact` trait, if implemented, tells that the corresponding type is a compact encode-able type. +//! The `HasCompact` trait, if implemented, tells that the corresponding type is a compact +//! encode-able type. //! //! ### EncodeLike //! //! The `EncodeLike` trait needs to be implemented for each type manually. When using derive, it is -//! done automatically for you. Basically the trait gives you the opportunity to accept multiple types -//! to a function that all encode to the same representation. +//! done automatically for you. Basically the trait gives you the opportunity to accept multiple +//! types to a function that all encode to the same representation. //! //! ## Usage Examples //! @@ -212,24 +221,22 @@ //! ## Derive attributes //! //! The derive implementation supports the following attributes: -//! - `codec(dumb_trait_bound)`: This attribute needs to be placed above the type that one of the trait -//! should be implemented for. It will make the algorithm that determines the to-add trait bounds -//! fall back to just use the type parameters of the type. This can be useful for situation where -//! the algorithm includes private types in the public interface. By using this attribute, you should -//! not get this error/warning again. +//! - `codec(dumb_trait_bound)`: This attribute needs to be placed above the type that one of the +//! trait should be implemented for. It will make the algorithm that determines the to-add trait +//! bounds fall back to just use the type parameters of the type. This can be useful for situation +//! where the algorithm includes private types in the public interface. By using this attribute, +//! you should not get this error/warning again. //! - `codec(skip)`: Needs to be placed above a field or variant and makes it to be skipped while //! encoding/decoding. //! - `codec(compact)`: Needs to be placed above a field and makes the field use compact encoding. //! (The type needs to support compact encoding.) -//! - `codec(encoded_as = "OtherType")`: Needs to be placed above a field and makes the field being encoded -//! by using `OtherType`. +//! - `codec(encoded_as = "OtherType")`: Needs to be placed above a field and makes the field being +//! encoded by using `OtherType`. //! - `codec(index = 0)`: Needs to be placed above an enum variant to make the variant use the given //! index when encoded. By default the index is determined by counting from `0` beginning wth the //! first variant. -//! #![warn(missing_docs)] - #![cfg_attr(not(feature = "std"), no_std)] #[cfg(not(feature = "std"))] @@ -274,6 +281,7 @@ mod depth_limit; mod encode_append; mod encode_like; mod error; +mod max_encoded_len; pub use self::error::Error; pub use self::codec::{ @@ -289,3 +297,49 @@ pub use self::decode_all::DecodeAll; pub use self::depth_limit::DecodeLimit; pub use self::encode_append::EncodeAppend; pub use self::encode_like::{EncodeLike, Ref}; +pub use max_encoded_len::MaxEncodedLen; +/// Derive macro for [`MaxEncodedLen`][max_encoded_len::MaxEncodedLen]. +/// +/// # Examples +/// +/// ``` +/// # use parity_scale_codec::{Encode, MaxEncodedLen}; +/// #[derive(Encode, MaxEncodedLen)] +/// struct Example; +/// ``` +/// +/// ``` +/// # use parity_scale_codec::{Encode, MaxEncodedLen}; +/// #[derive(Encode, MaxEncodedLen)] +/// struct TupleStruct(u8, u32); +/// +/// assert_eq!(TupleStruct::max_encoded_len(), u8::max_encoded_len() + u32::max_encoded_len()); +/// ``` +/// +/// ``` +/// # use parity_scale_codec::{Encode, MaxEncodedLen}; +/// #[derive(Encode, MaxEncodedLen)] +/// enum GenericEnum { +/// A, +/// B(T), +/// } +/// +/// assert_eq!(GenericEnum::::max_encoded_len(), u8::max_encoded_len() + u8::max_encoded_len()); +/// assert_eq!(GenericEnum::::max_encoded_len(), u8::max_encoded_len() + u128::max_encoded_len()); +/// ``` +/// +/// # Within other macros +/// +/// Sometimes the `MaxEncodedLen` trait and macro are used within another macro, and it can't be +/// guaranteed that the `max_encoded_len` module is available at the call site. In that case, the +/// macro should reexport the `max_encoded_len` module and specify the path to the reexport: +/// +/// ```ignore +/// pub use parity_scale_codec::max_encoded_len; +/// +/// #[derive(Encode, MaxEncodedLen)] +/// #[codec(crate = "$crate::max_encoded_len")] +/// struct Example; +/// ``` +#[cfg(feature = "derive")] +pub use parity_scale_codec_derive::MaxEncodedLen; diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs new file mode 100644 index 00000000..6579af32 --- /dev/null +++ b/src/max_encoded_len.rs @@ -0,0 +1,132 @@ +// Copyright (C) 2021 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. + +//! `trait MaxEncodedLen` bounds the maximum encoded length of items. + +use crate::{Compact, Encode}; +use impl_trait_for_tuples::impl_for_tuples; +use core::{mem, marker::PhantomData}; + +/// Items implementing `MaxEncodedLen` have a statically known maximum encoded size. +/// +/// Some containers, such as `BoundedVec`, have enforced size limits and this trait +/// can be implemented accurately. Other containers, such as `StorageMap`, do not have enforced size +/// limits. For those containers, it is necessary to make a documented assumption about the maximum +/// usage, and compute the max encoded length based on that assumption. +pub trait MaxEncodedLen: Encode { + /// Upper bound, in bytes, of the maximum encoded size of this item. + fn max_encoded_len() -> usize; +} + +macro_rules! impl_primitives { + ( $($t:ty),+ ) => { + $( + impl MaxEncodedLen for $t { + fn max_encoded_len() -> usize { + mem::size_of::<$t>() + } + } + )+ + }; +} + +impl_primitives!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, bool); + +macro_rules! impl_compact { + ($( $t:ty => $e:expr; )*) => { + $( + impl MaxEncodedLen for Compact<$t> { + fn max_encoded_len() -> usize { + $e + } + } + )* + }; +} + +impl_compact!( + // github.com/paritytech/parity-scale-codec/blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/src/compact.rs#L261 + u8 => 2; + // github.com/paritytech/parity-scale-codec/blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/src/compact.rs#L291 + u16 => 4; + // github.com/paritytech/parity-scale-codec/blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/src/compact.rs#L326 + u32 => 5; + // github.com/paritytech/parity-scale-codec/blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/src/compact.rs#L369 + u64 => 9; + // github.com/paritytech/parity-scale-codec/blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/src/compact.rs#L413 + u128 => 17; +); + +// impl_for_tuples for values 19 and higher fails because that's where the WrapperTypeEncode impl stops. +#[impl_for_tuples(18)] +impl MaxEncodedLen for Tuple { + fn max_encoded_len() -> usize { + let mut len: usize = 0; + for_tuples!( #( len = len.saturating_add(Tuple::max_encoded_len()); )* ); + len + } +} + +impl MaxEncodedLen for [T; N] { + fn max_encoded_len() -> usize { + T::max_encoded_len().saturating_mul(N) + } +} + +impl MaxEncodedLen for Option { + fn max_encoded_len() -> usize { + T::max_encoded_len().saturating_add(1) + } +} + +impl MaxEncodedLen for Result +where + T: MaxEncodedLen, + E: MaxEncodedLen, +{ + fn max_encoded_len() -> usize { + T::max_encoded_len().max(E::max_encoded_len()).saturating_add(1) + } +} + +impl MaxEncodedLen for PhantomData { + fn max_encoded_len() -> usize { + 0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! test_compact_length { + ($(fn $name:ident($t:ty);)*) => { + $( + #[test] + fn $name() { + assert_eq!(Compact(<$t>::MAX).encode().len(), Compact::<$t>::max_encoded_len()); + } + )* + }; + } + + test_compact_length!( + fn compact_u8(u8); + fn compact_u16(u16); + fn compact_u32(u32); + fn compact_u64(u64); + fn compact_u128(u128); + ); +} diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs new file mode 100644 index 00000000..df1c05f6 --- /dev/null +++ b/tests/max_encoded_len.rs @@ -0,0 +1,145 @@ +// Copyright (C) 2020-2021 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. + +//! Tests for MaxEncodedLen derive macro +#![cfg(feature = "derive")] + +use parity_scale_codec::{MaxEncodedLen, Compact, Encode}; + +#[derive(Encode, MaxEncodedLen)] +struct Primitives { + bool: bool, + eight: u8, +} + +#[test] +fn primitives_max_length() { + assert_eq!(Primitives::max_encoded_len(), 2); +} + +#[derive(Encode, MaxEncodedLen)] +struct Composites { + fixed_size_array: [u8; 128], + tuple: (u128, u128), +} + +#[test] +fn composites_max_length() { + assert_eq!(Composites::max_encoded_len(), 128 + 16 + 16); +} + +#[derive(Encode, MaxEncodedLen)] +struct Generic { + one: T, + two: T, +} + +#[test] +fn generic_max_length() { + assert_eq!(Generic::::max_encoded_len(), u8::max_encoded_len() * 2); + assert_eq!(Generic::::max_encoded_len(), u32::max_encoded_len() * 2); +} + +#[derive(Encode, MaxEncodedLen)] +struct TwoGenerics { + t: T, + u: U, +} + +#[test] +fn two_generics_max_length() { + assert_eq!( + TwoGenerics::::max_encoded_len(), + u8::max_encoded_len() + u16::max_encoded_len() + ); + assert_eq!( + TwoGenerics::, [u16; 8]>::max_encoded_len(), + Compact::::max_encoded_len() + <[u16; 8]>::max_encoded_len() + ); +} + +#[derive(Encode, MaxEncodedLen)] +struct UnitStruct; + +#[test] +fn unit_struct_max_length() { + assert_eq!(UnitStruct::max_encoded_len(), 0); +} + +#[derive(Encode, MaxEncodedLen)] +struct TupleStruct(u8, u32); + +#[test] +fn tuple_struct_max_length() { + assert_eq!(TupleStruct::max_encoded_len(), u8::max_encoded_len() + u32::max_encoded_len()); +} + +#[derive(Encode, MaxEncodedLen)] +struct TupleGeneric(T, T); + +#[test] +fn tuple_generic_max_length() { + assert_eq!(TupleGeneric::::max_encoded_len(), u8::max_encoded_len() * 2); + assert_eq!(TupleGeneric::::max_encoded_len(), u32::max_encoded_len() * 2); +} + +#[derive(Encode, MaxEncodedLen)] +#[allow(unused)] +enum UnitEnum { + A, + B, +} + +#[test] +fn unit_enum_max_length() { + assert_eq!(UnitEnum::max_encoded_len(), 1); +} + +#[derive(Encode, MaxEncodedLen)] +#[allow(unused)] +enum TupleEnum { + A(u32), + B, +} + +#[test] +fn tuple_enum_max_length() { + assert_eq!(TupleEnum::max_encoded_len(), 1 + u32::max_encoded_len()); +} + +#[derive(Encode, MaxEncodedLen)] +#[allow(unused)] +enum StructEnum { + A { sixty_four: u64, one_twenty_eight: u128 }, + B, +} + +#[test] +fn struct_enum_max_length() { + assert_eq!(StructEnum::max_encoded_len(), 1 + u64::max_encoded_len() + u128::max_encoded_len()); +} + +// ensure that enums take the max of variant length, not the sum +#[derive(Encode, MaxEncodedLen)] +#[allow(unused)] +enum EnumMaxNotSum { + A(u32), + B(u32), +} + +#[test] +fn enum_max_not_sum_max_length() { + assert_eq!(EnumMaxNotSum::max_encoded_len(), 1 + u32::max_encoded_len()); +} diff --git a/tests/max_encoded_len_ui.rs b/tests/max_encoded_len_ui.rs new file mode 100644 index 00000000..cb81d884 --- /dev/null +++ b/tests/max_encoded_len_ui.rs @@ -0,0 +1,24 @@ +// Copyright (C) 2020-2021 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. + +#[test] +#[cfg(feature = "derive")] +fn derive_no_bound_ui() { + // As trybuild is using `cargo check`, we don't need the real WASM binaries. + std::env::set_var("SKIP_WASM_BUILD", "1"); + + let t = trybuild::TestCases::new(); + t.compile_fail("tests/max_encoded_len_ui/*.rs"); +} diff --git a/tests/max_encoded_len_ui/incomplete_attr.rs b/tests/max_encoded_len_ui/incomplete_attr.rs new file mode 100644 index 00000000..884c3a16 --- /dev/null +++ b/tests/max_encoded_len_ui/incomplete_attr.rs @@ -0,0 +1,9 @@ +use parity_scale_codec::{Encode, MaxEncodedLen}; + +#[derive(Encode, MaxEncodedLen)] +#[codec(crate)] +struct Example; + +fn main() { + let _ = Example::max_encoded_len(); +} diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr new file mode 100644 index 00000000..53e5b726 --- /dev/null +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -0,0 +1,19 @@ +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = "path::to::crate")]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute + --> $DIR/incomplete_attr.rs:4:9 + | +4 | #[codec(crate)] + | ^^^^^ + +error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied + --> $DIR/incomplete_attr.rs:3:18 + | +3 | #[derive(Encode, MaxEncodedLen)] + | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` + | + ::: $WORKSPACE/src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ------ required by this bound in `MaxEncodedLen` + | + = note: required because of the requirements on the impl of `Encode` for `Example` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/list_list_item.rs b/tests/max_encoded_len_ui/list_list_item.rs new file mode 100644 index 00000000..cf2d2f99 --- /dev/null +++ b/tests/max_encoded_len_ui/list_list_item.rs @@ -0,0 +1,9 @@ +use parity_scale_codec::{Encode, MaxEncodedLen}; + +#[derive(Encode, MaxEncodedLen)] +#[codec(crate = "foo()")] +struct Example; + +fn main() { + let _ = Example::max_encoded_len(); +} diff --git a/tests/max_encoded_len_ui/list_list_item.stderr b/tests/max_encoded_len_ui/list_list_item.stderr new file mode 100644 index 00000000..af751525 --- /dev/null +++ b/tests/max_encoded_len_ui/list_list_item.stderr @@ -0,0 +1,19 @@ +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = "path::to::crate")]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute + --> $DIR/list_list_item.rs:4:9 + | +4 | #[codec(crate = "foo()")] + | ^^^^^ + +error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied + --> $DIR/list_list_item.rs:3:18 + | +3 | #[derive(Encode, MaxEncodedLen)] + | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` + | + ::: $WORKSPACE/src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ------ required by this bound in `MaxEncodedLen` + | + = note: required because of the requirements on the impl of `Encode` for `Example` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/not_encode.rs b/tests/max_encoded_len_ui/not_encode.rs new file mode 100644 index 00000000..15c9d71d --- /dev/null +++ b/tests/max_encoded_len_ui/not_encode.rs @@ -0,0 +1,6 @@ +use parity_scale_codec::{MaxEncodedLen}; + +#[derive(MaxEncodedLen)] +struct NotEncode; + +fn main() {} diff --git a/tests/max_encoded_len_ui/not_encode.stderr b/tests/max_encoded_len_ui/not_encode.stderr new file mode 100644 index 00000000..2968460b --- /dev/null +++ b/tests/max_encoded_len_ui/not_encode.stderr @@ -0,0 +1,13 @@ +error[E0277]: the trait bound `NotEncode: WrapperTypeEncode` is not satisfied + --> $DIR/not_encode.rs:3:10 + | +3 | #[derive(MaxEncodedLen)] + | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `NotEncode` + | + ::: $WORKSPACE/src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ------ required by this bound in `MaxEncodedLen` + | + = note: required because of the requirements on the impl of `Encode` for `NotEncode` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/not_mel.rs b/tests/max_encoded_len_ui/not_mel.rs new file mode 100644 index 00000000..0f4a5f44 --- /dev/null +++ b/tests/max_encoded_len_ui/not_mel.rs @@ -0,0 +1,13 @@ +use parity_scale_codec::{Encode, MaxEncodedLen}; + +#[derive(Encode)] +struct NotMel; + +#[derive(Encode, MaxEncodedLen)] +struct Generic { + t: T, +} + +fn main() { + let _ = Generic::::max_encoded_len(); +} diff --git a/tests/max_encoded_len_ui/not_mel.stderr b/tests/max_encoded_len_ui/not_mel.stderr new file mode 100644 index 00000000..8b9b2684 --- /dev/null +++ b/tests/max_encoded_len_ui/not_mel.stderr @@ -0,0 +1,21 @@ +error[E0599]: the function or associated item `max_encoded_len` exists for struct `Generic`, but its trait bounds were not satisfied + --> $DIR/not_mel.rs:12:29 + | +4 | struct NotMel; + | -------------- doesn't satisfy `NotMel: MaxEncodedLen` +... +7 | struct Generic { + | ----------------- + | | + | function or associated item `max_encoded_len` not found for this + | doesn't satisfy `Generic: MaxEncodedLen` +... +12 | let _ = Generic::::max_encoded_len(); + | ^^^^^^^^^^^^^^^ function or associated item cannot be called on `Generic` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `NotMel: MaxEncodedLen` + which is required by `Generic: MaxEncodedLen` + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `max_encoded_len`, perhaps you need to implement it: + candidate #1: `MaxEncodedLen` diff --git a/tests/max_encoded_len_ui/path_list_item.rs b/tests/max_encoded_len_ui/path_list_item.rs new file mode 100644 index 00000000..5422a2b1 --- /dev/null +++ b/tests/max_encoded_len_ui/path_list_item.rs @@ -0,0 +1,9 @@ +use parity_scale_codec::{Encode, MaxEncodedLen}; + +#[derive(Encode, MaxEncodedLen)] +#[codec(frame_support::max_encoded_len)] +struct Example; + +fn main() { + let _ = Example::max_encoded_len(); +} diff --git a/tests/max_encoded_len_ui/path_list_item.stderr b/tests/max_encoded_len_ui/path_list_item.stderr new file mode 100644 index 00000000..26680f7f --- /dev/null +++ b/tests/max_encoded_len_ui/path_list_item.stderr @@ -0,0 +1,19 @@ +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = "path::to::crate")]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute + --> $DIR/path_list_item.rs:4:9 + | +4 | #[codec(frame_support::max_encoded_len)] + | ^^^^^^^^^^^^^ + +error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied + --> $DIR/path_list_item.rs:3:18 + | +3 | #[derive(Encode, MaxEncodedLen)] + | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` + | + ::: $WORKSPACE/src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ------ required by this bound in `MaxEncodedLen` + | + = note: required because of the requirements on the impl of `Encode` for `Example` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/union.rs b/tests/max_encoded_len_ui/union.rs new file mode 100644 index 00000000..2fb91e39 --- /dev/null +++ b/tests/max_encoded_len_ui/union.rs @@ -0,0 +1,9 @@ +use parity_scale_codec::{Encode, MaxEncodedLen}; + +#[derive(Encode, MaxEncodedLen)] +union Union { + a: u8, + b: u16, +} + +fn main() {} diff --git a/tests/max_encoded_len_ui/union.stderr b/tests/max_encoded_len_ui/union.stderr new file mode 100644 index 00000000..36d0cc01 --- /dev/null +++ b/tests/max_encoded_len_ui/union.stderr @@ -0,0 +1,11 @@ +error: Union types are not supported. + --> $DIR/union.rs:4:1 + | +4 | union Union { + | ^^^^^ + +error: Union types are not supported + --> $DIR/union.rs:4:1 + | +4 | union Union { + | ^^^^^ diff --git a/tests/max_encoded_len_ui/unsupported_variant.rs b/tests/max_encoded_len_ui/unsupported_variant.rs new file mode 100644 index 00000000..7358107f --- /dev/null +++ b/tests/max_encoded_len_ui/unsupported_variant.rs @@ -0,0 +1,11 @@ +use parity_scale_codec::{Encode, MaxEncodedLen}; + +#[derive(Encode)] +struct NotMel; + +#[derive(Encode, MaxEncodedLen)] +enum UnsupportedVariant { + NotMel(NotMel), +} + +fn main() {} diff --git a/tests/max_encoded_len_ui/unsupported_variant.stderr b/tests/max_encoded_len_ui/unsupported_variant.stderr new file mode 100644 index 00000000..836c544c --- /dev/null +++ b/tests/max_encoded_len_ui/unsupported_variant.stderr @@ -0,0 +1,12 @@ +error[E0599]: no function or associated item named `max_encoded_len` found for struct `NotMel` in the current scope + --> $DIR/unsupported_variant.rs:8:9 + | +4 | struct NotMel; + | -------------- function or associated item `max_encoded_len` not found for this +... +8 | NotMel(NotMel), + | ^^^^^^ function or associated item not found in `NotMel` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `max_encoded_len`, perhaps you need to implement it: + candidate #1: `MaxEncodedLen` From 079a65940e967322e805e8b6fc0472a6cf596647 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Wed, 23 Jun 2021 14:10:14 +0200 Subject: [PATCH 055/286] Mention new `#[codec(crate = ...)]` attribute for MaxEncodedLen derive (#275) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Mention new #[codec(crate = ...)] attribute for MaxEncodedLen derive * Update CHANGELOG.md Co-authored-by: Peter Goodspeed-Niklaus * Update CHANGELOG.md Co-authored-by: Bastian Köcher Co-authored-by: Peter Goodspeed-Niklaus Co-authored-by: Bastian Köcher --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36f44459..4b810212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h ### Added - `MaxEncodedLen` trait for items that have a statically known maximum encoded size. ([#268](https://github.com/paritytech/parity-scale-codec/pull/268)) +- `#[codec(crate = "")]` top-level attribute to be used with the new `MaxEncodedLen` +trait, which allows to specify a different path to the crate that contains the `MaxEncodedLen` trait. +Useful when using generating a type through a macro and this type should implement `MaxEncodedLen` and the final crate doesn't have `parity-scale-codec` as dependency. ## [2.1.3] - 2021-06-14 From 459ebe68731906b02ccbc278cde4546bee205d02 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Wed, 23 Jun 2021 14:53:54 +0200 Subject: [PATCH 056/286] Facilitate publishing by removing version in codec dev-dependency (#276) Cargo will automatically strip dev-dependency for us, which removes the need for manually doing so before publishing the crates. See https://github.com/rust-lang/cargo/pull/7333 --- derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 76788679..257376b0 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -16,4 +16,4 @@ proc-macro2 = "1.0.6" proc-macro-crate = "1.0.0" [dev-dependencies] -parity-scale-codec = { path = "..", version = "2.2.0-rc.1" } +parity-scale-codec = { path = ".." } From 2dd6dc3fa849db75c5b4f39aac14a2cf66af7d1a Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Thu, 24 Jun 2021 13:35:57 +0200 Subject: [PATCH 057/286] Improve `#[codec(crate = path)]` attribute: path, not string literal (#277) * Improve `#[codec(crate = path)]` attribute: path, not string literal Accepting a path instead of a string literal makes life easier for the downstream macros which need to actually use that attribute. * actually test the pass test --- CHANGELOG.md | 14 +++++ derive/src/utils.rs | 63 ++++++++++++------- src/lib.rs | 10 +-- tests/max_encoded_len_ui.rs | 1 + .../{path_list_item.rs => crate_str.rs} | 2 +- ...list_list_item.stderr => crate_str.stderr} | 8 +-- .../max_encoded_len_ui/incomplete_attr.stderr | 2 +- ...ist_item.rs => missing_crate_specifier.rs} | 2 +- ....stderr => missing_crate_specifier.stderr} | 10 +-- tests/max_encoded_len_ui/pass/codec_crate.rs | 11 ++++ 10 files changed, 82 insertions(+), 41 deletions(-) rename tests/max_encoded_len_ui/{path_list_item.rs => crate_str.rs} (78%) rename tests/max_encoded_len_ui/{list_list_item.stderr => crate_str.stderr} (73%) rename tests/max_encoded_len_ui/{list_list_item.rs => missing_crate_specifier.rs} (83%) rename tests/max_encoded_len_ui/{path_list_item.stderr => missing_crate_specifier.stderr} (69%) create mode 100644 tests/max_encoded_len_ui/pass/codec_crate.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b810212..96cc87e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,17 @@ and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h ## Unreleased +## [2.2.0-rc.2] - 2021-06-24 + +- Updated syntax of `#[codec(crate = )]` attribute macro: no longer expects the crate path to + be a string literal, but a path literal. This improves usability when used within other macros; + the external macro doesn't need to construct a string, but can simply do + `#[codec(crate = $crate::my_codec_reexport)]`. + ## [2.2.0-rc.1] - 2021-06-22 ### Added + - `MaxEncodedLen` trait for items that have a statically known maximum encoded size. ([#268](https://github.com/paritytech/parity-scale-codec/pull/268)) - `#[codec(crate = "")]` top-level attribute to be used with the new `MaxEncodedLen` trait, which allows to specify a different path to the crate that contains the `MaxEncodedLen` trait. @@ -17,11 +25,13 @@ Useful when using generating a type through a macro and this type should impleme ## [2.1.3] - 2021-06-14 ### Changed + - Lint attributes now pass through to the derived impls of `Encode`, `Decode` and `CompactAs`. PR #272 ## [2.1.0] - 2021-04-06 ### Fix + - Add support for custom where bounds `codec(encode_bound(T: Encode))` and `codec(decode_bound(T: Decode))` when deriving the traits. Pr #262 - Switch to const generics for array implementations. Pr #261 @@ -29,11 +39,13 @@ deriving the traits. Pr #262 ## [2.0.1] - 2021-02-26 ### Fix + - Fix type inference issue in `Decode` derive macro. Pr #254 ## [2.0.0] - 2021-01-26 ### Added + - `Decode::skip` allows to skip some encoded types. Pr #243 - `Decode::encoded_fixed_size` allows to get the fixed encoded size of a type. PR #243 - `Error` now contains a chain of causes. This full error description can also be activated on @@ -41,6 +53,7 @@ deriving the traits. Pr #262 - `Encode::encoded_size` allows to get the encoded size of a type more efficiently. PR #245 ### Changed + - `CompactAs::decode_from` now returns result. This allow for decoding to fail from their compact form. - derive macro use literal index e.g. `#[codec(index = 15)]` instead of `#[codec(index = "15")]` @@ -49,6 +62,7 @@ deriving the traits. Pr #262 - `Output` can now be used as a trait object. ### Removed + - `EncodeAppend::append` is removed in favor of `EncodeAppend::append_or_new`. - `Output::push` is removed in favor of `Encode::encode_to`. - Some bounds on `HasCompact::Type` are removed. diff --git a/derive/src/utils.rs b/derive/src/utils.rs index 2d393d07..e07e6112 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -134,31 +134,46 @@ fn crate_access() -> syn::Result { } } -/// Match `#[codec(crate = ...)]` and return the `...` -fn codec_crate_path_lit(attr: &Attribute) -> Option { +/// This struct matches `crate = ...` where the ellipsis is a `Path`. +struct CratePath { + _crate_token: Token![crate], + _eq_token: Token![=], + path: Path, +} + +impl Parse for CratePath { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + Ok(CratePath { + _crate_token: input.parse()?, + _eq_token: input.parse()?, + path: input.parse()?, + }) + } +} + +impl From for Path { + fn from(CratePath { path, ..}: CratePath) -> Self { + path + } +} + +/// Match `#[codec(crate = ...)]` and return the `...` if it is a `Path`. +fn codec_crate_path_inner(attr: &Attribute) -> Option { // match `#[codec ...]` - if !attr.path.is_ident("codec") { - return None; - }; - // match `#[codec(crate = ...)]` and return the `...` - match attr.parse_meta() { - Ok(Meta::NameValue(MetaNameValue { path, lit, .. })) if path.is_ident("crate") => { - Some(lit) - } - _ => None, - } + attr.path.is_ident("codec").then(move || { + // match `#[codec(crate = ...)]` and return the `...` + attr.parse_args::().map(Into::into).ok() + }).flatten() } -/// Match `#[codec(crate = "...")]` and return the contents as a `Path` +/// Match `#[codec(crate = ...)]` and return the ellipsis as a `Path`. +/// +/// If not found, returns the default crate access pattern. +/// +/// If multiple items match the pattern, all but the first are ignored. pub fn codec_crate_path(attrs: &[Attribute]) -> syn::Result { - match attrs.iter().find_map(codec_crate_path_lit) { - Some(Lit::Str(lit_str)) => lit_str.parse::(), - Some(lit) => { - Err(Error::new( - lit.span(), - "Expected format: #[codec(crate = \"path::to::codec\")]", - )) - } + match attrs.iter().find_map(codec_crate_path_inner) { + Some(path) => Ok(path), None => crate_access().map(|ident| ident.into()), } } @@ -227,7 +242,7 @@ pub fn filter_skip_unnamed<'a>(fields: &'a syn::FieldsUnnamed) -> impl Iterator< /// The top level can have the following attributes: /// /// * `#[codec(dumb_trait_bound)]` -/// * `#[codec(crate = "path::to::crate")] +/// * `#[codec(crate = path::to::crate)] /// /// Fields can have the following attributes: /// @@ -346,12 +361,12 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { // Only `#[codec(dumb_trait_bound)]` is accepted as top attribute fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { let top_error = "Invalid attribute: only `#[codec(dumb_trait_bound)]`, \ - `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = \"path::to::crate\")]`, or \ + `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = path::to::crate)]`, or \ `#[codec(decode_bound(T: Decode))]` are accepted as top attribute"; if attr.path.is_ident("codec") && attr.parse_args::>().is_err() && attr.parse_args::>().is_err() - && codec_crate_path_lit(attr).is_none() + && codec_crate_path_inner(attr).is_none() { match attr.parse_meta()? { Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { diff --git a/src/lib.rs b/src/lib.rs index 541a6487..11a2d93e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,7 +38,7 @@ //! The `Encode` trait is used for encoding of data into the SCALE format. The `Encode` trait //! contains the following functions: -//! +//! //! * `size_hint(&self) -> usize`: Gets the capacity (in bytes) required for the encoded data. //! This is to avoid double-allocation of memory needed for the encoding. //! It can be an estimate and does not need to be an exact number. @@ -331,14 +331,14 @@ pub use max_encoded_len::MaxEncodedLen; /// # Within other macros /// /// Sometimes the `MaxEncodedLen` trait and macro are used within another macro, and it can't be -/// guaranteed that the `max_encoded_len` module is available at the call site. In that case, the -/// macro should reexport the `max_encoded_len` module and specify the path to the reexport: +/// guaranteed that the `parity_scale_codec` module is available at the call site. In that case, the +/// macro should reexport the `parity_scale_codec` module and specify the path to the reexport: /// /// ```ignore -/// pub use parity_scale_codec::max_encoded_len; +/// pub use parity_scale_codec as codec; /// /// #[derive(Encode, MaxEncodedLen)] -/// #[codec(crate = "$crate::max_encoded_len")] +/// #[codec(crate = $crate::codec)] /// struct Example; /// ``` #[cfg(feature = "derive")] diff --git a/tests/max_encoded_len_ui.rs b/tests/max_encoded_len_ui.rs index cb81d884..2bf41457 100644 --- a/tests/max_encoded_len_ui.rs +++ b/tests/max_encoded_len_ui.rs @@ -21,4 +21,5 @@ fn derive_no_bound_ui() { let t = trybuild::TestCases::new(); t.compile_fail("tests/max_encoded_len_ui/*.rs"); + t.pass("tests/max_encoded_len_ui/pass/*.rs"); } diff --git a/tests/max_encoded_len_ui/path_list_item.rs b/tests/max_encoded_len_ui/crate_str.rs similarity index 78% rename from tests/max_encoded_len_ui/path_list_item.rs rename to tests/max_encoded_len_ui/crate_str.rs index 5422a2b1..c7d6bb2f 100644 --- a/tests/max_encoded_len_ui/path_list_item.rs +++ b/tests/max_encoded_len_ui/crate_str.rs @@ -1,7 +1,7 @@ use parity_scale_codec::{Encode, MaxEncodedLen}; #[derive(Encode, MaxEncodedLen)] -#[codec(frame_support::max_encoded_len)] +#[codec(crate = "parity_scale_codec")] struct Example; fn main() { diff --git a/tests/max_encoded_len_ui/list_list_item.stderr b/tests/max_encoded_len_ui/crate_str.stderr similarity index 73% rename from tests/max_encoded_len_ui/list_list_item.stderr rename to tests/max_encoded_len_ui/crate_str.stderr index af751525..dfb8e7fe 100644 --- a/tests/max_encoded_len_ui/list_list_item.stderr +++ b/tests/max_encoded_len_ui/crate_str.stderr @@ -1,11 +1,11 @@ -error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = "path::to::crate")]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute - --> $DIR/list_list_item.rs:4:9 +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = path::to::crate)]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute + --> $DIR/crate_str.rs:4:9 | -4 | #[codec(crate = "foo()")] +4 | #[codec(crate = "parity_scale_codec")] | ^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> $DIR/list_list_item.rs:3:18 + --> $DIR/crate_str.rs:3:18 | 3 | #[derive(Encode, MaxEncodedLen)] | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr index 53e5b726..d21ca269 100644 --- a/tests/max_encoded_len_ui/incomplete_attr.stderr +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -1,4 +1,4 @@ -error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = "path::to::crate")]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = path::to::crate)]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute --> $DIR/incomplete_attr.rs:4:9 | 4 | #[codec(crate)] diff --git a/tests/max_encoded_len_ui/list_list_item.rs b/tests/max_encoded_len_ui/missing_crate_specifier.rs similarity index 83% rename from tests/max_encoded_len_ui/list_list_item.rs rename to tests/max_encoded_len_ui/missing_crate_specifier.rs index cf2d2f99..d3fbe23e 100644 --- a/tests/max_encoded_len_ui/list_list_item.rs +++ b/tests/max_encoded_len_ui/missing_crate_specifier.rs @@ -1,7 +1,7 @@ use parity_scale_codec::{Encode, MaxEncodedLen}; #[derive(Encode, MaxEncodedLen)] -#[codec(crate = "foo()")] +#[codec(parity_scale_codec)] struct Example; fn main() { diff --git a/tests/max_encoded_len_ui/path_list_item.stderr b/tests/max_encoded_len_ui/missing_crate_specifier.stderr similarity index 69% rename from tests/max_encoded_len_ui/path_list_item.stderr rename to tests/max_encoded_len_ui/missing_crate_specifier.stderr index 26680f7f..a05b65c0 100644 --- a/tests/max_encoded_len_ui/path_list_item.stderr +++ b/tests/max_encoded_len_ui/missing_crate_specifier.stderr @@ -1,11 +1,11 @@ -error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = "path::to::crate")]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute - --> $DIR/path_list_item.rs:4:9 +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = path::to::crate)]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute + --> $DIR/missing_crate_specifier.rs:4:9 | -4 | #[codec(frame_support::max_encoded_len)] - | ^^^^^^^^^^^^^ +4 | #[codec(parity_scale_codec)] + | ^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> $DIR/path_list_item.rs:3:18 + --> $DIR/missing_crate_specifier.rs:3:18 | 3 | #[derive(Encode, MaxEncodedLen)] | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` diff --git a/tests/max_encoded_len_ui/pass/codec_crate.rs b/tests/max_encoded_len_ui/pass/codec_crate.rs new file mode 100644 index 00000000..64d390e4 --- /dev/null +++ b/tests/max_encoded_len_ui/pass/codec_crate.rs @@ -0,0 +1,11 @@ +//! This test case demonstrates correct use of the `#[codec(crate = path)]` attribute. + +use parity_scale_codec::{self as codec, Encode, MaxEncodedLen}; + +#[derive(Encode, MaxEncodedLen)] +#[codec(crate = codec)] +struct Example; + +fn main() { + let _ = Example::max_encoded_len(); +} From ddd7960d2b8587202bb791724309bb12435436d2 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Thu, 24 Jun 2021 14:13:23 +0200 Subject: [PATCH 058/286] Bump version to 2.2.0-rc.2 (#278) --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56fe8289..c011b868 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -452,7 +452,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "2.2.0-rc.1" +version = "2.2.0-rc.2" dependencies = [ "arbitrary", "arrayvec", @@ -470,7 +470,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "2.2.0-rc.1" +version = "2.2.0-rc.2" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index daf1e2f1..a2317040 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.2.0-rc.1" +version = "2.2.0-rc.2" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,7 +11,7 @@ edition = "2018" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "2.2.0-rc.1", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "2.2.0-rc.2", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 257376b0..70aee778 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.2.0-rc.1" +version = "2.2.0-rc.2" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" From 4510676a1459c6a32963f8bda4839a1846560873 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 25 Jun 2021 15:36:03 -0700 Subject: [PATCH 059/286] Support custom trait bounds on MaxEncodedLen derive macro (#279) * Support custom trait bounds on MaxEncodedLen derive macro * Bump version to 2.2.0-rc.3 * Reorder error messaging --- CHANGELOG.md | 3 ++ Cargo.lock | 4 +- Cargo.toml | 4 +- derive/Cargo.toml | 2 +- derive/src/max_encoded_len.rs | 16 ++++++-- derive/src/utils.rs | 23 ++++++++++-- tests/max_encoded_len.rs | 37 +++++++++++++++++++ tests/max_encoded_len_ui/crate_str.stderr | 2 +- .../max_encoded_len_ui/incomplete_attr.stderr | 2 +- .../missing_crate_specifier.stderr | 2 +- tests/max_encoded_len_ui/union.stderr | 6 --- 11 files changed, 80 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96cc87e3..0ebdc3d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h ## Unreleased +## [2.2.0-rc.3] - 2021-06-25 +- Add support for custom where bounds `codec(mel_bound(T: MaxEncodedLen))` when deriving the traits. PR #279 + ## [2.2.0-rc.2] - 2021-06-24 - Updated syntax of `#[codec(crate = )]` attribute macro: no longer expects the crate path to diff --git a/Cargo.lock b/Cargo.lock index c011b868..7a058e67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -452,7 +452,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "2.2.0-rc.2" +version = "2.2.0-rc.3" dependencies = [ "arbitrary", "arrayvec", @@ -470,7 +470,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "2.2.0-rc.2" +version = "2.2.0-rc.3" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index a2317040..3ff689d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.2.0-rc.2" +version = "2.2.0-rc.3" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,7 +11,7 @@ edition = "2018" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "2.2.0-rc.2", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "2.2.0-rc.3", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 70aee778..705b2b28 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.2.0-rc.2" +version = "2.2.0-rc.3" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index f8ad7254..0402fa23 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::utils::codec_crate_path; +use crate::utils::{self, codec_crate_path, custom_mel_trait_bound}; use quote::{quote, quote_spanned}; use syn::{ Data, DeriveInput, Fields, GenericParam, Generics, TraitBound, Type, TypeParamBound, @@ -33,7 +33,11 @@ pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::Tok }; let name = &input.ident; - let generics = add_trait_bounds(input.generics, mel_trait.clone()); + let generics = if let Some(custom_bound) = custom_mel_trait_bound(&input.attrs) { + add_custom_trait_bounds(input.generics, custom_bound) + } else { + add_trait_bounds(input.generics, mel_trait.clone()) + }; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let data_expr = data_length_expr(&input.data); @@ -65,6 +69,12 @@ fn add_trait_bounds(mut generics: Generics, mel_trait: TraitBound) -> Generics { generics } +// Add custom trait bounds to the type parameters as specified by the user. +fn add_custom_trait_bounds(mut generics: Generics, custom_bound: utils::TraitBounds) -> Generics { + generics.make_where_clause().predicates.extend(custom_bound); + generics +} + /// generate an expression to sum up the max encoded length from several fields fn fields_length_expr(fields: &Fields) -> proc_macro2::TokenStream { let type_iter: Box> = match fields { @@ -124,7 +134,7 @@ fn data_length_expr(data: &Data) -> proc_macro2::TokenStream { Data::Union(ref data) => { // https://github.com/paritytech/parity-scale-codec/ // blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/derive/src/encode.rs#L290-L293 - syn::Error::new(data.union_token.span(), "Union types are not supported") + syn::Error::new(data.union_token.span(), "Union types are not supported.") .to_compile_error() } } diff --git a/derive/src/utils.rs b/derive/src/utils.rs index e07e6112..f00dd2f3 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -201,8 +201,9 @@ impl Parse for CustomTraitBound { syn::custom_keyword!(encode_bound); syn::custom_keyword!(decode_bound); +syn::custom_keyword!(mel_bound); -/// Look for a `#[codec(decode_bound(T: Decode))]`in the given attributes. +/// Look for a `#[codec(decode_bound(T: Decode))]` in the given attributes. /// /// If found, it should be used as trait bounds when deriving the `Decode` trait. pub fn custom_decode_trait_bound(attrs: &[Attribute]) -> Option { @@ -211,7 +212,7 @@ pub fn custom_decode_trait_bound(attrs: &[Attribute]) -> Option { }) } -/// Look for a `#[codec(encode_bound(T: Encode))]`in the given attributes. +/// Look for a `#[codec(encode_bound(T: Encode))]` in the given attributes. /// /// If found, it should be used as trait bounds when deriving the `Encode` trait. pub fn custom_encode_trait_bound(attrs: &[Attribute]) -> Option { @@ -220,6 +221,15 @@ pub fn custom_encode_trait_bound(attrs: &[Attribute]) -> Option { }) } +/// Look for a `#[codec(mel_bound(T: MaxEncodedLen))]` in the given attributes. +/// +/// If found, it should be used as the trait bounds when deriving the `MaxEncodedLen` trait. +pub fn custom_mel_trait_bound(attrs: &[Attribute]) -> Option { + find_meta_item(attrs.iter(), |meta: CustomTraitBound| { + Some(meta.bounds) + }) +} + /// Given a set of named fields, return an iterator of `Field` where all fields /// marked `#[codec(skip)]` are filtered out. pub fn filter_skip_named<'a>(fields: &'a syn::FieldsNamed) -> impl Iterator + 'a { @@ -242,6 +252,9 @@ pub fn filter_skip_unnamed<'a>(fields: &'a syn::FieldsUnnamed) -> impl Iterator< /// The top level can have the following attributes: /// /// * `#[codec(dumb_trait_bound)]` +/// * `#[codec(encode_bound(T: Encode))]` +/// * `#[codec(decode_bound(T: Decode))]` +/// * `#[codec(mel_bound(T: MaxEncodedLen))]` /// * `#[codec(crate = path::to::crate)] /// /// Fields can have the following attributes: @@ -361,11 +374,13 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { // Only `#[codec(dumb_trait_bound)]` is accepted as top attribute fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { let top_error = "Invalid attribute: only `#[codec(dumb_trait_bound)]`, \ - `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = path::to::crate)]`, or \ - `#[codec(decode_bound(T: Decode))]` are accepted as top attribute"; + `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, \ + `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` \ + are accepted as top attribute"; if attr.path.is_ident("codec") && attr.parse_args::>().is_err() && attr.parse_args::>().is_err() + && attr.parse_args::>().is_err() && codec_crate_path_inner(attr).is_none() { match attr.parse_meta()? { diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs index df1c05f6..b657695a 100644 --- a/tests/max_encoded_len.rs +++ b/tests/max_encoded_len.rs @@ -95,6 +95,43 @@ fn tuple_generic_max_length() { assert_eq!(TupleGeneric::::max_encoded_len(), u32::max_encoded_len() * 2); } +#[derive(Encode)] +struct ConstU32; + +trait Get: Encode { + fn get() -> T; +} + +impl Get for ConstU32 { + fn get() -> u32 { + N + } +} + +#[derive(Encode)] +struct SomeVec { + element: T, + size: N, +} + +impl> MaxEncodedLen for SomeVec { + fn max_encoded_len() -> usize { + T::max_encoded_len() * N::get() as usize + } +} + +#[derive(Encode, MaxEncodedLen)] +#[codec(mel_bound(N: Get))] +struct SizeGeneric { + vec: SomeVec, +} + +#[test] +fn some_vec_max_length() { + assert_eq!(SomeVec::>::max_encoded_len(), u64::max_encoded_len() * 3); + assert_eq!(SizeGeneric::>::max_encoded_len(), u64::max_encoded_len() * 5); +} + #[derive(Encode, MaxEncodedLen)] #[allow(unused)] enum UnitEnum { diff --git a/tests/max_encoded_len_ui/crate_str.stderr b/tests/max_encoded_len_ui/crate_str.stderr index dfb8e7fe..1f8dc30f 100644 --- a/tests/max_encoded_len_ui/crate_str.stderr +++ b/tests/max_encoded_len_ui/crate_str.stderr @@ -1,4 +1,4 @@ -error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = path::to::crate)]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute --> $DIR/crate_str.rs:4:9 | 4 | #[codec(crate = "parity_scale_codec")] diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr index d21ca269..43f7e54f 100644 --- a/tests/max_encoded_len_ui/incomplete_attr.stderr +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -1,4 +1,4 @@ -error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = path::to::crate)]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute --> $DIR/incomplete_attr.rs:4:9 | 4 | #[codec(crate)] diff --git a/tests/max_encoded_len_ui/missing_crate_specifier.stderr b/tests/max_encoded_len_ui/missing_crate_specifier.stderr index a05b65c0..3d97804b 100644 --- a/tests/max_encoded_len_ui/missing_crate_specifier.stderr +++ b/tests/max_encoded_len_ui/missing_crate_specifier.stderr @@ -1,4 +1,4 @@ -error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(crate = path::to::crate)]`, or `#[codec(decode_bound(T: Decode))]` are accepted as top attribute +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute --> $DIR/missing_crate_specifier.rs:4:9 | 4 | #[codec(parity_scale_codec)] diff --git a/tests/max_encoded_len_ui/union.stderr b/tests/max_encoded_len_ui/union.stderr index 36d0cc01..af3dc931 100644 --- a/tests/max_encoded_len_ui/union.stderr +++ b/tests/max_encoded_len_ui/union.stderr @@ -3,9 +3,3 @@ error: Union types are not supported. | 4 | union Union { | ^^^^^ - -error: Union types are not supported - --> $DIR/union.rs:4:1 - | -4 | union Union { - | ^^^^^ From d889b6256f047cdc8f5c67175ebd2e59adaf968f Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Fri, 2 Jul 2021 17:47:03 +0200 Subject: [PATCH 060/286] Bump version to 2.2.0 and hide `MaxEncodedLen` behind an additional crate feature (#282) * Hide `trait MaxEncodedLen` behind the new `max-encoded-len` feature * Bump versions to 2.2.0 * Shuffle some cfg feature directives * ci: Test also using the new feature flag --- .gitlab-ci.yml | 2 +- Cargo.lock | 4 ++-- Cargo.toml | 11 ++++++++--- derive/Cargo.toml | 8 +++++++- derive/src/lib.rs | 1 + derive/src/max_encoded_len.rs | 2 ++ src/lib.rs | 4 +++- 7 files changed, 24 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 84d2a3ef..86540b76 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -81,7 +81,7 @@ test-rust-stable: stage: test <<: *docker-env script: - - time cargo +stable test --verbose --all --features bit-vec,generic-array,derive + - time cargo +stable test --verbose --all --features bit-vec,generic-array,derive,max-encoded-len - sccache -s test-rust-stable-no_derive: diff --git a/Cargo.lock b/Cargo.lock index 7a058e67..9c2e2147 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -452,7 +452,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "2.2.0-rc.3" +version = "2.2.0" dependencies = [ "arbitrary", "arrayvec", @@ -470,7 +470,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "2.2.0-rc.3" +version = "2.2.0" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index 3ff689d7..8074860e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.2.0-rc.3" +version = "2.2.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,7 +11,7 @@ edition = "2018" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "2.2.0-rc.3", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "2.2.0", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } @@ -21,7 +21,7 @@ impl-trait-for-tuples = "0.2.1" [dev-dependencies] criterion = "0.3.0" serde_derive = { version = "1.0" } -parity-scale-codec-derive = { path = "derive", version = "2.2.0-rc.1", default-features = false } +parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" trybuild = "1.0.42" @@ -39,6 +39,11 @@ std = ["serde", "bitvec/std", "byte-slice-cast/std", "chain-error"] bit-vec = ["bitvec"] fuzz = ["std", "arbitrary"] +# Enables the new `MaxEncodedLen` trait. +# NOTE: This is still considered experimental and is exempt from the usual +# SemVer guarantees. We do not guarantee no code breakage when using this. +max-encoded-len = ["parity-scale-codec-derive/max-encoded-len"] + # Make error fully descriptive with chaining error message. # Should not be used in a constrained environment. chain-error = [] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 705b2b28..f8dc1348 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.2.0-rc.3" +version = "2.2.0" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" @@ -17,3 +17,9 @@ proc-macro-crate = "1.0.0" [dev-dependencies] parity-scale-codec = { path = ".." } + +[features] +# Enables the new `MaxEncodedLen` trait. +# NOTE: This is still considered experimental and is exempt from the usual +# SemVer guarantees. We do not guarantee no code breakage when using this. +max-encoded-len = [] diff --git a/derive/src/lib.rs b/derive/src/lib.rs index c95ce27d..624a912a 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -336,6 +336,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr } /// Derive `MaxEncodedLen`. +#[cfg(feature = "max-encoded-len")] #[proc_macro_derive(MaxEncodedLen, attributes(max_encoded_len_mod))] pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream { max_encoded_len::derive_max_encoded_len(input) diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index 0402fa23..7a89fe23 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![cfg(feature = "max-encoded-len")] + use crate::utils::{self, codec_crate_path, custom_mel_trait_bound}; use quote::{quote, quote_spanned}; use syn::{ diff --git a/src/lib.rs b/src/lib.rs index 11a2d93e..0e70ae19 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -281,6 +281,7 @@ mod depth_limit; mod encode_append; mod encode_like; mod error; +#[cfg(feature = "max-encoded-len")] mod max_encoded_len; pub use self::error::Error; @@ -297,6 +298,7 @@ pub use self::decode_all::DecodeAll; pub use self::depth_limit::DecodeLimit; pub use self::encode_append::EncodeAppend; pub use self::encode_like::{EncodeLike, Ref}; +#[cfg(feature = "max-encoded-len")] pub use max_encoded_len::MaxEncodedLen; /// Derive macro for [`MaxEncodedLen`][max_encoded_len::MaxEncodedLen]. /// @@ -341,5 +343,5 @@ pub use max_encoded_len::MaxEncodedLen; /// #[codec(crate = $crate::codec)] /// struct Example; /// ``` -#[cfg(feature = "derive")] +#[cfg(all(feature = "derive", feature = "max-encoded-len"))] pub use parity_scale_codec_derive::MaxEncodedLen; From 6213b06bc1814b6a3c908fdc2acda2f7db098f9c Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Sep 2021 16:09:31 -0700 Subject: [PATCH 061/286] Fix CI failures on master (#288) * Update UI test error expectations * Bump bitvec version to 0.22.3 * Run cargo update * Fix compilation errors with bit_vec.rs * Silence compilation warnings * Update CHANGELOG.md * Fix CHANGELOG.md * Revert "Bump bitvec version to 0.22.3" This reverts commit 0e3ea94612164c8b4e60d74f89277d07d64d9215. * Revert "Fix compilation errors with bit_vec.rs" This reverts commit 33a64124b6f55107de93c63945ac5daf2053d88a. * prevent false positive miri error * Update CHANGELOG.md Co-authored-by: thiolliere --- CHANGELOG.md | 17 +- Cargo.lock | 307 +++++++----------- derive/src/utils.rs | 14 +- src/bit_vec.rs | 2 +- tests/max_encoded_len_ui/crate_str.stderr | 2 +- .../max_encoded_len_ui/incomplete_attr.stderr | 2 +- .../missing_crate_specifier.stderr | 2 +- tests/max_encoded_len_ui/not_encode.stderr | 2 +- 8 files changed, 142 insertions(+), 206 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ebdc3d4..8d42bca8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,24 +4,13 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased - -## [2.2.0-rc.3] - 2021-06-25 -- Add support for custom where bounds `codec(mel_bound(T: MaxEncodedLen))` when deriving the traits. PR #279 - -## [2.2.0-rc.2] - 2021-06-24 - -- Updated syntax of `#[codec(crate = )]` attribute macro: no longer expects the crate path to - be a string literal, but a path literal. This improves usability when used within other macros; - the external macro doesn't need to construct a string, but can simply do - `#[codec(crate = $crate::my_codec_reexport)]`. - -## [2.2.0-rc.1] - 2021-06-22 +## [2.2.0] - 2021-07-02 ### Added +- Add support for custom where bounds `codec(mel_bound(T: MaxEncodedLen))` when deriving the traits. PR #279 - `MaxEncodedLen` trait for items that have a statically known maximum encoded size. ([#268](https://github.com/paritytech/parity-scale-codec/pull/268)) -- `#[codec(crate = "")]` top-level attribute to be used with the new `MaxEncodedLen` +- `#[codec(crate = )]` top-level attribute to be used with the new `MaxEncodedLen` trait, which allows to specify a different path to the crate that contains the `MaxEncodedLen` trait. Useful when using generating a type through a macro and this type should implement `MaxEncodedLen` and the final crate doesn't have `parity-scale-codec` as dependency. diff --git a/Cargo.lock b/Cargo.lock index 9c2e2147..0ef6e0fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a2f58b0bb10c380af2b26e57212856b8c9a59e0925b4c20f4a174a49734eaf7" +checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" [[package]] name = "atty" @@ -45,9 +45,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitvec" @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "bstr" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" +checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" dependencies = [ "lazy_static", "memchr", @@ -75,9 +75,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.5.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f07aa6688c702439a1be0307b6a94dffe1168569e45b9500c1372bc580740d59" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" [[package]] name = "byte-slice-cast" @@ -85,27 +85,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65c1bf4a04a88c54f589125563643d773f3254b5c38571395e2b591c693bbc81" -[[package]] -name = "byteorder" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" - [[package]] name = "cast" -version = "0.2.3" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" +checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" dependencies = [ "rustc_version", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -133,24 +121,18 @@ dependencies = [ "parity-scale-codec", ] -[[package]] -name = "const_fn" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" - [[package]] name = "criterion" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" +checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" dependencies = [ "atty", "cast", "clap", "criterion-plot", "csv", - "itertools 0.10.0", + "itertools", "lazy_static", "num-traits", "oorandom", @@ -167,43 +149,42 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" +checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" dependencies = [ "cast", - "itertools 0.9.0", + "itertools", ] [[package]] name = "crossbeam-channel" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ - "cfg-if 1.0.0", - "const_fn", + "cfg-if", "crossbeam-utils", "lazy_static", "memoffset", @@ -212,20 +193,19 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.1" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "autocfg", - "cfg-if 1.0.0", + "cfg-if", "lazy_static", ] [[package]] name = "csv" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d58633299b24b515ac72a3f869f8b91306a3cec616a602843a383acd6f9e97" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" dependencies = [ "bstr", "csv-core", @@ -262,9 +242,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ "log", "regex", @@ -292,7 +272,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] @@ -311,9 +291,9 @@ checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -342,33 +322,24 @@ dependencies = [ [[package]] name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" dependencies = [ "either", ] [[package]] name = "itoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "js-sys" -version = "0.3.47" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65" +checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" dependencies = [ "wasm-bindgen", ] @@ -381,24 +352,24 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.74" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10" +checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" [[package]] name = "log" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", ] [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memmap" @@ -412,9 +383,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ "autocfg", ] @@ -438,12 +409,6 @@ dependencies = [ "libc", ] -[[package]] -name = "once_cell" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" - [[package]] name = "oorandom" version = "11.1.3" @@ -481,9 +446,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" +checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" dependencies = [ "num-traits", "plotters-backend", @@ -494,15 +459,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" +checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" [[package]] name = "plotters-svg" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" +checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" dependencies = [ "plotters-backend", ] @@ -519,9 +484,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" dependencies = [ "unicode-xid", ] @@ -539,42 +504,42 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] [[package]] name = "radium" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e006811e1fdd12672b0820a7f44c18dde429f367d50cec003d22aa9b3c8ddc" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" [[package]] name = "rand" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "rand_core", ] [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom", ] [[package]] name = "rayon" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" dependencies = [ "autocfg", "crossbeam-deque", @@ -584,9 +549,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -597,36 +562,32 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] name = "regex-automata" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" -dependencies = [ - "byteorder", -] +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.22" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "rustc_version" -version = "0.2.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ "semver", ] @@ -654,33 +615,24 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" -version = "0.9.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.115" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" +checksum = "1056a0db1978e9dbf0f6e4fca677f6f9143dc1c19de346f22cac23e422196834" dependencies = [ "serde_derive", ] [[package]] name = "serde_cbor" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ "half", "serde", @@ -688,9 +640,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.115" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" +checksum = "13af2fbb8b60a8950d6c72a56d2095c28870367cc8e10c55e9745bac4995a2c4" dependencies = [ "proc-macro2", "quote", @@ -699,9 +651,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.61" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" dependencies = [ "itoa", "ryu", @@ -710,9 +662,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.72" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" dependencies = [ "proc-macro2", "quote", @@ -721,9 +673,9 @@ dependencies = [ [[package]] name = "tap" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "termcolor" @@ -745,38 +697,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "thread_local" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8208a331e1cb318dd5bd76951d2b8fc48ca38a69f5f4e4af1b6a9f8c6236915" -dependencies = [ - "once_cell", -] - [[package]] name = "tinytemplate" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ada8616fad06a2d0c455adc530de4ef57605a8120cc65da9653e0e9623ca74" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ "serde", "serde_json", @@ -784,18 +727,18 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" dependencies = [ "serde", ] [[package]] name = "trybuild" -version = "1.0.42" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1768998d9a3b179411618e377dbb134c58a88cda284b0aa71c42c40660127d46" +checksum = "5bdaf2a1d317f3d58b44b31c7f6436b9b9acafe7bddfeace50897c2b804d7792" dependencies = [ "glob", "lazy_static", @@ -807,9 +750,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" [[package]] name = "unicode-width" @@ -819,21 +762,21 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "version_check" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "walkdir" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", "winapi", @@ -848,19 +791,19 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.70" +version = "0.2.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be" +checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.70" +version = "0.2.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7" +checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" dependencies = [ "bumpalo", "lazy_static", @@ -873,9 +816,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.70" +version = "0.2.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c" +checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -883,9 +826,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.70" +version = "0.2.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385" +checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" dependencies = [ "proc-macro2", "quote", @@ -896,15 +839,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.70" +version = "0.2.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64" +checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" [[package]] name = "web-sys" -version = "0.3.47" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3" +checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/derive/src/utils.rs b/derive/src/utils.rs index f00dd2f3..42c1e130 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -19,11 +19,10 @@ use std::str::FromStr; -use proc_macro_crate::{crate_name, FoundCrate}; -use proc_macro2::{Span, Ident, TokenStream}; +use proc_macro2::TokenStream; use quote::quote; use syn::{ - Attribute, Data, DeriveInput, Error, Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, + Attribute, Data, DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, MetaNameValue, NestedMeta, parse::Parse, Path, punctuated::Punctuated, spanned::Spanned, token, Variant, }; @@ -122,7 +121,10 @@ pub fn has_dumb_trait_bound(attrs: &[Attribute]) -> bool { } /// Generate the crate access for the crate using 2018 syntax. -fn crate_access() -> syn::Result { +#[cfg(feature = "max-encoded-len")] +fn crate_access() -> syn::Result { + use proc_macro_crate::{crate_name, FoundCrate}; + use proc_macro2::{Span, Ident}; const DEF_CRATE: &str = "parity-scale-codec"; match crate_name(DEF_CRATE) { Ok(FoundCrate::Itself) => { @@ -130,7 +132,7 @@ fn crate_access() -> syn::Result { Ok(syn::Ident::new(&name, Span::call_site())) } Ok(FoundCrate::Name(name)) => Ok(Ident::new(&name, Span::call_site())), - Err(e) => Err(Error::new(Span::call_site(), e)), + Err(e) => Err(syn::Error::new(Span::call_site(), e)), } } @@ -171,6 +173,7 @@ fn codec_crate_path_inner(attr: &Attribute) -> Option { /// If not found, returns the default crate access pattern. /// /// If multiple items match the pattern, all but the first are ignored. +#[cfg(feature = "max-encoded-len")] pub fn codec_crate_path(attrs: &[Attribute]) -> syn::Result { match attrs.iter().find_map(codec_crate_path_inner) { Some(path) => Ok(path), @@ -224,6 +227,7 @@ pub fn custom_encode_trait_bound(attrs: &[Attribute]) -> Option { /// Look for a `#[codec(mel_bound(T: MaxEncodedLen))]` in the given attributes. /// /// If found, it should be used as the trait bounds when deriving the `MaxEncodedLen` trait. +#[cfg(feature = "max-encoded-len")] pub fn custom_mel_trait_bound(attrs: &[Attribute]) -> Option { find_meta_item(attrs.iter(), |meta: CustomTraitBound| { Some(meta.bounds) diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 053a6031..667fb830 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -196,7 +196,7 @@ mod tests { #[test] fn bitvec_u64() { for v in &test_data!(u64) { - let encoded = dbg!(v.encode()); + let encoded = v.encode(); assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); } } diff --git a/tests/max_encoded_len_ui/crate_str.stderr b/tests/max_encoded_len_ui/crate_str.stderr index 1f8dc30f..07048141 100644 --- a/tests/max_encoded_len_ui/crate_str.stderr +++ b/tests/max_encoded_len_ui/crate_str.stderr @@ -16,4 +16,4 @@ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied | ------ required by this bound in `MaxEncodedLen` | = note: required because of the requirements on the impl of `Encode` for `Example` - = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr index 43f7e54f..560fdfe1 100644 --- a/tests/max_encoded_len_ui/incomplete_attr.stderr +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -16,4 +16,4 @@ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied | ------ required by this bound in `MaxEncodedLen` | = note: required because of the requirements on the impl of `Encode` for `Example` - = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/missing_crate_specifier.stderr b/tests/max_encoded_len_ui/missing_crate_specifier.stderr index 3d97804b..22ae84bd 100644 --- a/tests/max_encoded_len_ui/missing_crate_specifier.stderr +++ b/tests/max_encoded_len_ui/missing_crate_specifier.stderr @@ -16,4 +16,4 @@ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied | ------ required by this bound in `MaxEncodedLen` | = note: required because of the requirements on the impl of `Encode` for `Example` - = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/not_encode.stderr b/tests/max_encoded_len_ui/not_encode.stderr index 2968460b..29a82d7f 100644 --- a/tests/max_encoded_len_ui/not_encode.stderr +++ b/tests/max_encoded_len_ui/not_encode.stderr @@ -10,4 +10,4 @@ error[E0277]: the trait bound `NotEncode: WrapperTypeEncode` is not satisfied | ------ required by this bound in `MaxEncodedLen` | = note: required because of the requirements on the impl of `Encode` for `NotEncode` - = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) From 205bb1aecdde51464e72a6b8a50ff7c1ed647aa1 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 10 Sep 2021 17:26:59 -0700 Subject: [PATCH 062/286] Add associated method to DecodeLimit for advancing input index (#286) * Add associated method to DecodeLimit for advancing input index * Run cargo update * remove flacky test false positive * Disable another flaky test * Disable yet another flaky test * Bump version to 2.3.0 Co-authored-by: thiolliere --- CHANGELOG.md | 5 +++ Cargo.lock | 80 +++++++++++++++++++++++----------------------- Cargo.toml | 2 +- derive/Cargo.toml | 2 +- src/bit_vec.rs | 14 ++++++++ src/depth_limit.rs | 25 +++++++++++++++ 6 files changed, 86 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d42bca8..855027c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.3.0] - 2021-09-11 + +### Added +- `decode_and_advance_with_depth_limit` to the `DecodeLimit` trait. This allows advancing the cursor while decoding the input. PR #286 + ## [2.2.0] - 2021-07-02 ### Added diff --git a/Cargo.lock b/Cargo.lock index 0ef6e0fd..b2da490e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691" +checksum = "577b08a4acd7b99869f863c50011b01eb73424ccc798ecd996f2e24817adfca7" dependencies = [ "derive_arbitrary", ] @@ -51,9 +51,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitvec" -version = "0.20.1" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5011ffc90248764d7005b0e10c7294f5aa1bd87d9dd7248f4ad475b347c294d" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" dependencies = [ "funty", "radium", @@ -225,9 +225,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1281ee141df08871db9fe261ab5312179eac32d1e314134ceaa8dd7c042f5a" +checksum = "b24629208e87a2d8b396ff43b15c4afb0a69cea3fbbaa9ed9b92b7c02f0aed73" dependencies = [ "proc-macro2", "quote", @@ -337,9 +337,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "js-sys" -version = "0.3.53" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +checksum = "1866b355d9c878e5e607473cbe3f63282c0b7aad2db1dbebf55076c686918254" dependencies = [ "wasm-bindgen", ] @@ -352,9 +352,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" +checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" [[package]] name = "log" @@ -417,7 +417,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "2.2.0" +version = "2.3.0" dependencies = [ "arbitrary", "arrayvec", @@ -435,7 +435,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "2.2.0" +version = "2.3.0" dependencies = [ "parity-scale-codec", "proc-macro-crate", @@ -484,9 +484,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" dependencies = [ "unicode-xid", ] @@ -621,9 +621,9 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.128" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1056a0db1978e9dbf0f6e4fca677f6f9143dc1c19de346f22cac23e422196834" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] @@ -640,9 +640,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.128" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13af2fbb8b60a8950d6c72a56d2095c28870367cc8e10c55e9745bac4995a2c4" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -651,9 +651,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" dependencies = [ "itoa", "ryu", @@ -662,9 +662,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" dependencies = [ "proc-macro2", "quote", @@ -697,18 +697,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" dependencies = [ "proc-macro2", "quote", @@ -750,9 +750,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "unicode-width" @@ -791,9 +791,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.76" +version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +checksum = "5e68338db6becec24d3c7977b5bf8a48be992c934b5d07177e3931f5dc9b076c" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -801,9 +801,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.76" +version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +checksum = "f34c405b4f0658583dba0c1c7c9b694f3cac32655db463b56c254a1c75269523" dependencies = [ "bumpalo", "lazy_static", @@ -816,9 +816,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.76" +version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +checksum = "b9d5a6580be83b19dc570a8f9c324251687ab2184e57086f71625feb57ec77c8" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -826,9 +826,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.76" +version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +checksum = "e3775a030dc6f5a0afd8a84981a21cc92a781eb429acef9ecce476d0c9113e92" dependencies = [ "proc-macro2", "quote", @@ -839,15 +839,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.76" +version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" +checksum = "c279e376c7a8e8752a8f1eaa35b7b0bee6bb9fb0cdacfa97cc3f1f289c87e2b4" [[package]] name = "web-sys" -version = "0.3.53" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +checksum = "0a84d70d1ec7d2da2d26a5bd78f4bca1b8c3254805363ce743b7a05bc30d195a" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 8074860e..88f942a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.2.0" +version = "2.3.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" diff --git a/derive/Cargo.toml b/derive/Cargo.toml index f8dc1348..3d3b0ce1 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.2.0" +version = "2.3.0" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 667fb830..1beca322 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -178,6 +178,11 @@ mod tests { } #[test] + // Flaky test due to: + // * https://github.com/bitvecto-rs/bitvec/issues/135 + // * https://github.com/rust-lang/miri/issues/1866 + #[cfg(not(miri))] + fn bitvec_u16() { for v in &test_data!(u16) { let encoded = v.encode(); @@ -194,6 +199,11 @@ mod tests { } #[test] + // Flaky test due to: + // * https://github.com/bitvecto-rs/bitvec/issues/135 + // * https://github.com/rust-lang/miri/issues/1866 + #[cfg(not(miri))] + fn bitvec_u64() { for v in &test_data!(u64) { let encoded = v.encode(); @@ -211,6 +221,10 @@ mod tests { } #[test] + // Flaky test due to: + // * https://github.com/bitvecto-rs/bitvec/issues/135 + // * https://github.com/rust-lang/miri/issues/1866 + #[cfg(not(miri))] fn bitbox() { let data: &[u8] = &[5, 10]; let slice = BitSlice::::from_slice(data).unwrap(); diff --git a/src/depth_limit.rs b/src/depth_limit.rs index cc0cf22e..7a6ec356 100644 --- a/src/depth_limit.rs +++ b/src/depth_limit.rs @@ -24,6 +24,11 @@ pub trait DecodeLimit: Sized { /// If `limit` is hit, an error is returned. fn decode_with_depth_limit(limit: u32, input: &[u8]) -> Result; + /// Decode `Self` and advance `input` by the number of bytes consumed. + /// + /// If `limit` is hit, an error is returned. + fn decode_and_advance_with_depth_limit(limit: u32, input: &mut I) -> Result; + /// Decode `Self` and consume all of the given input data. /// /// If not all data is consumed or `limit` is hit, an error is returned. @@ -82,6 +87,15 @@ impl DecodeLimit for T { } } + fn decode_and_advance_with_depth_limit(limit: u32, input: &mut I) -> Result { + let mut input = DepthTrackingInput { + input, + depth: 0, + max_depth: limit, + }; + T::decode(&mut input) + } + fn decode_with_depth_limit(limit: u32, input: &[u8]) -> Result { let mut input = DepthTrackingInput { input: &mut &input[..], @@ -107,4 +121,15 @@ mod tests { assert_eq!(decoded, nested); assert!(NestedVec::decode_with_depth_limit(2, &encoded).is_err()); } + + #[test] + fn decode_and_advance_works() { + type NestedVec = Vec>>>; + let nested: NestedVec = vec![vec![vec![vec![1]]]]; + let encoded = &mut &nested.encode()[..]; + + let decoded = Vec::::decode_and_advance_with_depth_limit(1, encoded).unwrap(); + assert_eq!(decoded, vec![4]); + assert!(NestedVec::decode_with_depth_limit(3, encoded).is_err()); + } } From 4fa5ddf786742b924eec7ef0b794815ea02c9ae6 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Mon, 13 Sep 2021 16:54:41 +0200 Subject: [PATCH 063/286] Minor codegen hygiene improvements and modernizations (#291) --- derive/src/decode.rs | 18 ++++--- derive/src/encode.rs | 53 ++++++++++++--------- derive/src/lib.rs | 89 ++++++++++++++++++++++------------- derive/src/max_encoded_len.rs | 2 +- derive/src/trait_bounds.rs | 5 +- 5 files changed, 102 insertions(+), 65 deletions(-) diff --git a/derive/src/decode.rs b/derive/src/decode.rs index bb1ce34b..10583256 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -31,6 +31,7 @@ pub fn quote( type_name: &Ident, type_generics: &TokenStream, input: &TokenStream, + crate_ident: &TokenStream, ) -> TokenStream { match *data { Data::Struct(ref data) => match data.fields { @@ -39,6 +40,7 @@ pub fn quote( &type_name.to_string(), input, &data.fields, + crate_ident, ), Fields::Unit => { quote_spanned! { data.fields.span() => @@ -65,6 +67,7 @@ pub fn quote( &format!("{}::{}", type_name, name), input, &v.fields, + crate_ident, ); quote_spanned! { v.span() => @@ -96,7 +99,7 @@ pub fn quote( } } -fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenStream { +fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_ident: &TokenStream) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); let compact = utils::is_compact(field); let skip = utils::should_skip(&field.attrs); @@ -117,7 +120,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt quote_spanned! { field.span() => { let #res = < - <#field_type as _parity_scale_codec::HasCompact>::Type as _parity_scale_codec::Decode + <#field_type as #crate_ident::HasCompact>::Type as #crate_ident::Decode >::decode(#input); match #res { ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), @@ -128,7 +131,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt } else if let Some(encoded_as) = encoded_as { quote_spanned! { field.span() => { - let #res = <#encoded_as as _parity_scale_codec::Decode>::decode(#input); + let #res = <#encoded_as as #crate_ident::Decode>::decode(#input); match #res { ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), ::core::result::Result::Ok(#res) => #res.into(), @@ -141,7 +144,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt let field_type = &field.ty; quote_spanned! { field.span() => { - let #res = <#field_type as _parity_scale_codec::Decode>::decode(#input); + let #res = <#field_type as #crate_ident::Decode>::decode(#input); match #res { ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), ::core::result::Result::Ok(#res) => #res, @@ -155,7 +158,8 @@ fn create_instance( name: TokenStream, name_str: &str, input: &TokenStream, - fields: &Fields + fields: &Fields, + crate_ident: &TokenStream, ) -> TokenStream { match *fields { Fields::Named(ref fields) => { @@ -165,7 +169,7 @@ fn create_instance( Some(a) => format!("{}::{}", name_str, a), None => format!("{}", name_str), // Should never happen, fields are named. }; - let decode = create_decode_expr(f, &field_name, input); + let decode = create_decode_expr(f, &field_name, input, crate_ident); quote_spanned! { f.span() => #name_ident: #decode @@ -182,7 +186,7 @@ fn create_instance( let recurse = fields.unnamed.iter().enumerate().map(|(i, f) | { let field_name = format!("{}.{}", name_str, i); - create_decode_expr(f, &field_name, input) + create_decode_expr(f, &field_name, input, crate_ident) }); quote_spanned! { fields.span() => diff --git a/derive/src/encode.rs b/derive/src/encode.rs index 434d4f3c..3e385182 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -30,6 +30,7 @@ type FieldsList = Punctuated; fn encode_single_field( field: &Field, field_name: TokenStream, + crate_ident: &TokenStream, ) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); let compact = utils::is_compact(field); @@ -52,8 +53,8 @@ fn encode_single_field( let field_type = &field.ty; quote_spanned! { field.span() => { - <<#field_type as _parity_scale_codec::HasCompact>::Type as - _parity_scale_codec::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) + <<#field_type as #crate_ident::HasCompact>::Type as + #crate_ident::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) } } } else if let Some(encoded_as) = encoded_as { @@ -61,7 +62,7 @@ fn encode_single_field( quote_spanned! { field.span() => { <#encoded_as as - _parity_scale_codec::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) + #crate_ident::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) } } } else { @@ -74,19 +75,19 @@ fn encode_single_field( let i_self = quote! { self }; quote_spanned! { field.span() => - fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output + ?Sized>( + fn encode_to<__CodecOutputEdqy: #crate_ident::Output + ?::core::marker::Sized>( &#i_self, __codec_dest_edqy: &mut __CodecOutputEdqy ) { - _parity_scale_codec::Encode::encode_to(&#final_field_variable, __codec_dest_edqy) + #crate_ident::Encode::encode_to(&#final_field_variable, __codec_dest_edqy) } - fn encode(&#i_self) -> _parity_scale_codec::alloc::vec::Vec { - _parity_scale_codec::Encode::encode(&#final_field_variable) + fn encode(&#i_self) -> #crate_ident::alloc::vec::Vec<::core::primitive::u8> { + #crate_ident::Encode::encode(&#final_field_variable) } fn using_encoded R>(&#i_self, f: F) -> R { - _parity_scale_codec::Encode::using_encoded(&#final_field_variable, f) + #crate_ident::Encode::using_encoded(&#final_field_variable, f) } } } @@ -95,6 +96,7 @@ fn encode_fields( dest: &TokenStream, fields: &FieldsList, field_name: F, + crate_ident: &TokenStream, ) -> TokenStream where F: Fn(usize, &Option) -> TokenStream, { @@ -117,10 +119,10 @@ fn encode_fields( let field_type = &f.ty; quote_spanned! { f.span() => { - _parity_scale_codec::Encode::encode_to( + #crate_ident::Encode::encode_to( &< - <#field_type as _parity_scale_codec::HasCompact>::Type as - _parity_scale_codec::EncodeAsRef<'_, #field_type> + <#field_type as #crate_ident::HasCompact>::Type as + #crate_ident::EncodeAsRef<'_, #field_type> >::RefType::from(#field), #dest, ); @@ -130,10 +132,10 @@ fn encode_fields( let field_type = &f.ty; quote_spanned! { f.span() => { - _parity_scale_codec::Encode::encode_to( + #crate_ident::Encode::encode_to( &< #encoded_as as - _parity_scale_codec::EncodeAsRef<'_, #field_type> + #crate_ident::EncodeAsRef<'_, #field_type> >::RefType::from(#field), #dest, ); @@ -145,7 +147,7 @@ fn encode_fields( } } else { quote_spanned! { f.span() => - _parity_scale_codec::Encode::encode_to(#field, #dest); + #crate_ident::Encode::encode_to(#field, #dest); } } }); @@ -155,7 +157,7 @@ fn encode_fields( } } -fn try_impl_encode_single_field_optimisation(data: &Data) -> Option { +fn try_impl_encode_single_field_optimisation(data: &Data, crate_ident: &TokenStream) -> Option { match *data { Data::Struct(ref data) => { match data.fields { @@ -164,7 +166,8 @@ fn try_impl_encode_single_field_optimisation(data: &Data) -> Option let name = &field.ident; Some(encode_single_field( field, - quote!(&self.#name) + quote!(&self.#name), + crate_ident, )) }, Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => { @@ -173,7 +176,8 @@ fn try_impl_encode_single_field_optimisation(data: &Data) -> Option Some(encode_single_field( field, - quote!(&self.#id) + quote!(&self.#id), + crate_ident, )) }, _ => None, @@ -183,7 +187,7 @@ fn try_impl_encode_single_field_optimisation(data: &Data) -> Option } } -fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { +fn impl_encode(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> TokenStream { let self_ = quote!(self); let dest = "e!(__codec_dest_edqy); let encoding = match *data { @@ -193,6 +197,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { dest, &fields.named, |_, name| quote!(&#self_.#name), + crate_ident, ), Fields::Unnamed(ref fields) => encode_fields( dest, @@ -201,6 +206,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { let i = syn::Index::from(i); quote!(&#self_.#i) }, + crate_ident, ), Fields::Unit => quote!(), } @@ -236,6 +242,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { dest, &fields.named, |a, b| field_name(a, b), + crate_ident, ); quote_spanned! { f.span() => @@ -261,6 +268,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { dest, &fields.unnamed, |a, b| field_name(a, b), + crate_ident, ); quote_spanned! { f.span() => @@ -292,9 +300,8 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { "Union types are not supported." ).to_compile_error(), }; - quote! { - fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output + ?Sized>( + fn encode_to<__CodecOutputEdqy: #crate_ident::Output + ?::core::marker::Sized>( &#self_, #dest: &mut __CodecOutputEdqy ) { @@ -303,11 +310,11 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream { } } -pub fn quote(data: &Data, type_name: &Ident) -> TokenStream { - if let Some(implementation) = try_impl_encode_single_field_optimisation(data) { +pub fn quote(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> TokenStream { + if let Some(implementation) = try_impl_encode_single_field_optimisation(data, crate_ident) { implementation } else { - impl_encode(data, type_name) + impl_encode(data, type_name, crate_ident) } } diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 624a912a..baed14dd 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -27,7 +27,7 @@ use proc_macro2::{Ident, Span}; use proc_macro_crate::{crate_name, FoundCrate}; use syn::spanned::Spanned; use syn::{Data, Field, Fields, DeriveInput, Error}; - +use proc_macro2::TokenStream as TokenStream2; use crate::utils::is_lint_attribute; mod decode; @@ -36,34 +36,35 @@ mod max_encoded_len; mod utils; mod trait_bounds; -/// Include the `parity-scale-codec` crate under a known name (`_parity_scale_codec`). -fn include_parity_scale_codec_crate() -> proc_macro2::TokenStream { +/// Returns the identifier of the `parity-scale-codec` crate as used. +/// +/// The identifier might change if the depending crate imported it +/// using a custom package name. +fn parity_scale_codec_ident() -> Result { + static CRATE_NAME: &str = "parity-scale-codec"; + fn root_import(name: &str) -> TokenStream2 { + let ident = Ident::new(name, Span::call_site()); + quote!{ :: #ident } + } // This "hack" is required for the tests. - if std::env::var("CARGO_PKG_NAME").unwrap() == "parity-scale-codec" { - quote!( extern crate parity_scale_codec as _parity_scale_codec; ) + if std::env::var("CARGO_PKG_NAME").unwrap() == CRATE_NAME { + Ok(root_import("parity_scale_codec")) } else { - match crate_name("parity-scale-codec") { - Ok(FoundCrate::Itself) => quote!( extern crate parity_scale_codec as _parity_scale_codec; ), - Ok(FoundCrate::Name(parity_codec_crate)) => { - let ident = Ident::new(&parity_codec_crate, Span::call_site()); - quote!( extern crate #ident as _parity_scale_codec; ) - }, - Err(e) => Error::new(Span::call_site(), &e).to_compile_error(), + match crate_name(CRATE_NAME) { + Ok(FoundCrate::Itself) => { + Ok(quote! { crate }) + } + Ok(FoundCrate::Name(custom_name)) => Ok(root_import(&custom_name)), + Err(e) => Err(Error::new(Span::call_site(), &e)), } } } /// Wraps the impl block in a "dummy const" fn wrap_with_dummy_const(input: DeriveInput, impl_block: proc_macro2::TokenStream) -> proc_macro::TokenStream { - let parity_codec_crate = include_parity_scale_codec_crate(); let attrs = input.attrs.into_iter().filter(is_lint_attribute); - let generated = quote! { const _: () = { - #[allow(unknown_lints)] - #[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))] - #[allow(rust_2018_idioms)] - #parity_codec_crate #(#attrs)* #impl_block }; @@ -148,15 +149,23 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream return e.to_compile_error().into(); } + let crate_ident = match crate::parity_scale_codec_ident() { + Ok(crate_ident) => crate_ident, + Err(error) => { + return error.into_compile_error().into() + } + }; + if let Some(custom_bound) = utils::custom_encode_trait_bound(&input.attrs) { input.generics.make_where_clause().predicates.extend(custom_bound); } else if let Err(e) = trait_bounds::add( &input.ident, &mut input.generics, &input.data, - parse_quote!(_parity_scale_codec::Encode), + parse_quote!(#crate_ident::Encode), None, utils::has_dumb_trait_bound(&input.attrs), + &crate_ident, ) { return e.to_compile_error().into(); } @@ -164,14 +173,14 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let name = &input.ident; let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - let encode_impl = encode::quote(&input.data, name); + let encode_impl = encode::quote(&input.data, name, &crate_ident); let impl_block = quote! { - impl #impl_generics _parity_scale_codec::Encode for #name #ty_generics #where_clause { + impl #impl_generics #crate_ident::Encode for #name #ty_generics #where_clause { #encode_impl } - impl #impl_generics _parity_scale_codec::EncodeLike for #name #ty_generics #where_clause {} + impl #impl_generics #crate_ident::EncodeLike for #name #ty_generics #where_clause {} }; wrap_with_dummy_const(input, impl_block) @@ -191,15 +200,23 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream return e.to_compile_error().into(); } + let crate_ident = match crate::parity_scale_codec_ident() { + Ok(crate_ident) => crate_ident, + Err(error) => { + return error.into_compile_error().into() + } + }; + if let Some(custom_bound) = utils::custom_decode_trait_bound(&input.attrs) { input.generics.make_where_clause().predicates.extend(custom_bound); } else if let Err(e) = trait_bounds::add( &input.ident, &mut input.generics, &input.data, - parse_quote!(_parity_scale_codec::Decode), + parse_quote!(#crate_ident::Decode), Some(parse_quote!(Default)), utils::has_dumb_trait_bound(&input.attrs), + &crate_ident, ) { return e.to_compile_error().into(); } @@ -209,13 +226,13 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let ty_gen_turbofish = ty_generics.as_turbofish(); let input_ = quote!(__codec_input_edqy); - let decoding = decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_); + let decoding = decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_, &crate_ident); let impl_block = quote! { - impl #impl_generics _parity_scale_codec::Decode for #name #ty_generics #where_clause { - fn decode<__CodecInputEdqy: _parity_scale_codec::Input>( + impl #impl_generics #crate_ident::Decode for #name #ty_generics #where_clause { + fn decode<__CodecInputEdqy: #crate_ident::Input>( #input_: &mut __CodecInputEdqy - ) -> ::core::result::Result { + ) -> ::core::result::Result { #decoding } } @@ -249,13 +266,21 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr return e.to_compile_error().into(); } + let crate_ident = match crate::parity_scale_codec_ident() { + Ok(crate_ident) => crate_ident, + Err(error) => { + return error.into_compile_error().into() + } + }; + if let Err(e) = trait_bounds::add( &input.ident, &mut input.generics, &input.data, - parse_quote!(_parity_scale_codec::CompactAs), + parse_quote!(#crate_ident::CompactAs), None, utils::has_dumb_trait_bound(&input.attrs), + &crate_ident, ) { return e.to_compile_error().into(); } @@ -311,22 +336,22 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr }; let impl_block = quote! { - impl #impl_generics _parity_scale_codec::CompactAs for #name #ty_generics #where_clause { + impl #impl_generics #crate_ident::CompactAs for #name #ty_generics #where_clause { type As = #inner_ty; fn encode_as(&self) -> &#inner_ty { #inner_field } fn decode_from(x: #inner_ty) - -> ::core::result::Result<#name #ty_generics, _parity_scale_codec::Error> + -> ::core::result::Result<#name #ty_generics, #crate_ident::Error> { ::core::result::Result::Ok(#constructor) } } - impl #impl_generics From<_parity_scale_codec::Compact<#name #ty_generics>> + impl #impl_generics From<#crate_ident::Compact<#name #ty_generics>> for #name #ty_generics #where_clause { - fn from(x: _parity_scale_codec::Compact<#name #ty_generics>) -> #name #ty_generics { + fn from(x: #crate_ident::Compact<#name #ty_generics>) -> #name #ty_generics { x.0 } } diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index 7a89fe23..35b9fedf 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -47,7 +47,7 @@ pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::Tok quote::quote!( const _: () = { impl #impl_generics #mel_trait for #name #ty_generics #where_clause { - fn max_encoded_len() -> usize { + fn max_encoded_len() -> ::core::primitive::usize { #data_expr } } diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index c6303f4f..a2361df7 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -14,7 +14,7 @@ use std::iter; -use proc_macro2::Ident; +use proc_macro2::{Ident, TokenStream}; use syn::{ spanned::Spanned, visit::{self, Visit}, @@ -112,6 +112,7 @@ pub fn add( codec_bound: syn::Path, codec_skip_bound: Option, dumb_trait_bounds: bool, + crate_ident: &TokenStream, ) -> Result<()> { let ty_params = generics.type_params().map(|p| p.ident.clone()).collect::>(); if ty_params.is_empty() { @@ -146,7 +147,7 @@ pub fn add( where_clause.predicates.push(parse_quote!(#ty : #codec_bound)) }); - let has_compact_bound: syn::Path = parse_quote!(_parity_scale_codec::HasCompact); + let has_compact_bound: syn::Path = parse_quote!(#crate_ident::HasCompact); compact_types .into_iter() .for_each(|ty| { From 7a845c205817d93f02ec7dbef2f20d056c6c76af Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 28 Sep 2021 17:38:43 +0200 Subject: [PATCH 064/286] Add test to assert macro hygiene for Encode and Decode derives (#293) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * improve macro hygiene in Decode derive * add UI tests with #![no_implicit_prelude] to assert macro hygiene Add tests for Decode and Encode derive proc macros. * fix compilation guard for max_encoded_len UI * Update tests/scale_codec_ui.rs Co-authored-by: Bastian Köcher * disable flaky test Co-authored-by: Bastian Köcher --- derive/src/decode.rs | 4 +++- src/bit_vec.rs | 4 ++++ tests/max_encoded_len.rs | 2 +- tests/scale_codec_ui.rs | 22 ++++++++++++++++++ .../pass/decode-no-implicit-prelude.rs | 23 +++++++++++++++++++ .../pass/encode-no-implicit-prelude.rs | 23 +++++++++++++++++++ 6 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 tests/scale_codec_ui.rs create mode 100644 tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs create mode 100644 tests/scale_codec_ui/pass/encode-no-implicit-prelude.rs diff --git a/derive/src/decode.rs b/derive/src/decode.rs index 10583256..75c4b74e 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -90,7 +90,9 @@ pub fn quote( .map_err(|e| e.chain(#read_byte_err_msg))? { #( #recurse )* - _ => ::core::result::Result::Err(#invalid_variant_err_msg.into()), + _ => ::core::result::Result::Err( + <_ as ::core::convert::Into<_>>::into(#invalid_variant_err_msg) + ), } } diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 1beca322..35d3123f 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -191,6 +191,10 @@ mod tests { } #[test] + // Flaky test due to: + // * https://github.com/bitvecto-rs/bitvec/issues/135 + // * https://github.com/rust-lang/miri/issues/1866 + #[cfg(not(miri))] fn bitvec_u32() { for v in &test_data!(u32) { let encoded = v.encode(); diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs index b657695a..5bc199dd 100644 --- a/tests/max_encoded_len.rs +++ b/tests/max_encoded_len.rs @@ -14,7 +14,7 @@ // limitations under the License. //! Tests for MaxEncodedLen derive macro -#![cfg(feature = "derive")] +#![cfg(all(feature = "derive", feature = "max-encoded-len"))] use parity_scale_codec::{MaxEncodedLen, Compact, Encode}; diff --git a/tests/scale_codec_ui.rs b/tests/scale_codec_ui.rs new file mode 100644 index 00000000..663217f6 --- /dev/null +++ b/tests/scale_codec_ui.rs @@ -0,0 +1,22 @@ +// Copyright (C) 2020-2021 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. + +#[test] +#[cfg(feature = "derive")] +fn scale_codec_ui_tests() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/scale_codec_ui/*.rs"); + t.pass("tests/scale_codec_ui/pass/*.rs"); +} diff --git a/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs b/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs new file mode 100644 index 00000000..6ee5e622 --- /dev/null +++ b/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs @@ -0,0 +1,23 @@ +#![no_implicit_prelude] + +#[derive(::parity_scale_codec::Decode)] +pub struct Struct { + field_1: i8, + field_2: i16, + field_3: i32, + field_4: i64, +} + +#[derive(::parity_scale_codec::Decode)] +pub enum Enum { + Variant1, + Variant2(i8, i16, i32, i64), + Variant3 { + field_1: i8, + field_2: i16, + field_3: i32, + field_4: i64, + } +} + +fn main() {} diff --git a/tests/scale_codec_ui/pass/encode-no-implicit-prelude.rs b/tests/scale_codec_ui/pass/encode-no-implicit-prelude.rs new file mode 100644 index 00000000..a8f9d2bc --- /dev/null +++ b/tests/scale_codec_ui/pass/encode-no-implicit-prelude.rs @@ -0,0 +1,23 @@ +#![no_implicit_prelude] + +#[derive(::parity_scale_codec::Encode)] +pub struct Struct { + field_1: i8, + field_2: i16, + field_3: i32, + field_4: i64, +} + +#[derive(::parity_scale_codec::Encode)] +pub enum Enum { + Variant1, + Variant2(i8, i16, i32, i64), + Variant3 { + field_1: i8, + field_2: i16, + field_3: i32, + field_4: i64, + } +} + +fn main() {} From a27e494eabca61e263e43367c9be96b2e0873b0c Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 28 Sep 2021 19:09:04 +0200 Subject: [PATCH 065/286] Prepare for release 2.3.1 (#294) --- CHANGELOG.md | 7 +++++++ Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 855027c0..92f64859 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,16 @@ # Changelog + All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.3.1] - 2021-09-28 + +### Fix + +- Improve macro hygiene of `Encode` and `Decode` proc. macro expansions. ([#291](https://github.com/paritytech/parity-scale-codec/pull/291), [#293](https://github.com/paritytech/parity-scale-codec/pull/293)) + ## [2.3.0] - 2021-09-11 ### Added diff --git a/Cargo.lock b/Cargo.lock index b2da490e..1f2c2f84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,7 +417,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "2.3.0" +version = "2.3.1" dependencies = [ "arbitrary", "arrayvec", @@ -435,7 +435,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "2.3.0" +version = "2.3.1" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index 88f942a1..264f3fd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.3.0" +version = "2.3.1" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -11,7 +11,7 @@ edition = "2018" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "2.2.0", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "2.3.1", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 3d3b0ce1..bc39a2a9 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.3.0" +version = "2.3.1" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2018" From ca03f7fd981855b7cd6348fe32a9831e8e142813 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 21 Oct 2021 11:09:51 +0100 Subject: [PATCH 066/286] Update codec compact docs links to docs.substrate.io (#296) --- README.md | 4 ++-- src/compact.rs | 2 +- src/lib.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c4925497..0c81fc26 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The encoded data does not include this contextual information. To get a better understanding of how the encoding is done for different types, take a look at the -[low-level data formats overview page at the Substrate docs site](https://substrate.dev/docs/en/knowledgebase/advanced/codec). +[low-level data formats overview page at the Substrate docs site](https://docs.substrate.io/v3/advanced/scale-codec/). ## Implementation @@ -45,7 +45,7 @@ Returns an `Err` if the decoding fails. ### CompactAs The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes them even more space/memory efficient. -The compact encoding is described [here](https://substrate.dev/docs/en/knowledgebase/advanced/codec#compactgeneral-integers). +The compact encoding is described [here](https://docs.substrate.io/v3/advanced/scale-codec/#compactgeneral-integers). * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. The type `As` is defined in the same trait and its implementation should be compact encode-able. diff --git a/src/compact.rs b/src/compact.rs index 4af468c7..89a7ea2c 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! [Compact encoding](https://substrate.dev/docs/en/overview/low-level-data-format#compact-general-integers) +//! [Compact encoding](https://docs.substrate.io/v3/advanced/scale-codec/#compactgeneral-integers) use arrayvec::ArrayVec; diff --git a/src/lib.rs b/src/lib.rs index 0e70ae19..aaa5ac77 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ //! //! To get a better understanding of how the encoding is done for different types, //! take a look at the -//! [SCALE Code page at the Substrate Knowledge Base](https://substrate.dev/docs/en/knowledgebase/advanced/codec). +//! [SCALE Code page at the Substrate Knowledge Base](https://docs.substrate.io/v3/advanced/scale-codec/). //! //! ## Implementation //! @@ -67,7 +67,7 @@ //! ### CompactAs //! //! The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes -//! them even more space/memory efficient. The compact encoding is described [here](https://substrate.dev/docs/en/knowledgebase/advanced/codec#compactgeneral-integers). +//! them even more space/memory efficient. The compact encoding is described [here](https://docs.substrate.io/v3/advanced/scale-codec/#compactgeneral-integers). //! //! * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. //! The type `As` is defined in the same trait and its implementation should be compact encode-able. From ce09441f86e168c3ad140396c6de6d853ce00e32 Mon Sep 17 00:00:00 2001 From: Dan Shields <35669742+NukeManDan@users.noreply.github.com> Date: Sun, 21 Nov 2021 02:38:56 -0700 Subject: [PATCH 067/286] move to rust 2021 (#298) * move to rust 2021 * edition = "2021" rust-version = "1.56.1" changelog * cargo update (needed for tests passing) * fix error message files * TRYBUILD=overwrite --- CHANGELOG.md | 3 + Cargo.lock | 92 +++++++++---------- Cargo.toml | 3 +- derive/Cargo.toml | 3 +- fuzzer/Cargo.toml | 3 +- tests/max_encoded_len_ui/crate_str.stderr | 12 +-- .../max_encoded_len_ui/incomplete_attr.stderr | 12 +-- .../missing_crate_specifier.stderr | 12 +-- tests/max_encoded_len_ui/not_encode.stderr | 10 +- 9 files changed, 78 insertions(+), 72 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92f64859..2d90fcda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +- Migrated to 2021 edition, enforcing MSRV of `1.56.1`. [#298](https://github.com/paritytech/parity-scale-codec/pull/298) + ## [2.3.1] - 2021-09-28 ### Fix diff --git a/Cargo.lock b/Cargo.lock index 1f2c2f84..7f9d7a8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,18 +13,18 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "577b08a4acd7b99869f863c50011b01eb73424ccc798ecd996f2e24817adfca7" +checksum = "510c76ecefdceada737ea728f4f9a84bd2e1ef29f1ba555e560940fe279954de" dependencies = [ "derive_arbitrary", ] [[package]] name = "arrayvec" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "atty" @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "bstr" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "lazy_static", "memchr", @@ -75,15 +75,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.7.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" [[package]] name = "byte-slice-cast" -version = "1.0.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65c1bf4a04a88c54f589125563643d773f3254b5c38571395e2b591c693bbc81" +checksum = "1d30c751592b77c499e7bce34d99d67c2c11bdc0574e9a488ddade14150a4698" [[package]] name = "cast" @@ -285,9 +285,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "half" -version = "1.7.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hermit-abi" @@ -337,9 +337,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "js-sys" -version = "0.3.54" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1866b355d9c878e5e607473cbe3f63282c0b7aad2db1dbebf55076c686918254" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ "wasm-bindgen", ] @@ -352,9 +352,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.101" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" [[package]] name = "log" @@ -474,9 +474,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" dependencies = [ "thiserror", "toml", @@ -484,9 +484,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" dependencies = [ "unicode-xid", ] @@ -504,9 +504,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] @@ -651,9 +651,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.67" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" +checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19" dependencies = [ "itoa", "ryu", @@ -662,9 +662,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.76" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" +checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" dependencies = [ "proc-macro2", "quote", @@ -697,18 +697,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -736,9 +736,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.45" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bdaf2a1d317f3d58b44b31c7f6436b9b9acafe7bddfeace50897c2b804d7792" +checksum = "150e726dc059e6fbd4fce3288f5bb3cf70128cf63b0dde23b938a3cad810fb23" dependencies = [ "glob", "lazy_static", @@ -756,9 +756,9 @@ checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" @@ -791,9 +791,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.77" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e68338db6becec24d3c7977b5bf8a48be992c934b5d07177e3931f5dc9b076c" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -801,9 +801,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.77" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34c405b4f0658583dba0c1c7c9b694f3cac32655db463b56c254a1c75269523" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" dependencies = [ "bumpalo", "lazy_static", @@ -816,9 +816,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.77" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d5a6580be83b19dc570a8f9c324251687ab2184e57086f71625feb57ec77c8" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -826,9 +826,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.77" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3775a030dc6f5a0afd8a84981a21cc92a781eb429acef9ecce476d0c9113e92" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ "proc-macro2", "quote", @@ -839,15 +839,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.77" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c279e376c7a8e8752a8f1eaa35b7b0bee6bb9fb0cdacfa97cc3f1f289c87e2b4" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" [[package]] name = "web-sys" -version = "0.3.54" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a84d70d1ec7d2da2d26a5bd78f4bca1b8c3254805363ce743b7a05bc30d195a" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 264f3fd1..0b6b08ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,8 @@ authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" categories = ["encoding"] -edition = "2018" +edition = "2021" +rust-version = "1.56.1" [dependencies] arrayvec = { version = "0.7", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index bc39a2a9..33ff281a 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -4,7 +4,8 @@ description = "Serialization and deserialization derive macro for Parity SCALE C version = "2.3.1" authors = ["Parity Technologies "] license = "Apache-2.0" -edition = "2018" +edition = "2021" +rust-version = "1.56.1" [lib] proc-macro = true diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index f2ba7415..422dc1d8 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -2,7 +2,8 @@ name = "codec-fuzzer" version = "0.1.0" authors = ["Parity Technologies ", "Vincent Ulitzsch "] -edition = "2018" +edition = "2021" +rust-version = "1.56.1" publish = false [dependencies] diff --git a/tests/max_encoded_len_ui/crate_str.stderr b/tests/max_encoded_len_ui/crate_str.stderr index 07048141..a634de8f 100644 --- a/tests/max_encoded_len_ui/crate_str.stderr +++ b/tests/max_encoded_len_ui/crate_str.stderr @@ -1,19 +1,19 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute - --> $DIR/crate_str.rs:4:9 + --> tests/max_encoded_len_ui/crate_str.rs:4:9 | 4 | #[codec(crate = "parity_scale_codec")] | ^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> $DIR/crate_str.rs:3:18 + --> tests/max_encoded_len_ui/crate_str.rs:3:18 | 3 | #[derive(Encode, MaxEncodedLen)] | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` | - ::: $WORKSPACE/src/max_encoded_len.rs + = note: required because of the requirements on the impl of `Encode` for `Example` +note: required by a bound in `MaxEncodedLen` + --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { - | ------ required by this bound in `MaxEncodedLen` - | - = note: required because of the requirements on the impl of `Encode` for `Example` + | ^^^^^^ required by this bound in `MaxEncodedLen` = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr index 560fdfe1..be8ff298 100644 --- a/tests/max_encoded_len_ui/incomplete_attr.stderr +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -1,19 +1,19 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute - --> $DIR/incomplete_attr.rs:4:9 + --> tests/max_encoded_len_ui/incomplete_attr.rs:4:9 | 4 | #[codec(crate)] | ^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> $DIR/incomplete_attr.rs:3:18 + --> tests/max_encoded_len_ui/incomplete_attr.rs:3:18 | 3 | #[derive(Encode, MaxEncodedLen)] | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` | - ::: $WORKSPACE/src/max_encoded_len.rs + = note: required because of the requirements on the impl of `Encode` for `Example` +note: required by a bound in `MaxEncodedLen` + --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { - | ------ required by this bound in `MaxEncodedLen` - | - = note: required because of the requirements on the impl of `Encode` for `Example` + | ^^^^^^ required by this bound in `MaxEncodedLen` = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/missing_crate_specifier.stderr b/tests/max_encoded_len_ui/missing_crate_specifier.stderr index 22ae84bd..8e9eeb27 100644 --- a/tests/max_encoded_len_ui/missing_crate_specifier.stderr +++ b/tests/max_encoded_len_ui/missing_crate_specifier.stderr @@ -1,19 +1,19 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute - --> $DIR/missing_crate_specifier.rs:4:9 + --> tests/max_encoded_len_ui/missing_crate_specifier.rs:4:9 | 4 | #[codec(parity_scale_codec)] | ^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> $DIR/missing_crate_specifier.rs:3:18 + --> tests/max_encoded_len_ui/missing_crate_specifier.rs:3:18 | 3 | #[derive(Encode, MaxEncodedLen)] | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` | - ::: $WORKSPACE/src/max_encoded_len.rs + = note: required because of the requirements on the impl of `Encode` for `Example` +note: required by a bound in `MaxEncodedLen` + --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { - | ------ required by this bound in `MaxEncodedLen` - | - = note: required because of the requirements on the impl of `Encode` for `Example` + | ^^^^^^ required by this bound in `MaxEncodedLen` = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/not_encode.stderr b/tests/max_encoded_len_ui/not_encode.stderr index 29a82d7f..0c23bc9f 100644 --- a/tests/max_encoded_len_ui/not_encode.stderr +++ b/tests/max_encoded_len_ui/not_encode.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `NotEncode: WrapperTypeEncode` is not satisfied - --> $DIR/not_encode.rs:3:10 + --> tests/max_encoded_len_ui/not_encode.rs:3:10 | 3 | #[derive(MaxEncodedLen)] | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `NotEncode` | - ::: $WORKSPACE/src/max_encoded_len.rs + = note: required because of the requirements on the impl of `Encode` for `NotEncode` +note: required by a bound in `MaxEncodedLen` + --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { - | ------ required by this bound in `MaxEncodedLen` - | - = note: required because of the requirements on the impl of `Encode` for `NotEncode` + | ^^^^^^ required by this bound in `MaxEncodedLen` = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) From 8ba7d5aeeeab541a6f44f4daf30e06f0ccab2e22 Mon Sep 17 00:00:00 2001 From: Sergejs Kostjucenko <85877331+sergejparity@users.noreply.github.com> Date: Tue, 23 Nov 2021 10:18:20 +0200 Subject: [PATCH 068/286] Add CODEOWNERS file (#300) --- CODEOWNERS | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..be41e024 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,22 @@ +# Lists some code owners. +# +# A codeowner just oversees some part of the codebase. If an owned file is changed then the +# corresponding codeowner receives a review request. An approval of the codeowner might be +# required for merging a PR (depends on repository settings). +# +# For details about syntax, see: +# https://help.github.com/en/articles/about-code-owners +# But here are some important notes: +# +# - Glob syntax is git-like, e.g. `/core` means the core directory in the root, unlike `core` +# which can be everywhere. +# - Multiple owners are supported. +# - Either handle (e.g, @github_user or @github_org/team) or email can be used. Keep in mind, +# that handles might work better because they are more recognizable on GitHub, +# eyou can use them for mentioning unlike an email. +# - The latest matching rule, if multiple, takes precedence. + +# CI +/.github/ @paritytech/ci +/scripts/ @paritytech/ci +/.gitlab-ci.yml @paritytech/ci From baa5863322117208203547f8ca00fec74f2e2f75 Mon Sep 17 00:00:00 2001 From: GreenBaneling | Supercolony Date: Tue, 23 Nov 2021 19:41:55 +0200 Subject: [PATCH 069/286] Optimised the `Decode::decode` for `[T; N]` (#299) * Simplified Decode for [T; N] * Robepop version * Added specific implementation for u8, i8, and other integers. Added tests. * Removed Debug(added for testing) * Add #[inline] * Fixed tests with a new rust. Fixed comments in PR * Fixed formatting * Added comment to describe complexity of transmute=) * Use `forget` instead of `ManualDrop` to avoid memory leak in case of error --- Cargo.lock | 7 +++ Cargo.toml | 1 + src/codec.rs | 122 +++++++++++++++++++++++++++++++++++++++---- tests/chain-error.rs | 8 +-- 4 files changed, 123 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f9d7a8a..c5638948 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,6 +427,7 @@ dependencies = [ "generic-array", "impl-trait-for-tuples", "parity-scale-codec-derive", + "paste", "quickcheck", "serde", "serde_derive", @@ -444,6 +445,12 @@ dependencies = [ "syn", ] +[[package]] +name = "paste" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" + [[package]] name = "plotters" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 0b6b08ee..644ea109 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" trybuild = "1.0.42" +paste = "1" [[bench]] name = "benches" diff --git a/src/codec.rs b/src/codec.rs index 4d3aebaa..4e59cb8e 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -20,8 +20,13 @@ use core::{ iter::FromIterator, marker::PhantomData, mem, + mem::{ + MaybeUninit, + forget, + }, ops::{Deref, Range, RangeInclusive}, time::Duration, + ptr, }; use core::num::{ NonZeroI8, @@ -35,7 +40,6 @@ use core::num::{ NonZeroU64, NonZeroU128, }; -use arrayvec::ArrayVec; use byte_slice_cast::{AsByteSlice, AsMutByteSlice, ToMutByteSlice}; @@ -637,7 +641,91 @@ pub(crate) fn encode_slice_no_len(slice: &[T], de } } -/// Decode the slice (without prepended the len). +/// Decode the array. +/// +/// This is equivalent to decoding all the element one by one, but it is optimized for some types. +#[inline] +pub(crate) fn decode_array(input: &mut I) -> Result<[T; N], Error> { + #[inline] + fn general_array_decode(input: &mut I) -> Result<[T; N], Error> { + let mut uninit = >::uninit(); + // The following line coerces the pointer to the array to a pointer + // to the first array element which is equivalent. + let mut ptr = uninit.as_mut_ptr() as *mut T; + for _ in 0..N { + let decoded = T::decode(input)?; + // SAFETY: We do not read uninitialized array contents + // while initializing them. + unsafe { + ptr::write(ptr, decoded); + } + // SAFETY: Point to the next element after every iteration. + // We do this N times therefore this is safe. + ptr = unsafe { ptr.add(1) }; + } + // SAFETY: All array elements have been initialized above. + let init = unsafe { uninit.assume_init() }; + Ok(init) + } + + // Description for the code below. + // It is not possible to transmute `[u8; N]` into `[T; N]` due to this issue: + // https://github.com/rust-lang/rust/issues/61956 + // + // Workaround: Transmute `&[u8; N]` into `&[T; N]` and interpret that reference as value. + // ``` + // let mut array: [u8; N] = [0; N]; + // let ref_typed: &[T; N] = unsafe { mem::transmute(&array) }; + // let typed: [T; N] = unsafe { ptr::read(ref_typed) }; + // forget(array); + // Here `array` and `typed` points on the same memory. + // Function returns `typed` -> it is not dropped, but `array` will be dropped. + // To avoid that `array` should be forgotten. + // ``` + macro_rules! decode { + ( u8 ) => {{ + let mut array: [u8; N] = [0; N]; + input.read(&mut array[..])?; + let ref_typed: &[T; N] = unsafe { mem::transmute(&array) }; + let typed: [T; N] = unsafe { ptr::read(ref_typed) }; + forget(array); + Ok(typed) + }}; + ( i8 ) => {{ + let mut array: [i8; N] = [0; N]; + let bytes = unsafe { mem::transmute::<&mut [i8], &mut [u8]>(&mut array[..]) }; + input.read(bytes)?; + + let ref_typed: &[T; N] = unsafe { mem::transmute(&array) }; + let typed: [T; N] = unsafe { ptr::read(ref_typed) }; + forget(array); + Ok(typed) + }}; + ( $ty:ty ) => {{ + if cfg!(target_endian = "little") { + let mut array: [$ty; N] = [0; N]; + let bytes = <[$ty] as AsMutByteSlice<$ty>>::as_mut_byte_slice(&mut array[..]); + input.read(bytes)?; + let ref_typed: &[T; N] = unsafe { mem::transmute(&array) }; + let typed: [T; N] = unsafe { ptr::read(ref_typed) }; + forget(array); + Ok(typed) + } else { + general_array_decode(input) + } + }}; + } + + with_type_info! { + ::TYPE_INFO, + decode, + { + general_array_decode(input) + }, + } +} + +/// Decode the vec (without prepended the len). /// /// This is equivalent to decode all elements one by one, but it is optimized in some /// situation. @@ -706,16 +794,9 @@ impl Encode for [T; N] { } impl Decode for [T; N] { + #[inline] fn decode(input: &mut I) -> Result { - let mut array = ArrayVec::new(); - for _ in 0..N { - array.push(T::decode(input)?); - } - - match array.into_inner() { - Ok(a) => Ok(a), - Err(_) => panic!("We decode `N` elements; qed"), - } + decode_array(input) } } @@ -1647,6 +1728,25 @@ mod tests { <[u32; 0]>::decode(&mut &encoded[..]).unwrap(); } + + macro_rules! test_array_encode_and_decode { + ( $( $name:ty ),* $(,)? ) => { + $( + paste::item! { + #[test] + fn []() { + let data: [$name; 32] = [123; 32]; + let encoded = data.encode(); + let decoded: [$name; 32] = Decode::decode(&mut &encoded[..]).unwrap(); + assert_eq!(decoded, data); + } + } + )* + } + } + + test_array_encode_and_decode!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128); + fn test_encoded_size(val: impl Encode) { let length = val.using_encoded(|v| v.len()); diff --git a/tests/chain-error.rs b/tests/chain-error.rs index d06f3582..6a106ae2 100644 --- a/tests/chain-error.rs +++ b/tests/chain-error.rs @@ -21,7 +21,7 @@ struct Wrapper(T); #[derive(Decode, Debug)] struct StructNamed { - foo: u16 + _foo: u16 } #[derive(Decode, Debug)] @@ -29,7 +29,7 @@ struct StructUnnamed(u16); #[derive(Decode, Debug)] enum E { - VariantNamed { foo: u16, }, + VariantNamed { _foo: u16, }, VariantUnnamed(u16), } @@ -37,7 +37,7 @@ enum E { fn full_error_struct_named() { let encoded = vec![0]; let err = r#"Could not decode `Wrapper.0`: - Could not decode `StructNamed::foo`: + Could not decode `StructNamed::_foo`: Not enough data to fill buffer "#; @@ -75,7 +75,7 @@ fn full_error_enum_unknown_variant() { #[test] fn full_error_enum_named_field() { let encoded = vec![0, 0]; - let err = r#"Could not decode `E::VariantNamed::foo`: + let err = r#"Could not decode `E::VariantNamed::_foo`: Not enough data to fill buffer "#; From 94f5887207af4abfb85e266985f9bd260ee09e04 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Wed, 24 Nov 2021 09:07:43 +0900 Subject: [PATCH 070/286] Add some doc for the derive macro (#301) * some doc * Update derive/src/lib.rs Co-authored-by: David * fmt Co-authored-by: David --- derive/Cargo.toml | 2 +- derive/src/lib.rs | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 33ff281a..0d312ad6 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -17,7 +17,7 @@ proc-macro2 = "1.0.6" proc-macro-crate = "1.0.0" [dev-dependencies] -parity-scale-codec = { path = ".." } +parity-scale-codec = { path = "..", features = ["max-encoded-len"] } [features] # Enables the new `MaxEncodedLen` trait. diff --git a/derive/src/lib.rs b/derive/src/lib.rs index baed14dd..38248929 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -75,6 +75,15 @@ fn wrap_with_dummy_const(input: DeriveInput, impl_block: proc_macro2::TokenStrea /// Derive `parity_scale_codec::Encode` and `parity_scale_codec::EncodeLike` for struct and enum. /// +/// # Top level attributes +/// +/// By default the macro will add [`Encode`] and [`Decode`] bounds to all types, but the bounds can +/// be specified manually with the top level attributes: +/// * `#[codec(encode_bound(T: Encode))]`: a custom bound added to the `where`-clause when deriving +/// the `Encode` trait, overriding the default. +/// * `#[codec(decode_bound(T: Decode))]`: a custom bound added to the `where`-clause when deriving +/// the `Decode` trait, overriding the default. +/// /// # Struct /// /// A struct is encoded by encoding each of its fields successively. @@ -87,8 +96,6 @@ fn wrap_with_dummy_const(input: DeriveInput, impl_block: proc_macro2::TokenStrea /// type must implement `parity_scale_codec::EncodeAsRef<'_, $FieldType>` with $FieldType the /// type of the field with the attribute. This is intended to be used for types implementing /// `HasCompact` as shown in the example. -/// * `#[codec(encode_bound(T: Encode))]`: a custom where bound that will be used when deriving the `Encode` trait. -/// * `#[codec(decode_bound(T: Encode))]`: a custom where bound that will be used when deriving the `Decode` trait. /// /// ``` /// # use parity_scale_codec_derive::Encode; @@ -360,7 +367,19 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr wrap_with_dummy_const(input, impl_block) } -/// Derive `MaxEncodedLen`. +/// Derive `parity_scale_codec::MaxEncodedLen` for struct and enum. +/// +/// # Top level attribute +/// +/// By default the macro will try to bound the types needed to implement `MaxEncodedLen`, but the +/// bounds can be specified manually with the top level attribute: +/// ``` +/// # use parity_scale_codec_derive::Encode; +/// # use parity_scale_codec::MaxEncodedLen; +/// # #[derive(Encode, MaxEncodedLen)] +/// #[codec(mel_bound(T: MaxEncodedLen))] +/// # struct MyWrapper(T); +/// ``` #[cfg(feature = "max-encoded-len")] #[proc_macro_derive(MaxEncodedLen, attributes(max_encoded_len_mod))] pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream { From eb37d20541a752b03c020a1767d0425e7348d23e Mon Sep 17 00:00:00 2001 From: Artem Vorotnikov Date: Sun, 23 Jan 2022 20:45:21 +0300 Subject: [PATCH 071/286] Add bytes::Bytes implementation (#309) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * TRYBUILD=overwrite * Add bytes implementation * Apply suggestions from code review * Update src/codec.rs * TRYBUILD=overwrite Co-authored-by: Bastian Köcher --- .gitlab-ci.yml | 16 ++++++------- Cargo.lock | 7 ++++++ Cargo.toml | 1 + src/codec.rs | 30 +++++++++++++++++++++++++ tests/max_encoded_len_ui/not_mel.stderr | 22 ++++++++++++++---- 5 files changed, 64 insertions(+), 12 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 86540b76..b21a2742 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -51,14 +51,14 @@ check-rust-stable-no_derive_no_std_full: stage: check <<: *docker-env script: - - time cargo +stable check --verbose --no-default-features --features bit-vec,generic-array,full + - time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array,full - sccache -s check-rust-stable-no_derive_no_std: stage: check <<: *docker-env script: - - time cargo +stable check --verbose --no-default-features --features bit-vec,generic-array + - time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array - sccache -s check-rust-stable-no_std-chain-error: @@ -72,7 +72,7 @@ check-rust-stable-no_derive_full: stage: check <<: *docker-env script: - - time cargo +stable check --verbose --features bit-vec,generic-array,full + - time cargo +stable check --verbose --features bit-vec,bytes,generic-array,full - sccache -s #### stage: test @@ -81,21 +81,21 @@ test-rust-stable: stage: test <<: *docker-env script: - - time cargo +stable test --verbose --all --features bit-vec,generic-array,derive,max-encoded-len + - time cargo +stable test --verbose --all --features bit-vec,bytes,generic-array,derive,max-encoded-len - sccache -s test-rust-stable-no_derive: stage: test <<: *docker-env script: - - time cargo +stable test --verbose --features bit-vec,generic-array + - time cargo +stable test --verbose --features bit-vec,bytes,generic-array - sccache -s bench-rust-nightly: stage: test <<: *docker-env script: - - time cargo +nightly bench --features bit-vec,generic-array,derive + - time cargo +nightly bench --features bit-vec,bytes,generic-array,derive - sccache -s miri: @@ -105,7 +105,7 @@ miri: RUST_BACKTRACE: 1 MIRIFLAGS: "-Zmiri-disable-isolation" script: - - time cargo +nightly miri test --features bit-vec,generic-array,arbitrary --release + - time cargo +nightly miri test --features bit-vec,bytes,generic-array,arbitrary --release #### stage: build @@ -118,5 +118,5 @@ build-linux-ubuntu-amd64: - if: $CI_COMMIT_REF_NAME == "master" - if: $CI_COMMIT_REF_NAME == "tags" script: - - cargo build --verbose --release --features bit-vec,generic-array,derive + - cargo build --verbose --release --features bit-vec,bytes,generic-array,derive - sccache -s diff --git a/Cargo.lock b/Cargo.lock index c5638948..c1b21a3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,6 +85,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d30c751592b77c499e7bce34d99d67c2c11bdc0574e9a488ddade14150a4698" +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + [[package]] name = "cast" version = "0.2.7" @@ -423,6 +429,7 @@ dependencies = [ "arrayvec", "bitvec", "byte-slice-cast", + "bytes", "criterion", "generic-array", "impl-trait-for-tuples", diff --git a/Cargo.toml b/Cargo.toml index 644ea109..6ffd6e2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } parity-scale-codec-derive = { path = "derive", version = "2.3.1", default-features = false, optional = true } bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } +bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } arbitrary = { version = "1.0.1", features = ["derive"], optional = true } diff --git a/src/codec.rs b/src/codec.rs index 4e59cb8e..69696ea6 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -371,6 +371,23 @@ mod feature_full_wrapper_type_encode { impl EncodeLike for &str {} } +#[cfg(feature = "bytes")] +mod feature_wrapper_bytes { + use super::*; + use bytes::Bytes; + + impl WrapperTypeEncode for Bytes {} + impl EncodeLike for Bytes {} + impl EncodeLike<&[u8]> for Bytes {} + impl EncodeLike> for Bytes {} + impl EncodeLike for &[u8] {} + impl EncodeLike for Vec {} + + impl WrapperTypeDecode for Bytes { + type Wrapped = Vec; + } +} + impl Encode for X where T: Encode + ?Sized, X: WrapperTypeEncode, @@ -1429,6 +1446,19 @@ mod tests { assert_eq!(>::decode(&mut &encoded[..]).unwrap(), value); } + #[cfg(feature = "bytes")] + #[test] + fn bytes_works_as_expected() { + let input = bytes::Bytes::from_static(b"hello"); + let encoded = Encode::encode(&input); + let encoded_vec = input.to_vec().encode(); + assert_eq!(encoded, encoded_vec); + + assert_eq!( + &b"hello"[..], + bytes::Bytes::decode(&mut &encoded[..]).unwrap(), + ); + } fn test_encode_length(thing: &T, len: usize) { assert_eq!(::len(&mut &thing.encode()[..]).unwrap(), len); } diff --git a/tests/max_encoded_len_ui/not_mel.stderr b/tests/max_encoded_len_ui/not_mel.stderr index 8b9b2684..1361561f 100644 --- a/tests/max_encoded_len_ui/not_mel.stderr +++ b/tests/max_encoded_len_ui/not_mel.stderr @@ -1,5 +1,5 @@ error[E0599]: the function or associated item `max_encoded_len` exists for struct `Generic`, but its trait bounds were not satisfied - --> $DIR/not_mel.rs:12:29 + --> tests/max_encoded_len_ui/not_mel.rs:12:29 | 4 | struct NotMel; | -------------- doesn't satisfy `NotMel: MaxEncodedLen` @@ -13,9 +13,23 @@ error[E0599]: the function or associated item `max_encoded_len` exists for struc 12 | let _ = Generic::::max_encoded_len(); | ^^^^^^^^^^^^^^^ function or associated item cannot be called on `Generic` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `NotMel: MaxEncodedLen` - which is required by `Generic: MaxEncodedLen` +note: the following trait bounds were not satisfied because of the requirements of the implementation of `MaxEncodedLen` for `_`: + `NotMel: MaxEncodedLen` + --> tests/max_encoded_len_ui/not_mel.rs:6:18 + | +6 | #[derive(Encode, MaxEncodedLen)] + | ^^^^^^^^^^^^^ +7 | struct Generic { + | ^^^^^^^^^^ +note: the following trait must be implemented + --> src/max_encoded_len.rs + | + | / pub trait MaxEncodedLen: Encode { + | | /// Upper bound, in bytes, of the maximum encoded size of this item. + | | fn max_encoded_len() -> usize; + | | } + | |_^ = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `max_encoded_len`, perhaps you need to implement it: candidate #1: `MaxEncodedLen` + = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) From 2bffcf90c1ad8c6555d1929f40adb8638877389a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 1 Feb 2022 15:01:43 +0100 Subject: [PATCH 072/286] Upgrade to BitVec 1.0 (#311) * Upgrade to BitVec 1.0 * Fix benches --- Cargo.lock | 19 +++-- Cargo.toml | 2 +- benches/benches.rs | 6 +- fuzzer/Cargo.toml | 2 +- fuzzer/src/main.rs | 16 ++-- src/bit_vec.rs | 202 +++++++++++++++++++-------------------------- 6 files changed, 108 insertions(+), 139 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1b21a3b..88585619 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,9 +51,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitvec" -version = "0.20.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" dependencies = [ "funty", "radium", @@ -258,9 +258,9 @@ dependencies = [ [[package]] name = "funty" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "generic-array" @@ -527,9 +527,9 @@ dependencies = [ [[package]] name = "radium" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" @@ -900,6 +900,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "wyz" -version = "0.2.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" +checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +dependencies = [ + "tap", +] diff --git a/Cargo.toml b/Cargo.toml index 6ffd6e2b..c5670890 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ rust-version = "1.56.1" arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } parity-scale-codec-derive = { path = "derive", version = "2.3.1", default-features = false, optional = true } -bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true } +bitvec = { version = "1", default-features = false, features = ["alloc"], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } diff --git a/benches/benches.rs b/benches/benches.rs index 242b8bd4..248147e2 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -203,7 +203,7 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { #[cfg(feature = "bit-vec")] c.bench_function_over_inputs("bitvec_u8_encode - BitVec", |b, &size| { - let vec: BitVec = [true, false] + let vec: BitVec = [true, false] .iter() .cloned() .cycle() @@ -216,7 +216,7 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { #[cfg(feature = "bit-vec")] c.bench_function_over_inputs("bitvec_u8_decode - BitVec", |b, &size| { - let vec: BitVec = [true, false] + let vec: BitVec = [true, false] .iter() .cloned() .cycle() @@ -227,7 +227,7 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { let vec = black_box(vec); b.iter(|| { - let _: BitVec = Decode::decode(&mut &vec[..]).unwrap(); + let _: BitVec = Decode::decode(&mut &vec[..]).unwrap(); }) }, vec![1, 2, 5, 32, 1024]); } diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 422dc1d8..c3dae4ea 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -10,4 +10,4 @@ publish = false parity-scale-codec = { path = "..", features = ["derive", "bit-vec", "fuzz"] } honggfuzz = "0.5.54" arbitrary = { version = "1.0.1", features = ["derive"] } -bitvec = { version = "0.20.1", features = ["alloc"] } +bitvec = { version = "1", features = ["alloc"] } diff --git a/fuzzer/src/main.rs b/fuzzer/src/main.rs index dae55189..8463d74e 100644 --- a/fuzzer/src/main.rs +++ b/fuzzer/src/main.rs @@ -13,12 +13,12 @@ pub struct MockStruct{ /// Used for implementing the Arbitrary trait for a BitVec. #[derive(Encode, Decode, Clone, PartialEq, Debug)] -pub struct BitVecWrapper(BitVec); +pub struct BitVecWrapper(BitVec); -impl<'a, O: 'static + BitOrder, T: 'static + BitStore + Arbitrary<'a>> Arbitrary<'a> for BitVecWrapper { +impl<'a, O: 'static + BitOrder, T: 'static + BitStore + Arbitrary<'a>> Arbitrary<'a> for BitVecWrapper { fn arbitrary(u: &mut Unstructured<'a>) -> ArbResult { let v = Vec::::arbitrary(u)?; - Ok(BitVecWrapper(BitVec::::from_vec(v))) + Ok(BitVecWrapper(BitVec::::from_vec(v))) } } @@ -40,7 +40,7 @@ pub enum MockEnum { UnitVec(Vec), Complex { data: Vec, - bitvec: BitVecWrapper, + bitvec: BitVecWrapper, string: String, }, Mock(MockStruct), @@ -226,8 +226,8 @@ fn fuzz_decode(data: &[u8]) { VecDeque, MockStruct, MockEnum, - BitVec, - BitVec, + BitVec, + BitVec, Duration, }; // Types for which we wish to apply the "sorted" method. @@ -299,8 +299,8 @@ macro_rules! fuzz_encoding { BinaryHeapWrapper, MockStruct, MockEnum, - BitVecWrapper, - BitVecWrapper, + BitVecWrapper, + BitVecWrapper, Duration, } }; diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 35d3123f..3341e158 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -15,52 +15,58 @@ //! `BitVec` specific serialization. use bitvec::{ - vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox, mem::BitMemory + vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox, }; use crate::{ EncodeLike, Encode, Decode, Input, Output, Error, Compact, codec::{decode_vec_with_len, encode_slice_no_len}, }; -impl Encode for BitSlice { +impl Encode for BitSlice + where + T::Mem: Encode +{ fn encode_to(&self, dest: &mut W) { - let len = self.len(); + let bits = self.len(); assert!( - len <= u32::max_value() as usize, - "Attempted to serialize a collection with too many elements.", + bits <= ARCH32BIT_BITSLICE_MAX_BITS, + "Attempted to encode a BitSlice with too many bits.", ); - Compact(len as u32).encode_to(dest); + Compact(bits as u32).encode_to(dest); - // NOTE: doc of `BitSlice::as_slice`: - // > The returned slice handle views all elements touched by self - // - // Thus we are sure the slice doesn't contain unused elements at the end. - let slice = self.as_slice(); - - encode_slice_no_len(slice, dest) + for element in self.domain() { + element.encode_to(dest); + } } } -impl Encode for BitVec { +impl Encode for BitVec { fn encode_to(&self, dest: &mut W) { - self.as_bitslice().encode_to(dest) + let bits = self.len(); + assert!( + bits <= ARCH32BIT_BITSLICE_MAX_BITS, + "Attempted to encode a BitVec with too many bits.", + ); + Compact(bits as u32).encode_to(dest); + + let slice = self.as_raw_slice(); + encode_slice_no_len(slice, dest) } } -impl EncodeLike for BitVec {} +impl EncodeLike for BitVec {} /// Equivalent of `BitStore::MAX_BITS` on 32bit machine. const ARCH32BIT_BITSLICE_MAX_BITS: usize = 0x1fff_ffff; -impl Decode for BitVec { +impl Decode for BitVec { fn decode(input: &mut I) -> Result { >::decode(input).and_then(move |Compact(bits)| { // Otherwise it is impossible to store it on 32bit machine. if bits as usize > ARCH32BIT_BITSLICE_MAX_BITS { - return Err("Attempt to decode a bitvec with too many bits".into()); + return Err("Attempt to decode a BitVec with too many bits".into()); } - let required_elements = required_elements::(bits)? as usize; - let vec = decode_vec_with_len(input, required_elements)?; + let vec = decode_vec_with_len(input, bitvec::mem::elts::(bits as usize))?; let mut result = Self::try_from_vec(vec) .map_err(|_| { @@ -76,32 +82,28 @@ impl Decode for BitVec { } } -impl Encode for BitBox { +impl Encode for BitBox { fn encode_to(&self, dest: &mut W) { - self.as_bitslice().encode_to(dest) + let bits = self.len(); + assert!( + bits <= ARCH32BIT_BITSLICE_MAX_BITS, + "Attempted to encode a BitBox with too many bits.", + ); + Compact(bits as u32).encode_to(dest); + + let slice = self.as_raw_slice(); + encode_slice_no_len(slice, dest) } } -impl EncodeLike for BitBox {} +impl EncodeLike for BitBox {} -impl Decode for BitBox { +impl Decode for BitBox { fn decode(input: &mut I) -> Result { - Ok(Self::from_bitslice(BitVec::::decode(input)?.as_bitslice())) + Ok(BitVec::::decode(input)?.into()) } } -/// Calculates the number of element `T` required to store given amount of `bits` as if they were -/// stored in `BitVec<_, T>` -/// -/// Returns an error if the number of bits + number of bits in element overflow u32 capacity. -/// NOTE: this should never happen if `bits` is already checked to be less than -/// `BitStore::MAX_BITS`. -fn required_elements(bits: u32) -> Result { - let element_bits = T::Mem::BITS as u32; - let error = Error::from("Attempt to decode bitvec with too many bits"); - Ok((bits.checked_add(element_bits).ok_or_else(|| error)? - 1) / element_bits) -} - #[cfg(test)] mod tests { use super::*; @@ -111,130 +113,94 @@ mod tests { macro_rules! test_data { ($inner_type:ident) => ( [ - BitVec::::new(), - bitvec![Msb0, $inner_type; 0], - bitvec![Msb0, $inner_type; 1], - bitvec![Msb0, $inner_type; 0, 0], - bitvec![Msb0, $inner_type; 1, 0], - bitvec![Msb0, $inner_type; 0, 1], - bitvec![Msb0, $inner_type; 1, 1], - bitvec![Msb0, $inner_type; 1, 0, 1], - bitvec![Msb0, $inner_type; 0, 1, 0, 1, 0, 1, 1], - bitvec![Msb0, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0], - bitvec![Msb0, $inner_type; 1, 1, 0, 1, 0, 1, 1, 0, 1], - bitvec![Msb0, $inner_type; 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0], - bitvec![Msb0, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0], - bitvec![Msb0, $inner_type; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0], - bitvec![Msb0, $inner_type; 0; 15], - bitvec![Msb0, $inner_type; 1; 16], - bitvec![Msb0, $inner_type; 0; 17], - bitvec![Msb0, $inner_type; 1; 31], - bitvec![Msb0, $inner_type; 0; 32], - bitvec![Msb0, $inner_type; 1; 33], - bitvec![Msb0, $inner_type; 0; 63], - bitvec![Msb0, $inner_type; 1; 64], - bitvec![Msb0, $inner_type; 0; 65], - bitvec![Msb0, $inner_type; 1; MAX_PREALLOCATION * 8 + 1], - bitvec![Msb0, $inner_type; 0; MAX_PREALLOCATION * 9], - bitvec![Msb0, $inner_type; 1; MAX_PREALLOCATION * 32 + 1], - bitvec![Msb0, $inner_type; 0; MAX_PREALLOCATION * 33], + BitVec::<$inner_type, Msb0>::new(), + bitvec![$inner_type, Msb0; 0], + bitvec![$inner_type, Msb0; 1], + bitvec![$inner_type, Msb0; 0, 0], + bitvec![$inner_type, Msb0; 1, 0], + bitvec![$inner_type, Msb0; 0, 1], + bitvec![$inner_type, Msb0; 1, 1], + bitvec![$inner_type, Msb0; 1, 0, 1], + bitvec![$inner_type, Msb0; 0, 1, 0, 1, 0, 1, 1], + bitvec![$inner_type, Msb0; 0, 1, 0, 1, 0, 1, 1, 0], + bitvec![$inner_type, Msb0; 1, 1, 0, 1, 0, 1, 1, 0, 1], + bitvec![$inner_type, Msb0; 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0], + bitvec![$inner_type, Msb0; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0], + bitvec![$inner_type, Msb0; 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0], + bitvec![$inner_type, Msb0; 0; 15], + bitvec![$inner_type, Msb0; 1; 16], + bitvec![$inner_type, Msb0; 0; 17], + bitvec![$inner_type, Msb0; 1; 31], + bitvec![$inner_type, Msb0; 0; 32], + bitvec![$inner_type, Msb0; 1; 33], + bitvec![$inner_type, Msb0; 0; 63], + bitvec![$inner_type, Msb0; 1; 64], + bitvec![$inner_type, Msb0; 0; 65], + bitvec![$inner_type, Msb0; 1; MAX_PREALLOCATION * 8 + 1], + bitvec![$inner_type, Msb0; 0; MAX_PREALLOCATION * 9], + bitvec![$inner_type, Msb0; 1; MAX_PREALLOCATION * 32 + 1], + bitvec![$inner_type, Msb0; 0; MAX_PREALLOCATION * 33], ] ) } - #[test] - fn required_items_test() { - assert_eq!(Ok(0), required_elements::(0)); - assert_eq!(Ok(1), required_elements::(1)); - assert_eq!(Ok(1), required_elements::(7)); - assert_eq!(Ok(1), required_elements::(8)); - assert_eq!(Ok(2), required_elements::(9)); - - assert_eq!(Ok(0), required_elements::(0)); - assert_eq!(Ok(1), required_elements::(1)); - assert_eq!(Ok(1), required_elements::(15)); - assert_eq!(Ok(1), required_elements::(16)); - assert_eq!(Ok(2), required_elements::(17)); - - assert_eq!(Ok(0), required_elements::(0)); - assert_eq!(Ok(1), required_elements::(1)); - assert_eq!(Ok(1), required_elements::(31)); - assert_eq!(Ok(1), required_elements::(32)); - assert_eq!(Ok(2), required_elements::(33)); - - assert_eq!(Ok(0), required_elements::(0)); - assert_eq!(Ok(1), required_elements::(1)); - assert_eq!(Ok(1), required_elements::(63)); - assert_eq!(Ok(1), required_elements::(64)); - assert_eq!(Ok(2), required_elements::(65)); - } - #[test] fn bitvec_u8() { for v in &test_data!(u8) { let encoded = v.encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + + let encoded = v.as_bitslice().encode(); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); } } #[test] - // Flaky test due to: - // * https://github.com/bitvecto-rs/bitvec/issues/135 - // * https://github.com/rust-lang/miri/issues/1866 - #[cfg(not(miri))] - fn bitvec_u16() { for v in &test_data!(u16) { let encoded = v.encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + + let encoded = v.as_bitslice().encode(); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); } } #[test] - // Flaky test due to: - // * https://github.com/bitvecto-rs/bitvec/issues/135 - // * https://github.com/rust-lang/miri/issues/1866 - #[cfg(not(miri))] fn bitvec_u32() { for v in &test_data!(u32) { let encoded = v.encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + + let encoded = v.as_bitslice().encode(); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); } } #[test] - // Flaky test due to: - // * https://github.com/bitvecto-rs/bitvec/issues/135 - // * https://github.com/rust-lang/miri/issues/1866 - #[cfg(not(miri))] - fn bitvec_u64() { for v in &test_data!(u64) { let encoded = v.encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); } } #[test] fn bitslice() { let data: &[u8] = &[0x69]; - let slice = BitSlice::::from_slice(data).unwrap(); + let slice = BitSlice::::from_slice(data); let encoded = slice.encode(); - let decoded = BitVec::::decode(&mut &encoded[..]).unwrap(); + let decoded = BitVec::::decode(&mut &encoded[..]).unwrap(); assert_eq!(slice, decoded.as_bitslice()); } #[test] - // Flaky test due to: - // * https://github.com/bitvecto-rs/bitvec/issues/135 - // * https://github.com/rust-lang/miri/issues/1866 - #[cfg(not(miri))] fn bitbox() { let data: &[u8] = &[5, 10]; - let slice = BitSlice::::from_slice(data).unwrap(); - let bb = BitBox::::from_bitslice(slice); + let slice = BitSlice::::from_slice(data); + let bb = BitBox::::from_bitslice(slice); let encoded = bb.encode(); - let decoded = BitBox::::decode(&mut &encoded[..]).unwrap(); + let decoded = BitBox::::decode(&mut &encoded[..]).unwrap(); assert_eq!(bb, decoded); } } From 0841cc48bc14d2573cb7a8de8b2d342db362ee62 Mon Sep 17 00:00:00 2001 From: wigy <1888808+wigy-opensource-developer@users.noreply.github.com> Date: Thu, 3 Feb 2022 16:14:12 +0100 Subject: [PATCH 073/286] BREAKING CHANGE: DecodeLimit and DecodeAll extensions now advance input (#314) * BREAKING CHANGE: DecodeLimit and DecodeAll extensions now properly advance input * Prepare for release 3.0.0 * This repo uses hard tabs --- CHANGELOG.md | 16 +++++++++- Cargo.lock | 4 +-- Cargo.toml | 11 +++---- derive/Cargo.toml | 2 +- rustfmt.toml | 23 +++++++++++++ src/decode_all.rs | 25 +++++++-------- src/depth_limit.rs | 80 ++++++++++++++++++++++------------------------ 7 files changed, 94 insertions(+), 67 deletions(-) create mode 100644 rustfmt.toml diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d90fcda..f262e804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,21 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## [3.0.0] - 2022-02-02 + +### Fix + +- Optimised the Decode::decode for [T; N] [#299](https://github.com/paritytech/parity-scale-codec/pull/299) + +### Changed + - Migrated to 2021 edition, enforcing MSRV of `1.56.1`. [#298](https://github.com/paritytech/parity-scale-codec/pull/298) +- Upgrade to BitVec 1.0 [#311](https://github.com/paritytech/parity-scale-codec/pull/311) +- DecodeLimit and DecodeAll extensions now advance input [#314](https://github.com/paritytech/parity-scale-codec/pull/314) + +### Added + +- Add bytes::Bytes implementation [#309](https://github.com/paritytech/parity-scale-codec/pull/309) ## [2.3.1] - 2021-09-28 @@ -17,6 +30,7 @@ and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h ## [2.3.0] - 2021-09-11 ### Added + - `decode_and_advance_with_depth_limit` to the `DecodeLimit` trait. This allows advancing the cursor while decoding the input. PR #286 ## [2.2.0] - 2021-07-02 diff --git a/Cargo.lock b/Cargo.lock index 88585619..c57526f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -423,7 +423,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "2.3.1" +version = "3.0.0" dependencies = [ "arbitrary", "arrayvec", @@ -443,7 +443,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "2.3.1" +version = "3.0.0" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index c5670890..fc47222c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "2.3.1" +version = "3.0.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,8 +12,8 @@ rust-version = "1.56.1" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "2.3.1", default-features = false, optional = true } -bitvec = { version = "1", default-features = false, features = ["alloc"], optional = true } +parity-scale-codec-derive = { path = "derive", version = "3.0.0", default-features = false, optional = true } +bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } @@ -59,7 +59,4 @@ chain-error = [] full = [] [workspace] -members = [ - "derive", - "fuzzer", -] +members = ["derive", "fuzzer"] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 0d312ad6..24316e25 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "2.3.1" +version = "3.0.0" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..441913f6 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,23 @@ +# Basic +hard_tabs = true +max_width = 100 +use_small_heuristics = "Max" +# Imports +imports_granularity = "Crate" +reorder_imports = true +# Consistency +newline_style = "Unix" +# Format comments +comment_width = 100 +wrap_comments = true +# Misc +chain_width = 80 +spaces_around_ranges = false +binop_separator = "Back" +reorder_impl_items = false +match_arm_leading_pipes = "Preserve" +match_arm_blocks = false +match_block_trailing_comma = true +trailing_comma = "Vertical" +trailing_semicolon = false +use_field_init_shorthand = true diff --git a/src/decode_all.rs b/src/decode_all.rs index 64f8df6d..fb29c66c 100644 --- a/src/decode_all.rs +++ b/src/decode_all.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Error, Decode}; +use crate::{Decode, Error}; /// The error message returned when `decode_all` fails. pub(crate) const DECODE_ALL_ERR_MSG: &str = "Input buffer has still data left after decoding!"; @@ -23,12 +23,11 @@ pub trait DecodeAll: Sized { /// Decode `Self` and consume all of the given input data. /// /// If not all data is consumed, an error is returned. - fn decode_all(input: &[u8]) -> Result; + fn decode_all(input: &mut &[u8]) -> Result; } impl DecodeAll for T { - fn decode_all(input: &[u8]) -> Result { - let input = &mut &input[..]; + fn decode_all(input: &mut &[u8]) -> Result { let res = T::decode(input)?; if input.is_empty() { @@ -42,7 +41,7 @@ impl DecodeAll for T { #[cfg(test)] mod tests { use super::*; - use crate::{Encode, Input, Compact, EncodeLike}; + use crate::{Compact, Encode, EncodeLike, Input}; macro_rules! test_decode_all { ( @@ -51,13 +50,13 @@ mod tests { $( { let mut encoded = <$type as Encode>::encode(&$value); - <$type>::decode_all(&encoded).expect( + <$type>::decode_all(&mut encoded.as_slice()).expect( &format!("`{} => {}` decodes all!", stringify!($type), stringify!($value)), ); encoded.extend(&[1, 2, 3, 4, 5, 6]); assert_eq!( - <$type>::decode_all(&encoded).unwrap_err().to_string(), + <$type>::decode_all(&mut encoded.as_slice()).unwrap_err().to_string(), "Input buffer has still data left after decoding!", ); } @@ -86,13 +85,11 @@ mod tests { impl Decode for TestStruct { fn decode(input: &mut I) -> Result { - Ok( - Self { - data: Vec::::decode(input)?, - other: u8::decode(input)?, - compact: Compact::::decode(input)?, - } - ) + Ok(Self { + data: Vec::::decode(input)?, + other: u8::decode(input)?, + compact: Compact::::decode(input)?, + }) } } diff --git a/src/depth_limit.rs b/src/depth_limit.rs index 7a6ec356..2af17843 100644 --- a/src/depth_limit.rs +++ b/src/depth_limit.rs @@ -12,37 +12,32 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Error, Decode, Input}; +use crate::{Decode, Error, Input}; /// The error message returned when depth limit is reached. const DECODE_MAX_DEPTH_MSG: &str = "Maximum recursion depth reached when decoding"; /// Extension trait to [`Decode`] for decoding with a maximum recursion depth. pub trait DecodeLimit: Sized { - /// Decode `Self` with the given maximum recursion depth. + /// Decode `Self` with the given maximum recursion depth and advance `input` by the number of + /// bytes consumed. /// /// If `limit` is hit, an error is returned. - fn decode_with_depth_limit(limit: u32, input: &[u8]) -> Result; - - /// Decode `Self` and advance `input` by the number of bytes consumed. - /// - /// If `limit` is hit, an error is returned. - fn decode_and_advance_with_depth_limit(limit: u32, input: &mut I) -> Result; + fn decode_with_depth_limit(limit: u32, input: &mut I) -> Result; /// Decode `Self` and consume all of the given input data. /// /// If not all data is consumed or `limit` is hit, an error is returned. - fn decode_all_with_depth_limit(limit: u32, input: &[u8]) -> Result; + fn decode_all_with_depth_limit(limit: u32, input: &mut &[u8]) -> Result; } - struct DepthTrackingInput<'a, I> { input: &'a mut I, depth: u32, max_depth: u32, } -impl<'a, I:Input> Input for DepthTrackingInput<'a, I> { +impl<'a, I: Input> Input for DepthTrackingInput<'a, I> { fn remaining_len(&mut self) -> Result, Error> { self.input.remaining_len() } @@ -72,36 +67,18 @@ impl<'a, I:Input> Input for DepthTrackingInput<'a, I> { } impl DecodeLimit for T { - fn decode_all_with_depth_limit(limit: u32, input: &[u8]) -> Result { - let mut input = DepthTrackingInput { - input: &mut &input[..], - depth: 0, - max_depth: limit, - }; - let res = T::decode(&mut input)?; - - if input.input.is_empty() { - Ok(res) + fn decode_all_with_depth_limit(limit: u32, input: &mut &[u8]) -> Result { + let t = ::decode_with_depth_limit(limit, input)?; + + if input.is_empty() { + Ok(t) } else { Err(crate::decode_all::DECODE_ALL_ERR_MSG.into()) } } - fn decode_and_advance_with_depth_limit(limit: u32, input: &mut I) -> Result { - let mut input = DepthTrackingInput { - input, - depth: 0, - max_depth: limit, - }; - T::decode(&mut input) - } - - fn decode_with_depth_limit(limit: u32, input: &[u8]) -> Result { - let mut input = DepthTrackingInput { - input: &mut &input[..], - depth: 0, - max_depth: limit, - }; + fn decode_with_depth_limit(limit: u32, input: &mut I) -> Result { + let mut input = DepthTrackingInput { input, depth: 0, max_depth: limit }; T::decode(&mut input) } } @@ -117,19 +94,38 @@ mod tests { let nested: NestedVec = vec![vec![vec![vec![1]]]]; let encoded = nested.encode(); - let decoded = NestedVec::decode_with_depth_limit(3, &encoded).unwrap(); + let decoded = NestedVec::decode_with_depth_limit(3, &mut encoded.as_slice()).unwrap(); assert_eq!(decoded, nested); - assert!(NestedVec::decode_with_depth_limit(2, &encoded).is_err()); + assert!(NestedVec::decode_with_depth_limit(2, &mut encoded.as_slice()).is_err()); } #[test] - fn decode_and_advance_works() { + fn decode_limit_advances_input() { type NestedVec = Vec>>>; let nested: NestedVec = vec![vec![vec![vec![1]]]]; - let encoded = &mut &nested.encode()[..]; + let encoded = nested.encode(); + let encoded_slice = &mut encoded.as_slice(); - let decoded = Vec::::decode_and_advance_with_depth_limit(1, encoded).unwrap(); + let decoded = Vec::::decode_with_depth_limit(1, encoded_slice).unwrap(); assert_eq!(decoded, vec![4]); - assert!(NestedVec::decode_with_depth_limit(3, encoded).is_err()); + assert!(NestedVec::decode_with_depth_limit(3, encoded_slice).is_err()); + } + + #[test] + fn decode_all_with_limit_advances_input() { + type NestedVec = Vec>>>; + let nested: NestedVec = vec![vec![vec![vec![1]]]]; + let mut encoded = NestedVec::encode(&nested); + + let decoded = NestedVec::decode_all_with_depth_limit(3, &mut encoded.as_slice()).unwrap(); + assert_eq!(decoded, nested); + + encoded.extend(&[1, 2, 3, 4, 5, 6]); + assert_eq!( + NestedVec::decode_all_with_depth_limit(3, &mut encoded.as_slice()) + .unwrap_err() + .to_string(), + "Input buffer has still data left after decoding!", + ); } } From a9895984af2798931231a104ff670d0485f79e7c Mon Sep 17 00:00:00 2001 From: Andre Nathan Date: Sat, 12 Feb 2022 03:24:44 -0300 Subject: [PATCH 074/286] Make `CompactRef` public (#320) (#321) --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index aaa5ac77..f7bfec70 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -291,7 +291,7 @@ pub use self::codec::{ }; #[cfg(feature = "std")] pub use self::codec::IoReader; -pub use self::compact::{Compact, HasCompact, CompactAs, CompactLen}; +pub use self::compact::{Compact, HasCompact, CompactAs, CompactLen, CompactRef}; pub use self::joiner::Joiner; pub use self::keyedvec::KeyedVec; pub use self::decode_all::DecodeAll; From 4413e9ad4578e5bafcbf49ac5f481cb3ffc5ed96 Mon Sep 17 00:00:00 2001 From: Sergejs Kostjucenko <85877331+sergejparity@users.noreply.github.com> Date: Wed, 16 Feb 2022 12:38:22 +0200 Subject: [PATCH 075/286] Move CI script to new location (#318) --- .gitlab-ci.yml | 2 +- scripts/{ => ci}/pre_cache.sh | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename scripts/{ => ci}/pre_cache.sh (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b21a2742..79158c51 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,7 +25,7 @@ workflow: - rustc -vV - rustup show - bash --version - - ./scripts/pre_cache.sh + - ./scripts/ci/pre_cache.sh - sccache -s rules: - if: $CI_PIPELINE_SOURCE == "trigger" diff --git a/scripts/pre_cache.sh b/scripts/ci/pre_cache.sh similarity index 100% rename from scripts/pre_cache.sh rename to scripts/ci/pre_cache.sh From 6f1346623d9e90292b791ed43eab0d87b178bea6 Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Tue, 1 Mar 2022 14:36:52 +0100 Subject: [PATCH 076/286] [ci] Change image to ci-linux:production with clang13 (#326) * [ci] Change image to ci-linux:production with clang13 * add miri * test image * change image --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 79158c51..23fd8ed2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,8 @@ workflow: - if: $CI_COMMIT_BRANCH .docker-env: &docker-env - image: paritytech/ink-ci-linux:production + # Temporary image, remove when clang in "ink-ci-linux:production" is updated to 13 + image: paritytech/parity-scale-codec:staging before_script: - cargo -vV - rustc -vV From b8604116ff68458a8776adf9fcab3c2db606e710 Mon Sep 17 00:00:00 2001 From: Georgy Shepelev Date: Fri, 4 Mar 2022 14:37:09 +0400 Subject: [PATCH 077/286] Add ability to re-export parity-scale-codec crate (#325) * use codec_crate_path for all derivable macros * update README * bump versions * use `codec` attribute in tests * remove redundant call to parse_quote --- Cargo.lock | 4 +- Cargo.toml | 4 +- README.md | 3 + derive/Cargo.toml | 2 +- derive/src/decode.rs | 20 ++--- derive/src/encode.rs | 56 +++++++------- derive/src/lib.rs | 75 ++++++------------- derive/src/trait_bounds.rs | 6 +- derive/src/utils.rs | 2 - .../pass/decode-no-implicit-prelude.rs | 2 + .../pass/encode-no-implicit-prelude.rs | 2 + 11 files changed, 77 insertions(+), 99 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c57526f4..52b3a843 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -423,7 +423,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.0.0" +version = "3.1.0" dependencies = [ "arbitrary", "arrayvec", @@ -443,7 +443,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.0.0" +version = "3.1.0" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index fc47222c..6818846f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.0.0" +version = "3.1.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.56.1" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "3.0.0", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "3.1.0", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } diff --git a/README.md b/README.md index 0c81fc26..66877b25 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,9 @@ The derive implementation supports the following attributes: - `codec(index = 0)`: Needs to be placed above an enum variant to make the variant use the given index when encoded. By default the index is determined by counting from `0` beginning wth the first variant. +- `codec(crate = path::to::crate)`: Specify a path to the parity-scale-codec crate instance to use + when referring to Codec APIs from generated code. This is normally only applicable when invoking + re-exported Codec derives from a public macro in a different crate. License: Apache-2.0 diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 24316e25..e5d9d9cf 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.0.0" +version = "3.1.0" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" diff --git a/derive/src/decode.rs b/derive/src/decode.rs index 75c4b74e..df603902 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -31,7 +31,7 @@ pub fn quote( type_name: &Ident, type_generics: &TokenStream, input: &TokenStream, - crate_ident: &TokenStream, + crate_path: &syn::Path, ) -> TokenStream { match *data { Data::Struct(ref data) => match data.fields { @@ -40,7 +40,7 @@ pub fn quote( &type_name.to_string(), input, &data.fields, - crate_ident, + crate_path, ), Fields::Unit => { quote_spanned! { data.fields.span() => @@ -67,7 +67,7 @@ pub fn quote( &format!("{}::{}", type_name, name), input, &v.fields, - crate_ident, + crate_path, ); quote_spanned! { v.span() => @@ -101,7 +101,7 @@ pub fn quote( } } -fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_ident: &TokenStream) -> TokenStream { +fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_path: &syn::Path) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); let compact = utils::is_compact(field); let skip = utils::should_skip(&field.attrs); @@ -122,7 +122,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_iden quote_spanned! { field.span() => { let #res = < - <#field_type as #crate_ident::HasCompact>::Type as #crate_ident::Decode + <#field_type as #crate_path::HasCompact>::Type as #crate_path::Decode >::decode(#input); match #res { ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), @@ -133,7 +133,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_iden } else if let Some(encoded_as) = encoded_as { quote_spanned! { field.span() => { - let #res = <#encoded_as as #crate_ident::Decode>::decode(#input); + let #res = <#encoded_as as #crate_path::Decode>::decode(#input); match #res { ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), ::core::result::Result::Ok(#res) => #res.into(), @@ -146,7 +146,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_iden let field_type = &field.ty; quote_spanned! { field.span() => { - let #res = <#field_type as #crate_ident::Decode>::decode(#input); + let #res = <#field_type as #crate_path::Decode>::decode(#input); match #res { ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), ::core::result::Result::Ok(#res) => #res, @@ -161,7 +161,7 @@ fn create_instance( name_str: &str, input: &TokenStream, fields: &Fields, - crate_ident: &TokenStream, + crate_path: &syn::Path, ) -> TokenStream { match *fields { Fields::Named(ref fields) => { @@ -171,7 +171,7 @@ fn create_instance( Some(a) => format!("{}::{}", name_str, a), None => format!("{}", name_str), // Should never happen, fields are named. }; - let decode = create_decode_expr(f, &field_name, input, crate_ident); + let decode = create_decode_expr(f, &field_name, input, crate_path); quote_spanned! { f.span() => #name_ident: #decode @@ -188,7 +188,7 @@ fn create_instance( let recurse = fields.unnamed.iter().enumerate().map(|(i, f) | { let field_name = format!("{}.{}", name_str, i); - create_decode_expr(f, &field_name, input, crate_ident) + create_decode_expr(f, &field_name, input, crate_path) }); quote_spanned! { fields.span() => diff --git a/derive/src/encode.rs b/derive/src/encode.rs index 3e385182..b2badc17 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -30,7 +30,7 @@ type FieldsList = Punctuated; fn encode_single_field( field: &Field, field_name: TokenStream, - crate_ident: &TokenStream, + crate_path: &syn::Path, ) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); let compact = utils::is_compact(field); @@ -53,8 +53,8 @@ fn encode_single_field( let field_type = &field.ty; quote_spanned! { field.span() => { - <<#field_type as #crate_ident::HasCompact>::Type as - #crate_ident::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) + <<#field_type as #crate_path::HasCompact>::Type as + #crate_path::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) } } } else if let Some(encoded_as) = encoded_as { @@ -62,7 +62,7 @@ fn encode_single_field( quote_spanned! { field.span() => { <#encoded_as as - #crate_ident::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) + #crate_path::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) } } } else { @@ -75,19 +75,19 @@ fn encode_single_field( let i_self = quote! { self }; quote_spanned! { field.span() => - fn encode_to<__CodecOutputEdqy: #crate_ident::Output + ?::core::marker::Sized>( + fn encode_to<__CodecOutputEdqy: #crate_path::Output + ?::core::marker::Sized>( &#i_self, __codec_dest_edqy: &mut __CodecOutputEdqy ) { - #crate_ident::Encode::encode_to(&#final_field_variable, __codec_dest_edqy) + #crate_path::Encode::encode_to(&#final_field_variable, __codec_dest_edqy) } - fn encode(&#i_self) -> #crate_ident::alloc::vec::Vec<::core::primitive::u8> { - #crate_ident::Encode::encode(&#final_field_variable) + fn encode(&#i_self) -> #crate_path::alloc::vec::Vec<::core::primitive::u8> { + #crate_path::Encode::encode(&#final_field_variable) } fn using_encoded R>(&#i_self, f: F) -> R { - #crate_ident::Encode::using_encoded(&#final_field_variable, f) + #crate_path::Encode::using_encoded(&#final_field_variable, f) } } } @@ -96,7 +96,7 @@ fn encode_fields( dest: &TokenStream, fields: &FieldsList, field_name: F, - crate_ident: &TokenStream, + crate_path: &syn::Path, ) -> TokenStream where F: Fn(usize, &Option) -> TokenStream, { @@ -119,10 +119,10 @@ fn encode_fields( let field_type = &f.ty; quote_spanned! { f.span() => { - #crate_ident::Encode::encode_to( + #crate_path::Encode::encode_to( &< - <#field_type as #crate_ident::HasCompact>::Type as - #crate_ident::EncodeAsRef<'_, #field_type> + <#field_type as #crate_path::HasCompact>::Type as + #crate_path::EncodeAsRef<'_, #field_type> >::RefType::from(#field), #dest, ); @@ -132,10 +132,10 @@ fn encode_fields( let field_type = &f.ty; quote_spanned! { f.span() => { - #crate_ident::Encode::encode_to( + #crate_path::Encode::encode_to( &< #encoded_as as - #crate_ident::EncodeAsRef<'_, #field_type> + #crate_path::EncodeAsRef<'_, #field_type> >::RefType::from(#field), #dest, ); @@ -147,7 +147,7 @@ fn encode_fields( } } else { quote_spanned! { f.span() => - #crate_ident::Encode::encode_to(#field, #dest); + #crate_path::Encode::encode_to(#field, #dest); } } }); @@ -157,7 +157,7 @@ fn encode_fields( } } -fn try_impl_encode_single_field_optimisation(data: &Data, crate_ident: &TokenStream) -> Option { +fn try_impl_encode_single_field_optimisation(data: &Data, crate_path: &syn::Path) -> Option { match *data { Data::Struct(ref data) => { match data.fields { @@ -167,7 +167,7 @@ fn try_impl_encode_single_field_optimisation(data: &Data, crate_ident: &TokenStr Some(encode_single_field( field, quote!(&self.#name), - crate_ident, + crate_path, )) }, Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => { @@ -177,7 +177,7 @@ fn try_impl_encode_single_field_optimisation(data: &Data, crate_ident: &TokenStr Some(encode_single_field( field, quote!(&self.#id), - crate_ident, + crate_path, )) }, _ => None, @@ -187,7 +187,7 @@ fn try_impl_encode_single_field_optimisation(data: &Data, crate_ident: &TokenStr } } -fn impl_encode(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> TokenStream { +fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenStream { let self_ = quote!(self); let dest = "e!(__codec_dest_edqy); let encoding = match *data { @@ -197,7 +197,7 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> Tok dest, &fields.named, |_, name| quote!(&#self_.#name), - crate_ident, + crate_path, ), Fields::Unnamed(ref fields) => encode_fields( dest, @@ -206,7 +206,7 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> Tok let i = syn::Index::from(i); quote!(&#self_.#i) }, - crate_ident, + crate_path, ), Fields::Unit => quote!(), } @@ -242,7 +242,7 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> Tok dest, &fields.named, |a, b| field_name(a, b), - crate_ident, + crate_path, ); quote_spanned! { f.span() => @@ -268,7 +268,7 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> Tok dest, &fields.unnamed, |a, b| field_name(a, b), - crate_ident, + crate_path, ); quote_spanned! { f.span() => @@ -301,7 +301,7 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> Tok ).to_compile_error(), }; quote! { - fn encode_to<__CodecOutputEdqy: #crate_ident::Output + ?::core::marker::Sized>( + fn encode_to<__CodecOutputEdqy: #crate_path::Output + ?::core::marker::Sized>( &#self_, #dest: &mut __CodecOutputEdqy ) { @@ -310,11 +310,11 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> Tok } } -pub fn quote(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> TokenStream { - if let Some(implementation) = try_impl_encode_single_field_optimisation(data, crate_ident) { +pub fn quote(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenStream { + if let Some(implementation) = try_impl_encode_single_field_optimisation(data, crate_path) { implementation } else { - impl_encode(data, type_name, crate_ident) + impl_encode(data, type_name, crate_path) } } diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 38248929..0bb297b2 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -23,12 +23,9 @@ extern crate syn; #[macro_use] extern crate quote; -use proc_macro2::{Ident, Span}; -use proc_macro_crate::{crate_name, FoundCrate}; use syn::spanned::Spanned; use syn::{Data, Field, Fields, DeriveInput, Error}; -use proc_macro2::TokenStream as TokenStream2; -use crate::utils::is_lint_attribute; +use crate::utils::{codec_crate_path, is_lint_attribute}; mod decode; mod encode; @@ -36,30 +33,6 @@ mod max_encoded_len; mod utils; mod trait_bounds; -/// Returns the identifier of the `parity-scale-codec` crate as used. -/// -/// The identifier might change if the depending crate imported it -/// using a custom package name. -fn parity_scale_codec_ident() -> Result { - static CRATE_NAME: &str = "parity-scale-codec"; - fn root_import(name: &str) -> TokenStream2 { - let ident = Ident::new(name, Span::call_site()); - quote!{ :: #ident } - } - // This "hack" is required for the tests. - if std::env::var("CARGO_PKG_NAME").unwrap() == CRATE_NAME { - Ok(root_import("parity_scale_codec")) - } else { - match crate_name(CRATE_NAME) { - Ok(FoundCrate::Itself) => { - Ok(quote! { crate }) - } - Ok(FoundCrate::Name(custom_name)) => Ok(root_import(&custom_name)), - Err(e) => Err(Error::new(Span::call_site(), &e)), - } - } -} - /// Wraps the impl block in a "dummy const" fn wrap_with_dummy_const(input: DeriveInput, impl_block: proc_macro2::TokenStream) -> proc_macro::TokenStream { let attrs = input.attrs.into_iter().filter(is_lint_attribute); @@ -156,8 +129,8 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream return e.to_compile_error().into(); } - let crate_ident = match crate::parity_scale_codec_ident() { - Ok(crate_ident) => crate_ident, + let crate_path = match codec_crate_path(&input.attrs) { + Ok(crate_path) => crate_path, Err(error) => { return error.into_compile_error().into() } @@ -169,10 +142,10 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream &input.ident, &mut input.generics, &input.data, - parse_quote!(#crate_ident::Encode), + parse_quote!(#crate_path::Encode), None, utils::has_dumb_trait_bound(&input.attrs), - &crate_ident, + &crate_path, ) { return e.to_compile_error().into(); } @@ -180,14 +153,14 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let name = &input.ident; let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - let encode_impl = encode::quote(&input.data, name, &crate_ident); + let encode_impl = encode::quote(&input.data, name, &crate_path); let impl_block = quote! { - impl #impl_generics #crate_ident::Encode for #name #ty_generics #where_clause { + impl #impl_generics #crate_path::Encode for #name #ty_generics #where_clause { #encode_impl } - impl #impl_generics #crate_ident::EncodeLike for #name #ty_generics #where_clause {} + impl #impl_generics #crate_path::EncodeLike for #name #ty_generics #where_clause {} }; wrap_with_dummy_const(input, impl_block) @@ -207,8 +180,8 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream return e.to_compile_error().into(); } - let crate_ident = match crate::parity_scale_codec_ident() { - Ok(crate_ident) => crate_ident, + let crate_path = match codec_crate_path(&input.attrs) { + Ok(crate_path) => crate_path, Err(error) => { return error.into_compile_error().into() } @@ -220,10 +193,10 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream &input.ident, &mut input.generics, &input.data, - parse_quote!(#crate_ident::Decode), + parse_quote!(#crate_path::Decode), Some(parse_quote!(Default)), utils::has_dumb_trait_bound(&input.attrs), - &crate_ident, + &crate_path, ) { return e.to_compile_error().into(); } @@ -233,13 +206,13 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let ty_gen_turbofish = ty_generics.as_turbofish(); let input_ = quote!(__codec_input_edqy); - let decoding = decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_, &crate_ident); + let decoding = decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_, &crate_path); let impl_block = quote! { - impl #impl_generics #crate_ident::Decode for #name #ty_generics #where_clause { - fn decode<__CodecInputEdqy: #crate_ident::Input>( + impl #impl_generics #crate_path::Decode for #name #ty_generics #where_clause { + fn decode<__CodecInputEdqy: #crate_path::Input>( #input_: &mut __CodecInputEdqy - ) -> ::core::result::Result { + ) -> ::core::result::Result { #decoding } } @@ -273,8 +246,8 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr return e.to_compile_error().into(); } - let crate_ident = match crate::parity_scale_codec_ident() { - Ok(crate_ident) => crate_ident, + let crate_path = match codec_crate_path(&input.attrs) { + Ok(crate_path) => crate_path, Err(error) => { return error.into_compile_error().into() } @@ -284,10 +257,10 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr &input.ident, &mut input.generics, &input.data, - parse_quote!(#crate_ident::CompactAs), + parse_quote!(#crate_path::CompactAs), None, utils::has_dumb_trait_bound(&input.attrs), - &crate_ident, + &crate_path, ) { return e.to_compile_error().into(); } @@ -343,22 +316,22 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr }; let impl_block = quote! { - impl #impl_generics #crate_ident::CompactAs for #name #ty_generics #where_clause { + impl #impl_generics #crate_path::CompactAs for #name #ty_generics #where_clause { type As = #inner_ty; fn encode_as(&self) -> &#inner_ty { #inner_field } fn decode_from(x: #inner_ty) - -> ::core::result::Result<#name #ty_generics, #crate_ident::Error> + -> ::core::result::Result<#name #ty_generics, #crate_path::Error> { ::core::result::Result::Ok(#constructor) } } - impl #impl_generics From<#crate_ident::Compact<#name #ty_generics>> + impl #impl_generics From<#crate_path::Compact<#name #ty_generics>> for #name #ty_generics #where_clause { - fn from(x: #crate_ident::Compact<#name #ty_generics>) -> #name #ty_generics { + fn from(x: #crate_path::Compact<#name #ty_generics>) -> #name #ty_generics { x.0 } } diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index a2361df7..8d81d7c9 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -14,7 +14,7 @@ use std::iter; -use proc_macro2::{Ident, TokenStream}; +use proc_macro2::Ident; use syn::{ spanned::Spanned, visit::{self, Visit}, @@ -112,7 +112,7 @@ pub fn add( codec_bound: syn::Path, codec_skip_bound: Option, dumb_trait_bounds: bool, - crate_ident: &TokenStream, + crate_path: &syn::Path, ) -> Result<()> { let ty_params = generics.type_params().map(|p| p.ident.clone()).collect::>(); if ty_params.is_empty() { @@ -147,7 +147,7 @@ pub fn add( where_clause.predicates.push(parse_quote!(#ty : #codec_bound)) }); - let has_compact_bound: syn::Path = parse_quote!(#crate_ident::HasCompact); + let has_compact_bound: syn::Path = parse_quote!(#crate_path::HasCompact); compact_types .into_iter() .for_each(|ty| { diff --git a/derive/src/utils.rs b/derive/src/utils.rs index 42c1e130..f59fcbbb 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -121,7 +121,6 @@ pub fn has_dumb_trait_bound(attrs: &[Attribute]) -> bool { } /// Generate the crate access for the crate using 2018 syntax. -#[cfg(feature = "max-encoded-len")] fn crate_access() -> syn::Result { use proc_macro_crate::{crate_name, FoundCrate}; use proc_macro2::{Span, Ident}; @@ -173,7 +172,6 @@ fn codec_crate_path_inner(attr: &Attribute) -> Option { /// If not found, returns the default crate access pattern. /// /// If multiple items match the pattern, all but the first are ignored. -#[cfg(feature = "max-encoded-len")] pub fn codec_crate_path(attrs: &[Attribute]) -> syn::Result { match attrs.iter().find_map(codec_crate_path_inner) { Some(path) => Ok(path), diff --git a/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs b/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs index 6ee5e622..69f01440 100644 --- a/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs +++ b/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs @@ -1,6 +1,7 @@ #![no_implicit_prelude] #[derive(::parity_scale_codec::Decode)] +#[codec(crate = ::parity_scale_codec)] pub struct Struct { field_1: i8, field_2: i16, @@ -9,6 +10,7 @@ pub struct Struct { } #[derive(::parity_scale_codec::Decode)] +#[codec(crate = ::parity_scale_codec)] pub enum Enum { Variant1, Variant2(i8, i16, i32, i64), diff --git a/tests/scale_codec_ui/pass/encode-no-implicit-prelude.rs b/tests/scale_codec_ui/pass/encode-no-implicit-prelude.rs index a8f9d2bc..e177d14f 100644 --- a/tests/scale_codec_ui/pass/encode-no-implicit-prelude.rs +++ b/tests/scale_codec_ui/pass/encode-no-implicit-prelude.rs @@ -1,6 +1,7 @@ #![no_implicit_prelude] #[derive(::parity_scale_codec::Encode)] +#[codec(crate = ::parity_scale_codec)] pub struct Struct { field_1: i8, field_2: i16, @@ -9,6 +10,7 @@ pub struct Struct { } #[derive(::parity_scale_codec::Encode)] +#[codec(crate = ::parity_scale_codec)] pub enum Enum { Variant1, Variant2(i8, i16, i32, i64), From 372d6177d8e66cdfe0968c200c8e29fda674bf14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 17 Mar 2022 09:41:29 +0100 Subject: [PATCH 078/286] BitVec: Improve the encoding and consolidate the implementations (#327) * BitVec: Improve the encoding and consolidate the implementations * Bump version * Remove debugging stuff :see_no_evil: * Feature gate the test * More testing * More tests --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/bit_vec.rs | 73 +++++++++++++++++++++++++++----------------------- tests/mod.rs | 34 ++++++++++++++++++++++- 4 files changed, 74 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52b3a843..249e1e83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -423,7 +423,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.1.0" +version = "3.1.1" dependencies = [ "arbitrary", "arrayvec", diff --git a/Cargo.toml b/Cargo.toml index 6818846f..0b12514d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.1.0" +version = "3.1.1" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 3341e158..b57e793b 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -15,17 +15,13 @@ //! `BitVec` specific serialization. use bitvec::{ - vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox, + vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox, view::BitView, }; use crate::{ - EncodeLike, Encode, Decode, Input, Output, Error, Compact, - codec::{decode_vec_with_len, encode_slice_no_len}, + EncodeLike, Encode, Decode, Input, Output, Error, Compact, codec::decode_vec_with_len, }; -impl Encode for BitSlice - where - T::Mem: Encode -{ +impl Encode for BitSlice { fn encode_to(&self, dest: &mut W) { let bits = self.len(); assert!( @@ -34,7 +30,10 @@ impl Encode for BitSlice ); Compact(bits as u32).encode_to(dest); - for element in self.domain() { + // Iterate over chunks + for chunk in self.chunks(core::mem::size_of::() * 8) { + let mut element = T::ZERO; + element.view_bits_mut::()[..chunk.len()].copy_from_bitslice(chunk); element.encode_to(dest); } } @@ -42,15 +41,7 @@ impl Encode for BitSlice impl Encode for BitVec { fn encode_to(&self, dest: &mut W) { - let bits = self.len(); - assert!( - bits <= ARCH32BIT_BITSLICE_MAX_BITS, - "Attempted to encode a BitVec with too many bits.", - ); - Compact(bits as u32).encode_to(dest); - - let slice = self.as_raw_slice(); - encode_slice_no_len(slice, dest) + self.as_bitslice().encode_to(dest) } } @@ -84,15 +75,7 @@ impl Decode for BitVec { impl Encode for BitBox { fn encode_to(&self, dest: &mut W) { - let bits = self.len(); - assert!( - bits <= ARCH32BIT_BITSLICE_MAX_BITS, - "Attempted to encode a BitBox with too many bits.", - ); - Compact(bits as u32).encode_to(dest); - - let slice = self.as_raw_slice(); - encode_slice_no_len(slice, dest) + self.as_bitslice().encode_to(dest) } } @@ -107,8 +90,8 @@ impl Decode for BitBox { #[cfg(test)] mod tests { use super::*; - use bitvec::{bitvec, order::Msb0}; - use crate::codec::MAX_PREALLOCATION; + use bitvec::{bitvec, order::{Msb0, Lsb0}}; + use crate::{codec::MAX_PREALLOCATION, CompactLen}; macro_rules! test_data { ($inner_type:ident) => ( @@ -150,8 +133,9 @@ mod tests { let encoded = v.encode(); assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); - let encoded = v.as_bitslice().encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + let elements = bitvec::mem::elts::(v.len()); + let compact_len = Compact::compact_len(&(v.len() as u32)); + assert_eq!(compact_len + elements, encoded.len(), "{}", v); } } @@ -161,8 +145,9 @@ mod tests { let encoded = v.encode(); assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); - let encoded = v.as_bitslice().encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + let elements = bitvec::mem::elts::(v.len()); + let compact_len = Compact::compact_len(&(v.len() as u32)); + assert_eq!(compact_len + elements * 2, encoded.len(), "{}", v); } } @@ -172,8 +157,9 @@ mod tests { let encoded = v.encode(); assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); - let encoded = v.as_bitslice().encode(); - assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + let elements = bitvec::mem::elts::(v.len()); + let compact_len = Compact::compact_len(&(v.len() as u32)); + assert_eq!(compact_len + elements * 4, encoded.len(), "{}", v); } } @@ -182,6 +168,10 @@ mod tests { for v in &test_data!(u64) { let encoded = v.encode(); assert_eq!(*v, BitVec::::decode(&mut &encoded[..]).unwrap()); + + let elements = bitvec::mem::elts::(v.len()); + let compact_len = Compact::compact_len(&(v.len() as u32)); + assert_eq!(compact_len + elements * 8, encoded.len(), "{}", v); } } @@ -203,4 +193,19 @@ mod tests { let decoded = BitBox::::decode(&mut &encoded[..]).unwrap(); assert_eq!(bb, decoded); } + + #[test] + fn bitvec_u8_encodes_as_expected() { + let cases = vec![ + (bitvec![u8, Lsb0; 0, 0, 1, 1].encode(), (Compact(4u32), 0b00001100u8).encode()), + (bitvec![u8, Lsb0; 0, 1, 1, 1].encode(), (Compact(4u32), 0b00001110u8).encode()), + (bitvec![u8, Lsb0; 1, 1, 1, 1].encode(), (Compact(4u32), 0b00001111u8).encode()), + (bitvec![u8, Lsb0; 1, 1, 1, 1, 1].encode(), (Compact(5u32), 0b00011111u8).encode()), + (bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 0].encode(), (Compact(6u32), 0b00011111u8).encode()), + ]; + + for (idx, (actual, expected)) in cases.into_iter().enumerate() { + assert_eq!(actual, expected, "case at index {} failed; encodings differ", idx); + } + } } diff --git a/tests/mod.rs b/tests/mod.rs index 41bf9466..c694469a 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -15,7 +15,7 @@ #[cfg(not(feature="derive"))] use parity_scale_codec_derive::{Encode, Decode}; use parity_scale_codec::{ - Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error, Output, + Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error, Output, DecodeAll }; use serde_derive::{Serialize, Deserialize}; @@ -586,3 +586,35 @@ fn custom_trait_bound() { Something::::decode(&mut &encoded[..]).unwrap(); } + +#[test] +#[cfg(feature = "bit-vec")] +fn bit_vec_works() { + use bitvec::prelude::*; + + // Try some fancy stuff + let original_vec = bitvec![u8, Msb0; 1; 8]; + let mut original_vec_clone = original_vec.clone(); + original_vec_clone = original_vec_clone.split_off(5); + original_vec_clone.push(true); + original_vec_clone.push(true); + original_vec_clone.push(true); + original_vec_clone.push(true); + original_vec_clone.push(true); + + assert_eq!(original_vec, original_vec_clone); + + #[derive(Decode, Encode, PartialEq, Debug)] + struct MyStruct { + v: BitVec, + x: u8, + } + + let v1 = MyStruct { v: original_vec, x: 42 }.encode(); + let v2 = MyStruct { v: original_vec_clone, x: 42 }.encode(); + assert_eq!(v1, v2); + + let v1 = MyStruct::decode(&mut &v1[..]).unwrap(); + let v2 = MyStruct::decode_all(&mut &v2[..]).unwrap(); + assert_eq!(v1.x, v2.x); +} From 04c7c6e77a881630975fb1f96aa774851a0efdc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 17 Mar 2022 11:05:32 +0100 Subject: [PATCH 079/286] Fix crate access by putting a leading `::` (#328) This was done before as well, but we accidentally lost it while adding support for the `crate = ` attribute. --- derive/src/utils.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/derive/src/utils.rs b/derive/src/utils.rs index f59fcbbb..fa72a8a6 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -143,25 +143,25 @@ struct CratePath { } impl Parse for CratePath { - fn parse(input: syn::parse::ParseStream) -> syn::Result { - Ok(CratePath { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + Ok(CratePath { _crate_token: input.parse()?, _eq_token: input.parse()?, path: input.parse()?, }) - } + } } impl From for Path { - fn from(CratePath { path, ..}: CratePath) -> Self { - path - } + fn from(CratePath { path, ..}: CratePath) -> Self { + path + } } /// Match `#[codec(crate = ...)]` and return the `...` if it is a `Path`. fn codec_crate_path_inner(attr: &Attribute) -> Option { // match `#[codec ...]` - attr.path.is_ident("codec").then(move || { + attr.path.is_ident("codec").then(|| { // match `#[codec(crate = ...)]` and return the `...` attr.parse_args::().map(Into::into).ok() }).flatten() @@ -175,7 +175,7 @@ fn codec_crate_path_inner(attr: &Attribute) -> Option { pub fn codec_crate_path(attrs: &[Attribute]) -> syn::Result { match attrs.iter().find_map(codec_crate_path_inner) { Some(path) => Ok(path), - None => crate_access().map(|ident| ident.into()), + None => crate_access().map(|ident| parse_quote!(::#ident)), } } From 5aab13d31634beb3768d77c6e24f5f879d0ffc14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 17 Mar 2022 11:25:21 +0100 Subject: [PATCH 080/286] Bump versions (#329) --- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0b12514d..7e15dc63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.1.1" +version = "3.1.2" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.56.1" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "3.1.0", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "3.1.2", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index e5d9d9cf..f066eece 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.1.0" +version = "3.1.2" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" From 9a97f2985a83f5a133454f809672f9be1fa7e40e Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Fri, 8 Apr 2022 11:23:39 +0200 Subject: [PATCH 081/286] [ci] change ci image to latest (#332) --- .gitlab-ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 23fd8ed2..b1750096 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,7 +11,6 @@ variables: GIT_DEPTH: "100" CARGO_TARGET_DIR: "/ci-cache/${CI_PROJECT_NAME}/targets/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" CARGO_INCREMENTAL: 0 - CI_SERVER_NAME: "GitLab CI" workflow: rules: @@ -19,8 +18,7 @@ workflow: - if: $CI_COMMIT_BRANCH .docker-env: &docker-env - # Temporary image, remove when clang in "ink-ci-linux:production" is updated to 13 - image: paritytech/parity-scale-codec:staging + image: paritytech/parity-scale-codec:latest before_script: - cargo -vV - rustc -vV From cd63c911f6926807abbc82633ab8f72612dc5adf Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Fri, 8 Apr 2022 14:04:00 +0200 Subject: [PATCH 082/286] fix CI_IMAGE var (#333) --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b1750096..67e90ee6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,6 +11,7 @@ variables: GIT_DEPTH: "100" CARGO_TARGET_DIR: "/ci-cache/${CI_PROJECT_NAME}/targets/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" CARGO_INCREMENTAL: 0 + CI_IMAGE: "paritytech/parity-scale-codec:production" workflow: rules: @@ -18,7 +19,7 @@ workflow: - if: $CI_COMMIT_BRANCH .docker-env: &docker-env - image: paritytech/parity-scale-codec:latest + image: $CI_IMAGE before_script: - cargo -vV - rustc -vV From c16fa8b50d1cececbaa43c08a53f62f0321979f7 Mon Sep 17 00:00:00 2001 From: bear Date: Tue, 19 Apr 2022 04:42:42 +0800 Subject: [PATCH 083/286] No need to use mutable reference (#335) * Little things * Fix ci --- Cargo.lock | 4 ++-- src/codec.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 249e1e83..091dcd7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -423,7 +423,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.1.1" +version = "3.1.2" dependencies = [ "arbitrary", "arrayvec", @@ -443,7 +443,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.0" +version = "3.1.2" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/src/codec.rs b/src/codec.rs index 69696ea6..819ca74d 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -1460,7 +1460,7 @@ mod tests { ); } fn test_encode_length(thing: &T, len: usize) { - assert_eq!(::len(&mut &thing.encode()[..]).unwrap(), len); + assert_eq!(::len(&thing.encode()[..]).unwrap(), len); } #[test] From c20a2985f69cd476c1168e4e56ec1c42ef0401db Mon Sep 17 00:00:00 2001 From: Matheus Cardoso <45436839+Cardosaum@users.noreply.github.com> Date: Fri, 22 Apr 2022 17:33:19 -0300 Subject: [PATCH 084/286] docs(Decode): fix tense in phrase (#336) --- src/codec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codec.rs b/src/codec.rs index 819ca74d..d964e28f 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -290,7 +290,7 @@ pub trait Decode: Sized { /// Attempt to skip the encoded value from input. /// /// The default implementation of this function is just calling [`Decode::decode`]. - /// When possible, an implementation should provided a specialized implementation. + /// When possible, an implementation should provide a specialized implementation. fn skip(input: &mut I) -> Result<(), Error> { Self::decode(input).map(|_| ()) } From d70f8d474bdbcf3c6eaa580ec8983cdab1b4743e Mon Sep 17 00:00:00 2001 From: Koute Date: Wed, 25 May 2022 06:27:41 +0900 Subject: [PATCH 085/286] Support `f32` and `f64` when the `full` feature is enabled (#340) --- src/codec.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index d964e28f..9832ffb2 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -203,6 +203,11 @@ pub enum TypeInfo { I64, U128, I128, + + #[cfg(feature = "full")] + F32, + #[cfg(feature = "full")] + F64, } /// Trait that allows zero-copy write of value-references to slices in LE format. @@ -461,6 +466,11 @@ macro_rules! with_type_info { TypeInfo::U128 => { $macro!(u128 $( $( , $params )* )? ) }, TypeInfo::I128 => { $macro!(i128 $( $( , $params )* )? ) }, TypeInfo::Unknown => { $( $unknown_variant )* }, + + #[cfg(feature = "full")] + TypeInfo::F32 => { $macro!(f32 $( $( , $params )* )? ) }, + #[cfg(feature = "full")] + TypeInfo::F64 => { $macro!(f64 $( $( , $params )* )? ) }, } }; } @@ -720,7 +730,7 @@ pub(crate) fn decode_array(input: &mut I) - }}; ( $ty:ty ) => {{ if cfg!(target_endian = "little") { - let mut array: [$ty; N] = [0; N]; + let mut array: [$ty; N] = [0 as $ty; N]; let bytes = <[$ty] as AsMutByteSlice<$ty>>::as_mut_byte_slice(&mut array[..]); input.read(bytes)?; let ref_typed: &[T; N] = unsafe { mem::transmute(&array) }; @@ -1261,6 +1271,9 @@ macro_rules! impl_one_byte { impl_endians!(u16; U16, u32; U32, u64; U64, u128; U128, i16; I16, i32; I32, i64; I64, i128; I128); impl_one_byte!(u8; U8, i8; I8); +#[cfg(feature = "full")] +impl_endians!(f32; F32, f64; F64); + impl EncodeLike for bool {} impl Encode for bool { @@ -1765,7 +1778,7 @@ mod tests { paste::item! { #[test] fn []() { - let data: [$name; 32] = [123; 32]; + let data: [$name; 32] = [123 as $name; 32]; let encoded = data.encode(); let decoded: [$name; 32] = Decode::decode(&mut &encoded[..]).unwrap(); assert_eq!(decoded, data); @@ -1777,6 +1790,9 @@ mod tests { test_array_encode_and_decode!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128); + #[cfg(feature = "full")] + test_array_encode_and_decode!(f32, f64); + fn test_encoded_size(val: impl Encode) { let length = val.using_encoded(|v| v.len()); From 361a0bf9ae0189d05a8ed388c77f7f820babc6f8 Mon Sep 17 00:00:00 2001 From: Koute Date: Wed, 1 Jun 2022 04:50:01 +0900 Subject: [PATCH 086/286] Add `decode_from_bytes` (#342) * Add `decode_from_bytes` * Bump version to 3.1.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/codec.rs | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 3 ++ 4 files changed, 105 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 091dcd7a..e76b7ab8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -423,7 +423,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.1.2" +version = "3.1.3" dependencies = [ "arbitrary", "arrayvec", diff --git a/Cargo.toml b/Cargo.toml index 7e15dc63..f4f6b084 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.1.2" +version = "3.1.3" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" diff --git a/src/codec.rs b/src/codec.rs index 9832ffb2..a84c713f 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -98,6 +98,15 @@ pub trait Input { /// Ascend to previous structure level when decoding. /// This is called when decoding reference-based type is finished. fn ascend_ref(&mut self) {} + + /// !INTERNAL USE ONLY! + /// + /// Decodes a `bytes::Bytes`. + #[cfg(feature = "bytes")] + #[doc(hidden)] + fn scale_internal_decode_bytes(&mut self) -> Result where Self: Sized { + Vec::::decode(self).map(bytes::Bytes::from) + } } impl<'a> Input for &'a [u8] { @@ -387,9 +396,74 @@ mod feature_wrapper_bytes { impl EncodeLike> for Bytes {} impl EncodeLike for &[u8] {} impl EncodeLike for Vec {} +} + +#[cfg(feature = "bytes")] +struct BytesCursor { + bytes: bytes::Bytes, + position: usize +} + +#[cfg(feature = "bytes")] +impl Input for BytesCursor { + fn remaining_len(&mut self) -> Result, Error> { + Ok(Some(self.bytes.len() - self.position)) + } + + fn read(&mut self, into: &mut [u8]) -> Result<(), Error> { + if into.len() > self.bytes.len() - self.position { + return Err("Not enough data to fill buffer".into()) + } + + into.copy_from_slice(&self.bytes[self.position..self.position + into.len()]); + self.position += into.len(); + Ok(()) + } + + fn scale_internal_decode_bytes(&mut self) -> Result { + let length = >::decode(self)?.0 as usize; + + bytes::Buf::advance(&mut self.bytes, self.position); + self.position = 0; + + if length > self.bytes.len() { + return Err("Not enough data to fill buffer".into()); + } - impl WrapperTypeDecode for Bytes { - type Wrapped = Vec; + Ok(self.bytes.split_to(length)) + } +} + +/// Decodes a given `T` from `Bytes`. +#[cfg(feature = "bytes")] +pub fn decode_from_bytes(bytes: bytes::Bytes) -> Result where T: Decode { + // We could just use implement `Input` for `Bytes` and use `Bytes::split_to` + // to move the cursor, however doing it this way allows us to prevent an + // unnecessary allocation when the `T` which is being deserialized doesn't + // take advantage of the fact that it's being deserialized from `Bytes`. + // + // `Bytes` can be cheaply created from a `Vec`. It is both zero-copy + // *and* zero-allocation. However once you `.clone()` it or call `split_to()` + // an extra one-time allocation is triggered where the `Bytes` changes it's internal + // representation from essentially being a `Box<[u8]>` into being an `Arc>`. + // + // If the `T` is `Bytes` or is a structure which contains `Bytes` in it then + // we don't really care, because this allocation will have to be made anyway. + // + // However, if `T` doesn't contain any `Bytes` then this extra allocation is + // technically unnecessary, and we can avoid it by tracking the position ourselves + // and treating the underlying `Bytes` as a fancy `&[u8]`. + let mut input = BytesCursor { + bytes, + position: 0 + }; + T::decode(&mut input) +} + +#[cfg(feature = "bytes")] +impl Decode for bytes::Bytes { + fn decode(input: &mut I) -> Result { + input.scale_internal_decode_bytes() } } @@ -1472,6 +1546,30 @@ mod tests { bytes::Bytes::decode(&mut &encoded[..]).unwrap(), ); } + + #[cfg(feature = "bytes")] + #[test] + fn bytes_deserialized_from_bytes_is_zero_copy() { + let encoded = bytes::Bytes::from(Encode::encode(&b"hello".to_vec())); + let decoded = decode_from_bytes::(encoded.clone()).unwrap(); + assert_eq!(decoded, &b"hello"[..]); + + // The `slice_ref` will panic if the `decoded` is not a subslice of `encoded`. + assert_eq!(encoded.slice_ref(&decoded), &b"hello"[..]); + } + + #[cfg(feature = "bytes")] + #[test] + fn nested_bytes_deserialized_from_bytes_is_zero_copy() { + let encoded = bytes::Bytes::from(Encode::encode(&Some(b"hello".to_vec()))); + let decoded = decode_from_bytes::>(encoded.clone()).unwrap(); + let decoded = decoded.as_ref().unwrap(); + assert_eq!(decoded, &b"hello"[..]); + + // The `slice_ref` will panic if the `decoded` is not a subslice of `encoded`. + assert_eq!(encoded.slice_ref(&decoded), &b"hello"[..]); + } + fn test_encode_length(thing: &T, len: usize) { assert_eq!(::len(&thing.encode()[..]).unwrap(), len); } diff --git a/src/lib.rs b/src/lib.rs index f7bfec70..d99db496 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -345,3 +345,6 @@ pub use max_encoded_len::MaxEncodedLen; /// ``` #[cfg(all(feature = "derive", feature = "max-encoded-len"))] pub use parity_scale_codec_derive::MaxEncodedLen; + +#[cfg(feature = "bytes")] +pub use self::codec::decode_from_bytes; From 24c485606c890b59d45f2fd6b80e423a7d1985b6 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 2 Jun 2022 16:56:14 +0100 Subject: [PATCH 087/286] Add skip_type_params attribute (#337) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add skip_type_params attribute * Update docs * Fixes * Some code fixups * Uniformly use trait_bound::add * Update derive/src/max_encoded_len.rs Co-authored-by: Bastian Köcher * Fixes Co-authored-by: Bastian Köcher --- derive/src/lib.rs | 131 ++++++++++----------- derive/src/max_encoded_len.rs | 64 ++++------ derive/src/trait_bounds.rs | 120 +++++++++---------- derive/src/utils.rs | 215 +++++++++++++++++++--------------- tests/max_encoded_len.rs | 20 +++- tests/mod.rs | 3 +- 6 files changed, 293 insertions(+), 260 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 0bb297b2..5d6b753f 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -23,18 +23,20 @@ extern crate syn; #[macro_use] extern crate quote; -use syn::spanned::Spanned; -use syn::{Data, Field, Fields, DeriveInput, Error}; use crate::utils::{codec_crate_path, is_lint_attribute}; +use syn::{spanned::Spanned, Data, DeriveInput, Error, Field, Fields}; mod decode; mod encode; mod max_encoded_len; -mod utils; mod trait_bounds; +mod utils; /// Wraps the impl block in a "dummy const" -fn wrap_with_dummy_const(input: DeriveInput, impl_block: proc_macro2::TokenStream) -> proc_macro::TokenStream { +fn wrap_with_dummy_const( + input: DeriveInput, + impl_block: proc_macro2::TokenStream, +) -> proc_macro::TokenStream { let attrs = input.attrs.into_iter().filter(is_lint_attribute); let generated = quote! { const _: () = { @@ -66,8 +68,8 @@ fn wrap_with_dummy_const(input: DeriveInput, impl_block: proc_macro2::TokenStrea /// * `#[codec(compact)]`: the field is encoded in its compact representation i.e. the field must /// implement `parity_scale_codec::HasCompact` and will be encoded as `HasCompact::Type`. /// * `#[codec(encoded_as = "$EncodeAs")]`: the field is encoded as an alternative type. $EncodedAs -/// type must implement `parity_scale_codec::EncodeAsRef<'_, $FieldType>` with $FieldType the -/// type of the field with the attribute. This is intended to be used for types implementing +/// type must implement `parity_scale_codec::EncodeAsRef<'_, $FieldType>` with $FieldType the type +/// of the field with the attribute. This is intended to be used for types implementing /// `HasCompact` as shown in the example. /// /// ``` @@ -75,12 +77,12 @@ fn wrap_with_dummy_const(input: DeriveInput, impl_block: proc_macro2::TokenStrea /// # use parity_scale_codec::{Encode as _, HasCompact}; /// #[derive(Encode)] /// struct StructType { -/// #[codec(skip)] -/// a: u32, -/// #[codec(compact)] -/// b: u32, -/// #[codec(encoded_as = "::Type")] -/// c: u32, +/// #[codec(skip)] +/// a: u32, +/// #[codec(compact)] +/// b: u32, +/// #[codec(encoded_as = "::Type")] +/// c: u32, /// } /// ``` /// @@ -126,28 +128,25 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream }; if let Err(e) = utils::check_attributes(&input) { - return e.to_compile_error().into(); + return e.to_compile_error().into() } let crate_path = match codec_crate_path(&input.attrs) { Ok(crate_path) => crate_path, - Err(error) => { - return error.into_compile_error().into() - } + Err(error) => return error.into_compile_error().into(), }; - if let Some(custom_bound) = utils::custom_encode_trait_bound(&input.attrs) { - input.generics.make_where_clause().predicates.extend(custom_bound); - } else if let Err(e) = trait_bounds::add( + if let Err(e) = trait_bounds::add( &input.ident, &mut input.generics, &input.data, + utils::custom_encode_trait_bound(&input.attrs), parse_quote!(#crate_path::Encode), None, utils::has_dumb_trait_bound(&input.attrs), &crate_path, ) { - return e.to_compile_error().into(); + return e.to_compile_error().into() } let name = &input.ident; @@ -177,28 +176,25 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream }; if let Err(e) = utils::check_attributes(&input) { - return e.to_compile_error().into(); + return e.to_compile_error().into() } let crate_path = match codec_crate_path(&input.attrs) { Ok(crate_path) => crate_path, - Err(error) => { - return error.into_compile_error().into() - } + Err(error) => return error.into_compile_error().into(), }; - if let Some(custom_bound) = utils::custom_decode_trait_bound(&input.attrs) { - input.generics.make_where_clause().predicates.extend(custom_bound); - } else if let Err(e) = trait_bounds::add( + if let Err(e) = trait_bounds::add( &input.ident, &mut input.generics, &input.data, + utils::custom_decode_trait_bound(&input.attrs), parse_quote!(#crate_path::Decode), Some(parse_quote!(Default)), utils::has_dumb_trait_bound(&input.attrs), &crate_path, ) { - return e.to_compile_error().into(); + return e.to_compile_error().into() } let name = &input.ident; @@ -206,7 +202,8 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let ty_gen_turbofish = ty_generics.as_turbofish(); let input_ = quote!(__codec_input_edqy); - let decoding = decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_, &crate_path); + let decoding = + decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_, &crate_path); let impl_block = quote! { impl #impl_generics #crate_path::Decode for #name #ty_generics #where_clause { @@ -243,26 +240,25 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr }; if let Err(e) = utils::check_attributes(&input) { - return e.to_compile_error().into(); + return e.to_compile_error().into() } let crate_path = match codec_crate_path(&input.attrs) { Ok(crate_path) => crate_path, - Err(error) => { - return error.into_compile_error().into() - } + Err(error) => return error.into_compile_error().into(), }; - if let Err(e) = trait_bounds::add( + if let Err(e) = trait_bounds::add::<()>( &input.ident, &mut input.generics, &input.data, + None, parse_quote!(#crate_path::CompactAs), None, utils::has_dumb_trait_bound(&input.attrs), &crate_path, ) { - return e.to_compile_error().into(); + return e.to_compile_error().into() } let name = &input.ident; @@ -278,41 +274,40 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr } let (inner_ty, inner_field, constructor) = match input.data { - Data::Struct(ref data) => { - match data.fields { - Fields::Named(ref fields) if utils::filter_skip_named(fields).count() == 1 => { - let recurse = fields.named.iter().map(|f| { - let name_ident = &f.ident; - let val_or_default = val_or_default(&f); - quote_spanned!(f.span()=> #name_ident: #val_or_default) - }); - let field = utils::filter_skip_named(fields).next().expect("Exactly one field"); - let field_name = &field.ident; - let constructor = quote!( #name { #( #recurse, )* }); - (&field.ty, quote!(&self.#field_name), constructor) - }, - Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => { - let recurse = fields.unnamed.iter().enumerate().map(|(_, f) | { - let val_or_default = val_or_default(&f); - quote_spanned!(f.span()=> #val_or_default) - }); - let (id, field) = utils::filter_skip_unnamed(fields).next().expect("Exactly one field"); - let id = syn::Index::from(id); - let constructor = quote!( #name(#( #recurse, )*)); - (&field.ty, quote!(&self.#id), constructor) - }, - _ => { - return Error::new( - data.fields.span(), - "Only structs with a single non-skipped field can derive CompactAs" - ).to_compile_error().into(); - }, - } + Data::Struct(ref data) => match data.fields { + Fields::Named(ref fields) if utils::filter_skip_named(fields).count() == 1 => { + let recurse = fields.named.iter().map(|f| { + let name_ident = &f.ident; + let val_or_default = val_or_default(&f); + quote_spanned!(f.span()=> #name_ident: #val_or_default) + }); + let field = utils::filter_skip_named(fields).next().expect("Exactly one field"); + let field_name = &field.ident; + let constructor = quote!( #name { #( #recurse, )* }); + (&field.ty, quote!(&self.#field_name), constructor) + }, + Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => { + let recurse = fields.unnamed.iter().enumerate().map(|(_, f)| { + let val_or_default = val_or_default(&f); + quote_spanned!(f.span()=> #val_or_default) + }); + let (id, field) = + utils::filter_skip_unnamed(fields).next().expect("Exactly one field"); + let id = syn::Index::from(id); + let constructor = quote!( #name(#( #recurse, )*)); + (&field.ty, quote!(&self.#id), constructor) + }, + _ => + return Error::new( + data.fields.span(), + "Only structs with a single non-skipped field can derive CompactAs", + ) + .to_compile_error() + .into(), }, Data::Enum(syn::DataEnum { enum_token: syn::token::Enum { span }, .. }) | - Data::Union(syn::DataUnion { union_token: syn::token::Union { span }, .. }) => { - return Error::new(span, "Only structs can derive CompactAs").to_compile_error().into(); - }, + Data::Union(syn::DataUnion { union_token: syn::token::Union { span }, .. }) => + return Error::new(span, "Only structs can derive CompactAs").to_compile_error().into(), }; let impl_block = quote! { diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index 35b9fedf..c55d3167 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -15,38 +15,45 @@ #![cfg(feature = "max-encoded-len")] -use crate::utils::{self, codec_crate_path, custom_mel_trait_bound}; -use quote::{quote, quote_spanned}; -use syn::{ - Data, DeriveInput, Fields, GenericParam, Generics, TraitBound, Type, TypeParamBound, - parse_quote, spanned::Spanned, +use crate::{ + trait_bounds, + utils::{codec_crate_path, custom_mel_trait_bound, has_dumb_trait_bound}, }; +use quote::{quote, quote_spanned}; +use syn::{parse_quote, spanned::Spanned, Data, DeriveInput, Fields, Type}; /// impl for `#[derive(MaxEncodedLen)]` pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input: DeriveInput = match syn::parse(input) { + let mut input: DeriveInput = match syn::parse(input) { Ok(input) => input, Err(e) => return e.to_compile_error().into(), }; - let mel_trait = match max_encoded_len_trait(&input) { - Ok(mel_trait) => mel_trait, - Err(e) => return e.to_compile_error().into(), + let crate_path = match codec_crate_path(&input.attrs) { + Ok(crate_path) => crate_path, + Err(error) => return error.into_compile_error().into(), }; let name = &input.ident; - let generics = if let Some(custom_bound) = custom_mel_trait_bound(&input.attrs) { - add_custom_trait_bounds(input.generics, custom_bound) - } else { - add_trait_bounds(input.generics, mel_trait.clone()) - }; - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + if let Err(e) = trait_bounds::add( + &input.ident, + &mut input.generics, + &input.data, + custom_mel_trait_bound(&input.attrs), + parse_quote!(#crate_path::MaxEncodedLen), + None, + has_dumb_trait_bound(&input.attrs), + &crate_path + ) { + return e.to_compile_error().into() + } + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); let data_expr = data_length_expr(&input.data); quote::quote!( const _: () = { - impl #impl_generics #mel_trait for #name #ty_generics #where_clause { + impl #impl_generics #crate_path::MaxEncodedLen for #name #ty_generics #where_clause { fn max_encoded_len() -> ::core::primitive::usize { #data_expr } @@ -56,27 +63,6 @@ pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::Tok .into() } -fn max_encoded_len_trait(input: &DeriveInput) -> syn::Result { - let mel = codec_crate_path(&input.attrs)?; - Ok(parse_quote!(#mel::MaxEncodedLen)) -} - -// Add a bound `T: MaxEncodedLen` to every type parameter T. -fn add_trait_bounds(mut generics: Generics, mel_trait: TraitBound) -> Generics { - for param in &mut generics.params { - if let GenericParam::Type(ref mut type_param) = *param { - type_param.bounds.push(TypeParamBound::Trait(mel_trait.clone())); - } - } - generics -} - -// Add custom trait bounds to the type parameters as specified by the user. -fn add_custom_trait_bounds(mut generics: Generics, custom_bound: utils::TraitBounds) -> Generics { - generics.make_where_clause().predicates.extend(custom_bound); - generics -} - /// generate an expression to sum up the max encoded length from several fields fn fields_length_expr(fields: &Fields) -> proc_macro2::TokenStream { let type_iter: Box> = match fields { @@ -132,12 +118,12 @@ fn data_length_expr(data: &Data) -> proc_macro2::TokenStream { quote! { 0_usize #( #expansion )* .saturating_add(1) } - } + }, Data::Union(ref data) => { // https://github.com/paritytech/parity-scale-codec/ // blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/derive/src/encode.rs#L290-L293 syn::Error::new(data.union_token.span(), "Union types are not supported.") .to_compile_error() - } + }, } } diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index 8d81d7c9..f808588d 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -21,12 +21,12 @@ use syn::{ Generics, Result, Type, TypePath, }; -use crate::utils; +use crate::utils::{self, CustomTraitBound}; /// Visits the ast and checks if one of the given idents is found. struct ContainIdents<'a> { result: bool, - idents: &'a[Ident] + idents: &'a [Ident], } impl<'a, 'ast> Visit<'ast> for ContainIdents<'a> { @@ -47,7 +47,7 @@ fn type_contain_idents(ty: &Type, idents: &[Ident]) -> bool { /// Visits the ast and checks if the a type path starts with the given ident. struct TypePathStartsWithIdent<'a> { result: bool, - ident: &'a Ident + ident: &'a Ident, } impl<'a, 'ast> Visit<'ast> for TypePathStartsWithIdent<'a> { @@ -55,7 +55,7 @@ impl<'a, 'ast> Visit<'ast> for TypePathStartsWithIdent<'a> { if let Some(segment) = i.path.segments.first() { if &segment.ident == self.ident { self.result = true; - return; + return } } @@ -82,7 +82,7 @@ fn type_or_sub_type_path_starts_with_ident(ty: &Type, ident: &Ident) -> bool { /// Returns `T`, `N`, `A` for `Vec<(Recursive, A)>` with `Recursive` as ident. struct FindTypePathsNotStartOrContainIdent<'a> { result: Vec, - ident: &'a Ident + ident: &'a Ident, } impl<'a, 'ast> Visit<'ast> for FindTypePathsNotStartOrContainIdent<'a> { @@ -105,21 +105,38 @@ fn find_type_paths_not_start_or_contain_ident(ty: &Type, ident: &Ident) -> Vec( input_ident: &Ident, generics: &mut Generics, data: &syn::Data, + custom_trait_bound: Option>, codec_bound: syn::Path, codec_skip_bound: Option, dumb_trait_bounds: bool, crate_path: &syn::Path, ) -> Result<()> { - let ty_params = generics.type_params().map(|p| p.ident.clone()).collect::>(); + let skip_type_params = match custom_trait_bound { + Some(CustomTraitBound::SpecifiedBounds { bounds, .. }) => { + generics.make_where_clause().predicates.extend(bounds); + return Ok(()) + }, + Some(CustomTraitBound::SkipTypeParams { type_names, .. }) => + type_names.into_iter().collect::>(), + None => Vec::new(), + }; + + let ty_params = generics + .type_params() + .filter_map(|tp| { + skip_type_params.iter().all(|skip| skip != &tp.ident).then(|| tp.ident.clone()) + }) + .collect::>(); if ty_params.is_empty() { - return Ok(()); + return Ok(()) } - let codec_types = get_types_to_add_trait_bound(input_ident, data, &ty_params, dumb_trait_bounds)?; + let codec_types = + get_types_to_add_trait_bound(input_ident, data, &ty_params, dumb_trait_bounds)?; let compact_types = collect_types(&data, utils::is_compact)? .into_iter() @@ -143,23 +160,17 @@ pub fn add( codec_types .into_iter() - .for_each(|ty| { - where_clause.predicates.push(parse_quote!(#ty : #codec_bound)) - }); + .for_each(|ty| where_clause.predicates.push(parse_quote!(#ty : #codec_bound))); let has_compact_bound: syn::Path = parse_quote!(#crate_path::HasCompact); compact_types .into_iter() - .for_each(|ty| { - where_clause.predicates.push(parse_quote!(#ty : #has_compact_bound)) - }); + .for_each(|ty| where_clause.predicates.push(parse_quote!(#ty : #has_compact_bound))); - skip_types - .into_iter() - .for_each(|ty| { - let codec_skip_bound = codec_skip_bound.as_ref().unwrap(); - where_clause.predicates.push(parse_quote!(#ty : #codec_skip_bound)) - }); + skip_types.into_iter().for_each(|ty| { + let codec_skip_bound = codec_skip_bound.as_ref(); + where_clause.predicates.push(parse_quote!(#ty : #codec_skip_bound)) + }); } Ok(()) @@ -175,15 +186,17 @@ fn get_types_to_add_trait_bound( if dumb_trait_bound { Ok(ty_params.iter().map(|t| parse_quote!( #t )).collect()) } else { - let needs_codec_bound = |f: &syn::Field| !utils::is_compact(f) - && utils::get_encoded_as_type(f).is_none() - && !utils::should_skip(&f.attrs); + let needs_codec_bound = |f: &syn::Field| { + !utils::is_compact(f) && + utils::get_encoded_as_type(f).is_none() && + !utils::should_skip(&f.attrs) + }; let res = collect_types(&data, needs_codec_bound)? .into_iter() // Only add a bound if the type uses a generic .filter(|ty| type_contain_idents(ty, &ty_params)) - // If a struct contains itself as field type, we can not add this type into the where clause. - // This is required to work a round the following compiler bug: https://github.com/rust-lang/rust/issues/47032 + // If a struct contains itself as field type, we can not add this type into the where + // clause. This is required to work a round the following compiler bug: https://github.com/rust-lang/rust/issues/47032 .flat_map(|ty| { find_type_paths_not_start_or_contain_ident(&ty, input_ident) .into_iter() @@ -193,7 +206,8 @@ fn get_types_to_add_trait_bound( // Add back the original type, as we don't want to loose it. .chain(iter::once(ty)) }) - // Remove all remaining types that start/contain the input ident to not have them in the where clause. + // Remove all remaining types that start/contain the input ident to not have them in the + // where clause. .filter(|ty| !type_or_sub_type_path_starts_with_ident(ty, input_ident)) .collect(); @@ -201,45 +215,33 @@ fn get_types_to_add_trait_bound( } } -fn collect_types( - data: &syn::Data, - type_filter: fn(&syn::Field) -> bool, -) -> Result> { +fn collect_types(data: &syn::Data, type_filter: fn(&syn::Field) -> bool) -> Result> { use syn::*; let types = match *data { Data::Struct(ref data) => match &data.fields { - | Fields::Named(FieldsNamed { named: fields , .. }) - | Fields::Unnamed(FieldsUnnamed { unnamed: fields, .. }) => { - fields.iter() - .filter(|f| type_filter(f)) - .map(|f| f.ty.clone()) - .collect() - }, - - Fields::Unit => { Vec::new() }, + | Fields::Named(FieldsNamed { named: fields, .. }) | + Fields::Unnamed(FieldsUnnamed { unnamed: fields, .. }) => + fields.iter().filter(|f| type_filter(f)).map(|f| f.ty.clone()).collect(), + + Fields::Unit => Vec::new(), }, - Data::Enum(ref data) => data.variants.iter() + Data::Enum(ref data) => data + .variants + .iter() .filter(|variant| !utils::should_skip(&variant.attrs)) - .flat_map(|variant| { - match &variant.fields { - | Fields::Named(FieldsNamed { named: fields , .. }) - | Fields::Unnamed(FieldsUnnamed { unnamed: fields, .. }) => { - fields.iter() - .filter(|f| type_filter(f)) - .map(|f| f.ty.clone()) - .collect() - }, - - Fields::Unit => { Vec::new() }, - } - }).collect(), - - Data::Union(ref data) => return Err(Error::new( - data.union_token.span(), - "Union types are not supported." - )), + .flat_map(|variant| match &variant.fields { + | Fields::Named(FieldsNamed { named: fields, .. }) | + Fields::Unnamed(FieldsUnnamed { unnamed: fields, .. }) => + fields.iter().filter(|f| type_filter(f)).map(|f| f.ty.clone()).collect(), + + Fields::Unit => Vec::new(), + }) + .collect(), + + Data::Union(ref data) => + return Err(Error::new(data.union_token.span(), "Union types are not supported.")), }; Ok(types) diff --git a/derive/src/utils.rs b/derive/src/utils.rs index fa72a8a6..585ce9a0 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -22,17 +22,19 @@ use std::str::FromStr; use proc_macro2::TokenStream; use quote::quote; use syn::{ - Attribute, Data, DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, - MetaNameValue, NestedMeta, parse::Parse, Path, punctuated::Punctuated, - spanned::Spanned, token, Variant, + parse::Parse, punctuated::Punctuated, spanned::Spanned, token, Attribute, Data, DeriveInput, + Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, MetaNameValue, NestedMeta, Path, Variant, }; -fn find_meta_item<'a, F, R, I, M>(mut itr: I, mut pred: F) -> Option where +fn find_meta_item<'a, F, R, I, M>(mut itr: I, mut pred: F) -> Option +where F: FnMut(M) -> Option + Clone, - I: Iterator, + I: Iterator, M: Parse, { - itr.find_map(|attr| attr.path.is_ident("codec").then(|| pred(attr.parse_args().ok()?)).flatten()) + itr.find_map(|attr| { + attr.path.is_ident("codec").then(|| pred(attr.parse_args().ok()?)).flatten() + }) } /// Look for a `#[scale(index = $int)]` attribute on a variant. If no attribute @@ -43,7 +45,8 @@ pub fn variant_index(v: &Variant, i: usize) -> TokenStream { if let NestedMeta::Meta(Meta::NameValue(ref nv)) = meta { if nv.path.is_ident("index") { if let Lit::Int(ref v) = nv.lit { - let byte = v.base10_parse::() + let byte = v + .base10_parse::() .expect("Internal error, index attribute must have been checked"); return Some(byte) } @@ -54,12 +57,12 @@ pub fn variant_index(v: &Variant, i: usize) -> TokenStream { }); // then fallback to discriminant or just index - index.map(|i| quote! { #i }) - .unwrap_or_else(|| v.discriminant + index.map(|i| quote! { #i }).unwrap_or_else(|| { + v.discriminant .as_ref() .map(|&(_, ref expr)| quote! { #expr }) .unwrap_or_else(|| quote! { #i }) - ) + }) } /// Look for a `#[codec(encoded_as = "SomeType")]` outer attribute on the given @@ -71,8 +74,8 @@ pub fn get_encoded_as_type(field: &Field) -> Option { if let Lit::Str(ref s) = nv.lit { return Some( TokenStream::from_str(&s.value()) - .expect("Internal error, encoded_as attribute must have been checked") - ); + .expect("Internal error, encoded_as attribute must have been checked"), + ) } } } @@ -86,12 +89,13 @@ pub fn is_compact(field: &Field) -> bool { find_meta_item(field.attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("compact") { - return Some(()); + return Some(()) } } None - }).is_some() + }) + .is_some() } /// Look for a `#[codec(skip)]` in the given attributes. @@ -99,12 +103,13 @@ pub fn should_skip(attrs: &[Attribute]) -> bool { find_meta_item(attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("skip") { - return Some(path.span()); + return Some(path.span()) } } None - }).is_some() + }) + .is_some() } /// Look for a `#[codec(dumb_trait_bound)]`in the given attributes. @@ -112,24 +117,25 @@ pub fn has_dumb_trait_bound(attrs: &[Attribute]) -> bool { find_meta_item(attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("dumb_trait_bound") { - return Some(()); + return Some(()) } } None - }).is_some() + }) + .is_some() } /// Generate the crate access for the crate using 2018 syntax. fn crate_access() -> syn::Result { + use proc_macro2::{Ident, Span}; use proc_macro_crate::{crate_name, FoundCrate}; - use proc_macro2::{Span, Ident}; const DEF_CRATE: &str = "parity-scale-codec"; match crate_name(DEF_CRATE) { Ok(FoundCrate::Itself) => { let name = DEF_CRATE.to_string().replace("-", "_"); Ok(syn::Ident::new(&name, Span::call_site())) - } + }, Ok(FoundCrate::Name(name)) => Ok(Ident::new(&name, Span::call_site())), Err(e) => Err(syn::Error::new(Span::call_site(), e)), } @@ -153,7 +159,7 @@ impl Parse for CratePath { } impl From for Path { - fn from(CratePath { path, ..}: CratePath) -> Self { + fn from(CratePath { path, .. }: CratePath) -> Self { path } } @@ -161,10 +167,13 @@ impl From for Path { /// Match `#[codec(crate = ...)]` and return the `...` if it is a `Path`. fn codec_crate_path_inner(attr: &Attribute) -> Option { // match `#[codec ...]` - attr.path.is_ident("codec").then(|| { - // match `#[codec(crate = ...)]` and return the `...` - attr.parse_args::().map(Into::into).ok() - }).flatten() + attr.path + .is_ident("codec") + .then(|| { + // match `#[codec(crate = ...)]` and return the `...` + attr.parse_args::().map(Into::into).ok() + }) + .flatten() } /// Match `#[codec(crate = ...)]` and return the ellipsis as a `Path`. @@ -179,72 +188,84 @@ pub fn codec_crate_path(attrs: &[Attribute]) -> syn::Result { } } -/// Trait bounds. -pub type TraitBounds = Punctuated; - -/// Parse `name(T: Bound, N: Bound)` as a custom trait bound. -struct CustomTraitBound { - _name: N, - _paren_token: token::Paren, - bounds: TraitBounds, +/// Parse `name(T: Bound, N: Bound)` or `name(skip_type_params(T, N))` as a custom trait bound. +pub enum CustomTraitBound { + SpecifiedBounds { + _name: N, + _paren_token: token::Paren, + bounds: Punctuated, + }, + SkipTypeParams { + _name: N, + _paren_token_1: token::Paren, + _skip_type_params: skip_type_params, + _paren_token_2: token::Paren, + type_names: Punctuated, + }, } impl Parse for CustomTraitBound { fn parse(input: syn::parse::ParseStream) -> syn::Result { - let content; - Ok(Self { - _name: input.parse()?, - _paren_token: syn::parenthesized!(content in input), - bounds: content.parse_terminated(syn::WherePredicate::parse)?, - }) + let mut content; + let _name: N = input.parse()?; + let _paren_token = syn::parenthesized!(content in input); + if content.peek(skip_type_params) { + Ok(Self::SkipTypeParams { + _name, + _paren_token_1: _paren_token, + _skip_type_params: content.parse::()?, + _paren_token_2: syn::parenthesized!(content in content), + type_names: content.parse_terminated(syn::Ident::parse)?, + }) + } else { + Ok(Self::SpecifiedBounds { + _name, + _paren_token, + bounds: content.parse_terminated(syn::WherePredicate::parse)?, + }) + } } } syn::custom_keyword!(encode_bound); syn::custom_keyword!(decode_bound); syn::custom_keyword!(mel_bound); +syn::custom_keyword!(skip_type_params); /// Look for a `#[codec(decode_bound(T: Decode))]` in the given attributes. /// /// If found, it should be used as trait bounds when deriving the `Decode` trait. -pub fn custom_decode_trait_bound(attrs: &[Attribute]) -> Option { - find_meta_item(attrs.iter(), |meta: CustomTraitBound| { - Some(meta.bounds) - }) +pub fn custom_decode_trait_bound(attrs: &[Attribute]) -> Option> { + find_meta_item(attrs.iter(), Some) } /// Look for a `#[codec(encode_bound(T: Encode))]` in the given attributes. /// /// If found, it should be used as trait bounds when deriving the `Encode` trait. -pub fn custom_encode_trait_bound(attrs: &[Attribute]) -> Option { - find_meta_item(attrs.iter(), |meta: CustomTraitBound| { - Some(meta.bounds) - }) +pub fn custom_encode_trait_bound(attrs: &[Attribute]) -> Option> { + find_meta_item(attrs.iter(), Some) } /// Look for a `#[codec(mel_bound(T: MaxEncodedLen))]` in the given attributes. /// /// If found, it should be used as the trait bounds when deriving the `MaxEncodedLen` trait. #[cfg(feature = "max-encoded-len")] -pub fn custom_mel_trait_bound(attrs: &[Attribute]) -> Option { - find_meta_item(attrs.iter(), |meta: CustomTraitBound| { - Some(meta.bounds) - }) +pub fn custom_mel_trait_bound(attrs: &[Attribute]) -> Option> { + find_meta_item(attrs.iter(), Some) } /// Given a set of named fields, return an iterator of `Field` where all fields /// marked `#[codec(skip)]` are filtered out. -pub fn filter_skip_named<'a>(fields: &'a syn::FieldsNamed) -> impl Iterator + 'a { - fields.named.iter() - .filter(|f| !should_skip(&f.attrs)) +pub fn filter_skip_named<'a>(fields: &'a syn::FieldsNamed) -> impl Iterator + 'a { + fields.named.iter().filter(|f| !should_skip(&f.attrs)) } /// Given a set of unnamed fields, return an iterator of `(index, Field)` where all fields /// marked `#[codec(skip)]` are filtered out. -pub fn filter_skip_unnamed<'a>(fields: &'a syn::FieldsUnnamed) -> impl Iterator + 'a { - fields.unnamed.iter() - .enumerate() - .filter(|(_, f)| !should_skip(&f.attrs)) +pub fn filter_skip_unnamed<'a>( + fields: &'a syn::FieldsUnnamed, +) -> impl Iterator + 'a { + fields.unnamed.iter().enumerate().filter(|(_, f)| !should_skip(&f.attrs)) } /// Ensure attributes are correctly applied. This *must* be called before using @@ -276,17 +297,16 @@ pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> { match input.data { Data::Struct(ref data) => match &data.fields { - | Fields::Named(FieldsNamed { named: fields , .. }) - | Fields::Unnamed(FieldsUnnamed { unnamed: fields, .. }) => { + | Fields::Named(FieldsNamed { named: fields, .. }) | + Fields::Unnamed(FieldsUnnamed { unnamed: fields, .. }) => for field in fields { for attr in &field.attrs { check_field_attribute(attr)?; } - } - } + }, Fields::Unit => (), - } - Data::Enum(ref data) => { + }, + Data::Enum(ref data) => for variant in data.variants.iter() { for attr in &variant.attrs { check_variant_attribute(attr)?; @@ -296,8 +316,7 @@ pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> { check_field_attribute(attr)?; } } - } - }, + }, Data::Union(_) => (), } Ok(()) @@ -305,10 +324,10 @@ pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> { // Check if the attribute is `#[allow(..)]`, `#[deny(..)]`, `#[forbid(..)]` or `#[warn(..)]`. pub fn is_lint_attribute(attr: &Attribute) -> bool { - attr.path.is_ident("allow") - || attr.path.is_ident("deny") - || attr.path.is_ident("forbid") - || attr.path.is_ident("warn") + attr.path.is_ident("allow") || + attr.path.is_ident("deny") || + attr.path.is_ident("forbid") || + attr.path.is_ident("warn") } // Ensure a field is decorated only with the following attributes: @@ -324,15 +343,21 @@ fn check_field_attribute(attr: &Attribute) -> syn::Result<()> { Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { match meta_list.nested.first().expect("Just checked that there is one item; qed") { NestedMeta::Meta(Meta::Path(path)) - if path.get_ident().map_or(false, |i| i == "skip") => Ok(()), + if path.get_ident().map_or(false, |i| i == "skip") => + Ok(()), NestedMeta::Meta(Meta::Path(path)) - if path.get_ident().map_or(false, |i| i == "compact") => Ok(()), - - NestedMeta::Meta(Meta::NameValue(MetaNameValue { path, lit: Lit::Str(lit_str), .. })) - if path.get_ident().map_or(false, |i| i == "encoded_as") - => TokenStream::from_str(&lit_str.value()).map(|_| ()) - .map_err(|_e| syn::Error::new(lit_str.span(), "Invalid token stream")), + if path.get_ident().map_or(false, |i| i == "compact") => + Ok(()), + + NestedMeta::Meta(Meta::NameValue(MetaNameValue { + path, + lit: Lit::Str(lit_str), + .. + })) if path.get_ident().map_or(false, |i| i == "encoded_as") => + TokenStream::from_str(&lit_str.value()) + .map(|_| ()) + .map_err(|_e| syn::Error::new(lit_str.span(), "Invalid token stream")), elt @ _ => Err(syn::Error::new(elt.span(), field_error)), } @@ -356,11 +381,16 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { match meta_list.nested.first().expect("Just checked that there is one item; qed") { NestedMeta::Meta(Meta::Path(path)) - if path.get_ident().map_or(false, |i| i == "skip") => Ok(()), - - NestedMeta::Meta(Meta::NameValue(MetaNameValue { path, lit: Lit::Int(lit_int), .. })) - if path.get_ident().map_or(false, |i| i == "index") - => lit_int.base10_parse::().map(|_| ()) + if path.get_ident().map_or(false, |i| i == "skip") => + Ok(()), + + NestedMeta::Meta(Meta::NameValue(MetaNameValue { + path, + lit: Lit::Int(lit_int), + .. + })) if path.get_ident().map_or(false, |i| i == "index") => lit_int + .base10_parse::() + .map(|_| ()) .map_err(|_| syn::Error::new(lit_int.span(), "Index must be in 0..255")), elt @ _ => Err(syn::Error::new(elt.span(), variant_error)), @@ -379,21 +409,22 @@ fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, \ `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` \ are accepted as top attribute"; - if attr.path.is_ident("codec") - && attr.parse_args::>().is_err() - && attr.parse_args::>().is_err() - && attr.parse_args::>().is_err() - && codec_crate_path_inner(attr).is_none() + if attr.path.is_ident("codec") && + attr.parse_args::>().is_err() && + attr.parse_args::>().is_err() && + attr.parse_args::>().is_err() && + codec_crate_path_inner(attr).is_none() { match attr.parse_meta()? { Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { match meta_list.nested.first().expect("Just checked that there is one item; qed") { - NestedMeta::Meta(Meta::Path(path)) - if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => Ok(()), + NestedMeta::Meta(Meta::Path(path)) + if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => + Ok(()), - elt @ _ => Err(syn::Error::new(elt.span(), top_error)), - } - } + elt @ _ => Err(syn::Error::new(elt.span(), top_error)), + } + }, _ => Err(syn::Error::new(attr.span(), top_error)), } } else { diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs index 5bc199dd..9901630c 100644 --- a/tests/max_encoded_len.rs +++ b/tests/max_encoded_len.rs @@ -16,7 +16,7 @@ //! Tests for MaxEncodedLen derive macro #![cfg(all(feature = "derive", feature = "max-encoded-len"))] -use parity_scale_codec::{MaxEncodedLen, Compact, Encode}; +use parity_scale_codec::{MaxEncodedLen, Compact, Decode, Encode}; #[derive(Encode, MaxEncodedLen)] struct Primitives { @@ -180,3 +180,21 @@ enum EnumMaxNotSum { fn enum_max_not_sum_max_length() { assert_eq!(EnumMaxNotSum::max_encoded_len(), 1 + u32::max_encoded_len()); } + +#[test] +fn skip_type_params() { + #[derive(Encode, Decode, MaxEncodedLen)] + #[codec(mel_bound(skip_type_params(N)))] + struct SomeData { + element: T, + size: std::marker::PhantomData, + } + + trait SomeTrait {} + + struct SomeStruct; + + impl SomeTrait for SomeStruct {} + + assert_eq!(SomeData::::max_encoded_len(), 4); +} diff --git a/tests/mod.rs b/tests/mod.rs index c694469a..0a3855aa 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -15,7 +15,7 @@ #[cfg(not(feature="derive"))] use parity_scale_codec_derive::{Encode, Decode}; use parity_scale_codec::{ - Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error, Output, DecodeAll + Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error, Output, }; use serde_derive::{Serialize, Deserialize}; @@ -591,6 +591,7 @@ fn custom_trait_bound() { #[cfg(feature = "bit-vec")] fn bit_vec_works() { use bitvec::prelude::*; + use parity_scale_codec::DecodeAll; // Try some fancy stuff let original_vec = bitvec![u8, Msb0; 1; 8]; From 75fab93eac5d5301d704b587ed4dcebfd3b72f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 3 Jun 2022 17:48:27 +0200 Subject: [PATCH 088/286] Derived code should not emit deprecated warnings (#343) * Derived code should not emit deprecated warnings * Let the build fail with warnings enabled --- .gitlab-ci.yml | 12 +++++ derive/src/lib.rs | 6 +++ tests/mod.rs | 123 ++++++++++++++++++++++++++++------------------ 3 files changed, 92 insertions(+), 49 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 67e90ee6..ee7ae05b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -50,6 +50,8 @@ workflow: check-rust-stable-no_derive_no_std_full: stage: check <<: *docker-env + variables: + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array,full - sccache -s @@ -57,6 +59,8 @@ check-rust-stable-no_derive_no_std_full: check-rust-stable-no_derive_no_std: stage: check <<: *docker-env + variables: + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array - sccache -s @@ -64,6 +68,8 @@ check-rust-stable-no_derive_no_std: check-rust-stable-no_std-chain-error: stage: check <<: *docker-env + variables: + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --no-default-features --features chain-error - sccache -s @@ -71,6 +77,8 @@ check-rust-stable-no_std-chain-error: check-rust-stable-no_derive_full: stage: check <<: *docker-env + variables: + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --features bit-vec,bytes,generic-array,full - sccache -s @@ -80,6 +88,8 @@ check-rust-stable-no_derive_full: test-rust-stable: stage: test <<: *docker-env + variables: + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable test --verbose --all --features bit-vec,bytes,generic-array,derive,max-encoded-len - sccache -s @@ -87,6 +97,8 @@ test-rust-stable: test-rust-stable-no_derive: stage: test <<: *docker-env + variables: + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable test --verbose --features bit-vec,bytes,generic-array - sccache -s diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 5d6b753f..9d80304b 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -39,6 +39,7 @@ fn wrap_with_dummy_const( ) -> proc_macro::TokenStream { let attrs = input.attrs.into_iter().filter(is_lint_attribute); let generated = quote! { + #[allow(deprecated)] const _: () = { #(#attrs)* #impl_block @@ -155,10 +156,12 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let encode_impl = encode::quote(&input.data, name, &crate_path); let impl_block = quote! { + #[automatically_derived] impl #impl_generics #crate_path::Encode for #name #ty_generics #where_clause { #encode_impl } + #[automatically_derived] impl #impl_generics #crate_path::EncodeLike for #name #ty_generics #where_clause {} }; @@ -206,6 +209,7 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_, &crate_path); let impl_block = quote! { + #[automatically_derived] impl #impl_generics #crate_path::Decode for #name #ty_generics #where_clause { fn decode<__CodecInputEdqy: #crate_path::Input>( #input_: &mut __CodecInputEdqy @@ -311,6 +315,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr }; let impl_block = quote! { + #[automatically_derived] impl #impl_generics #crate_path::CompactAs for #name #ty_generics #where_clause { type As = #inner_ty; fn encode_as(&self) -> &#inner_ty { @@ -323,6 +328,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr } } + #[automatically_derived] impl #impl_generics From<#crate_path::Compact<#name #ty_generics>> for #name #ty_generics #where_clause { diff --git a/tests/mod.rs b/tests/mod.rs index 0a3855aa..7d6a0ee3 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[cfg(not(feature="derive"))] -use parity_scale_codec_derive::{Encode, Decode}; use parity_scale_codec::{ - Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error, Output, + Compact, CompactAs, Decode, Encode, EncodeAsRef, Error, HasCompact, Output, }; -use serde_derive::{Serialize, Deserialize}; +#[cfg(not(feature = "derive"))] +use parity_scale_codec_derive::{Decode, Encode}; +use serde_derive::{Deserialize, Serialize}; #[derive(Debug, PartialEq, Encode, Decode)] struct Unit; @@ -41,7 +41,7 @@ struct StructWithPhantom { type TestType = Struct>; -impl Struct { +impl Struct { fn new(a: A, b: B, c: C) -> Self { Self { a, b, c } } @@ -82,12 +82,12 @@ enum TestHasCompactEnum { Unnamed(#[codec(encoded_as = "::Type")] T), Named { #[codec(encoded_as = "::Type")] - bar: T + bar: T, }, UnnamedCompact(#[codec(compact)] T), NamedCompact { #[codec(compact)] - bar: T + bar: T, }, } @@ -158,9 +158,7 @@ fn should_work_for_enum_with_discriminant() { fn should_derive_encode() { let v = TestType::new(15, 9, b"Hello world".to_vec()); - v.using_encoded(|ref slice| { - assert_eq!(slice, &b"\x0f\0\0\0\x09\0\0\0\0\0\0\0\x2cHello world") - }); + v.using_encoded(|ref slice| assert_eq!(slice, &b"\x0f\0\0\0\x09\0\0\0\0\0\0\0\x2cHello world")); } #[test] @@ -188,9 +186,7 @@ fn should_work_for_unit() { fn should_work_for_indexed() { let v = Indexed(1, 2); - v.using_encoded(|ref slice| { - assert_eq!(slice, &b"\x01\0\0\0\x02\0\0\0\0\0\0\0") - }); + v.using_encoded(|ref slice| assert_eq!(slice, &b"\x01\0\0\0\x02\0\0\0\0\0\0\0")); let mut v: &[u8] = b"\x01\0\0\0\x02\0\0\0\0\0\0\0"; assert_eq!(Indexed::decode(&mut v), Ok(Indexed(1, 2))); @@ -232,17 +228,37 @@ fn correct_error_for_named_struct_2() { } const U64_TEST_COMPACT_VALUES: &[(u64, usize)] = &[ - (0u64, 1usize), (63, 1), (64, 2), (16383, 2), - (16384, 4), (1073741823, 4), - (1073741824, 5), (1 << 32 - 1, 5), - (1 << 32, 6), (1 << 40, 7), (1 << 48, 8), (1 << 56 - 1, 8), (1 << 56, 9), (u64::max_value(), 9) + (0u64, 1usize), + (63, 1), + (64, 2), + (16383, 2), + (16384, 4), + (1073741823, 4), + (1073741824, 5), + (1 << 32 - 1, 5), + (1 << 32, 6), + (1 << 40, 7), + (1 << 48, 8), + (1 << 56 - 1, 8), + (1 << 56, 9), + (u64::max_value(), 9), ]; const U64_TEST_COMPACT_VALUES_FOR_ENUM: &[(u64, usize)] = &[ - (0u64, 2usize), (63, 2), (64, 3), (16383, 3), - (16384, 5), (1073741823, 5), - (1073741824, 6), (1 << 32 - 1, 6), - (1 << 32, 7), (1 << 40, 8), (1 << 48, 9), (1 << 56 - 1, 9), (1 << 56, 10), (u64::max_value(), 10) + (0u64, 2usize), + (63, 2), + (64, 3), + (16383, 3), + (16384, 5), + (1073741823, 5), + (1073741824, 6), + (1 << 32 - 1, 6), + (1 << 32, 7), + (1 << 40, 8), + (1 << 48, 9), + (1 << 56 - 1, 9), + (1 << 56, 10), + (u64::max_value(), 10), ]; #[test] @@ -273,7 +289,9 @@ fn enum_compact_and_encoded_as_with_has_compact_works() { TestHasCompactEnum::Named { bar: n }, TestHasCompactEnum::UnnamedCompact(n), TestHasCompactEnum::NamedCompact { bar: n }, - ].iter() { + ] + .iter() + { let encoded = value.encode(); println!("{:?}", value); assert_eq!(encoded.len(), l); @@ -294,7 +312,10 @@ fn compact_meta_attribute_works() { #[test] fn enum_compact_meta_attribute_works() { for &(n, l) in U64_TEST_COMPACT_VALUES_FOR_ENUM { - for value in [ TestCompactAttributeEnum::Unnamed(n), TestCompactAttributeEnum::Named { bar: n } ].iter() { + for value in + [TestCompactAttributeEnum::Unnamed(n), TestCompactAttributeEnum::Named { bar: n }] + .iter() + { let encoded = value.encode(); assert_eq!(encoded.len(), l); assert_eq!(&TestCompactAttributeEnum::decode(&mut &encoded[..]).unwrap(), value); @@ -360,9 +381,7 @@ fn generic_bound_encoded_as() { a: A, } - let a = TestGeneric:: { - a: StructEncodeAsRef, - }; + let a = TestGeneric:: { a: StructEncodeAsRef }; a.encode(); } @@ -392,13 +411,12 @@ fn generic_bound_hascompact() { #[derive(Debug, PartialEq, Encode, Decode)] enum TestGenericHasCompact { A { - #[codec(compact)] a: T + #[codec(compact)] + a: T, }, } - let a = TestGenericHasCompact::A:: { - a: StructHasCompact(0), - }; + let a = TestGenericHasCompact::A:: { a: StructHasCompact(0) }; a.encode(); } @@ -423,9 +441,7 @@ fn generic_trait() { t: T::Type, } - let a = TestGenericTrait:: { - t: StructCodec, - }; + let a = TestGenericTrait:: { t: StructCodec }; a.encode(); } @@ -489,12 +505,7 @@ fn encode_decode_empty_enum() { #[test] fn codec_vec_u8() { - for v in [ - vec![0u8; 0], - vec![0u8; 10], - vec![0u8; 100], - vec![0u8; 1000], - ].iter() { + for v in [vec![0u8; 0], vec![0u8; 10], vec![0u8; 100], vec![0u8; 1000]].iter() { let e = v.encode(); assert_eq!(v, &Vec::::decode(&mut &e[..]).unwrap()); } @@ -512,13 +523,15 @@ fn recursive_type() { pub struct Bar { field: Foo, } - } #[test] fn crafted_input_for_vec_u8() { assert_eq!( - Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]).err().unwrap().to_string(), + Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]) + .err() + .unwrap() + .to_string(), "Not enough data to decode vector", ); } @@ -533,7 +546,10 @@ fn crafted_input_for_vec_t() { }; assert_eq!( - Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]).err().unwrap().to_string(), + Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]) + .err() + .unwrap() + .to_string(), msg, ); } @@ -543,12 +559,12 @@ fn weird_derive() { // Tests that compilation succeeds when the macro invocation // hygiene context is different from the field hygiene context. macro_rules! make_struct { - (#[$attr:meta]) => ( + (#[$attr:meta]) => { #[$attr] pub struct MyStruct { - field: u8 + field: u8, } - ) + }; } make_struct!(#[derive(Encode, Decode)]); @@ -579,10 +595,9 @@ fn custom_trait_bound() { #[derive(Default)] struct NotEncode; - let encoded = Something:: { - hello: Hello { _phantom: Default::default() }, - val: 32u32, - }.encode(); + let encoded = + Something:: { hello: Hello { _phantom: Default::default() }, val: 32u32 } + .encode(); Something::::decode(&mut &encoded[..]).unwrap(); } @@ -619,3 +634,13 @@ fn bit_vec_works() { let v2 = MyStruct::decode_all(&mut &v2[..]).unwrap(); assert_eq!(v1.x, v2.x); } + +#[test] +fn no_warning_for_deprecated() { + #[derive(Encode, Decode)] + pub enum MyEnum { + VariantA, + #[deprecated] + VariantB, + } +} From 51d047413fc0c9d1e815cc947015c5a90930033d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jun 2022 12:11:30 +0200 Subject: [PATCH 089/286] Bump crossbeam-utils from 0.8.5 to 0.8.8 (#345) Bumps [crossbeam-utils](https://github.com/crossbeam-rs/crossbeam) from 0.8.5 to 0.8.8. - [Release notes](https://github.com/crossbeam-rs/crossbeam/releases) - [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-utils-0.8.5...crossbeam-utils-0.8.8) --- updated-dependencies: - dependency-name: crossbeam-utils dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e76b7ab8..afa0a318 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,9 +199,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ "cfg-if", "lazy_static", From dc7af67b2bea692335f58a5d7da0519039d250f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jun 2022 14:32:12 +0200 Subject: [PATCH 090/286] Bump regex from 1.5.4 to 1.5.6 (#346) Bumps [regex](https://github.com/rust-lang/regex) from 1.5.4 to 1.5.6. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.5.4...1.5.6) --- updated-dependencies: - dependency-name: regex dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index afa0a318..e57b4e41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -576,9 +576,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.4" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ "aho-corasick", "memchr", @@ -593,9 +593,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "rustc_version" From f281968f4e8264e284786cf4fede320ab7991cdc Mon Sep 17 00:00:00 2001 From: Koute Date: Fri, 10 Jun 2022 14:26:25 +0900 Subject: [PATCH 091/286] Bump `parity-scale-codec-derive` to 3.1.3 (#344) --- Cargo.lock | 2 +- Cargo.toml | 2 +- derive/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e57b4e41..24dd5f6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -443,7 +443,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.2" +version = "3.1.3" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index f4f6b084..116ea8c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.56.1" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.102", optional = true } -parity-scale-codec-derive = { path = "derive", version = "3.1.2", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "3.1.3", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index f066eece..c526f67e 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.1.2" +version = "3.1.3" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" From 9109135ffd7b828712cf803c25a6ed54208e26be Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 10 Jun 2022 18:27:34 +0100 Subject: [PATCH 092/286] Respect #[codec(skip)] when deriving MEL (#347) * Respect #[codec(skip)] when deriving MEL * Hopefully satisfy linter --- derive/src/max_encoded_len.rs | 18 +++++++++++++++--- tests/max_encoded_len.rs | 12 ++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index c55d3167..bf8b20f7 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -17,7 +17,7 @@ use crate::{ trait_bounds, - utils::{codec_crate_path, custom_mel_trait_bound, has_dumb_trait_bound}, + utils::{codec_crate_path, custom_mel_trait_bound, has_dumb_trait_bound, should_skip}, }; use quote::{quote, quote_spanned}; use syn::{parse_quote, spanned::Spanned, Data, DeriveInput, Fields, Type}; @@ -66,8 +66,20 @@ pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::Tok /// generate an expression to sum up the max encoded length from several fields fn fields_length_expr(fields: &Fields) -> proc_macro2::TokenStream { let type_iter: Box> = match fields { - Fields::Named(ref fields) => Box::new(fields.named.iter().map(|field| &field.ty)), - Fields::Unnamed(ref fields) => Box::new(fields.unnamed.iter().map(|field| &field.ty)), + Fields::Named(ref fields) => Box::new( + fields.named.iter().filter_map(|field| if should_skip(&field.attrs) { + None + } else { + Some(&field.ty) + }) + ), + Fields::Unnamed(ref fields) => Box::new( + fields.unnamed.iter().filter_map(|field| if should_skip(&field.attrs) { + None + } else { + Some(&field.ty) + }) + ), Fields::Unit => Box::new(std::iter::empty()), }; // expands to an expression like diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs index 9901630c..b34ec12e 100644 --- a/tests/max_encoded_len.rs +++ b/tests/max_encoded_len.rs @@ -29,6 +29,18 @@ fn primitives_max_length() { assert_eq!(Primitives::max_encoded_len(), 2); } +#[derive(Encode, MaxEncodedLen)] +struct SkippedField { + bool: bool, + #[codec(skip)] + _skipped: u64, +} + +#[test] +fn skipped_field_max_length() { + assert_eq!(SkippedField::max_encoded_len(), 1); +} + #[derive(Encode, MaxEncodedLen)] struct Composites { fixed_size_array: [u8; 128], From 2a45797449b3dfeea12aae0596d2803c4564fd86 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 10 Jun 2022 23:10:59 +0100 Subject: [PATCH 093/286] Implement MaxEncodedLen for Box (#349) --- src/max_encoded_len.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs index 6579af32..620f8d16 100644 --- a/src/max_encoded_len.rs +++ b/src/max_encoded_len.rs @@ -85,6 +85,12 @@ impl MaxEncodedLen for [T; N] { } } +impl MaxEncodedLen for Box { + fn max_encoded_len() -> usize { + T::max_encoded_len() + } +} + impl MaxEncodedLen for Option { fn max_encoded_len() -> usize { T::max_encoded_len().saturating_add(1) From 9fad5983548903233a84e36a49b9f07bb73a6e01 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 11 Jun 2022 11:02:37 +0100 Subject: [PATCH 094/286] Bump to 3.1.4 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 116ea8c5..d864ff61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.1.3" +version = "3.1.4" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" From c25f14a46546c75e4208363ced9d89aa81c85e7f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 11 Jun 2022 11:08:52 +0100 Subject: [PATCH 095/286] Fix build on no-std and bump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/max_encoded_len.rs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24dd5f6b..7ec81da1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -423,7 +423,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.1.3" +version = "3.1.4" dependencies = [ "arbitrary", "arrayvec", diff --git a/Cargo.toml b/Cargo.toml index d864ff61..aeeae868 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.1.4" +version = "3.1.5" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs index 620f8d16..b8b5ad45 100644 --- a/src/max_encoded_len.rs +++ b/src/max_encoded_len.rs @@ -18,6 +18,7 @@ use crate::{Compact, Encode}; use impl_trait_for_tuples::impl_for_tuples; use core::{mem, marker::PhantomData}; +use allow::boxed::Box; /// Items implementing `MaxEncodedLen` have a statically known maximum encoded size. /// From 7f8fdba9a87f53c385a19574f6d464d7890ee17f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 11 Jun 2022 11:11:23 +0100 Subject: [PATCH 096/286] Use preimported alloc --- Cargo.lock | 2 +- src/max_encoded_len.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ec81da1..c0711fb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -423,7 +423,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.1.4" +version = "3.1.5" dependencies = [ "arbitrary", "arrayvec", diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs index b8b5ad45..556fedf7 100644 --- a/src/max_encoded_len.rs +++ b/src/max_encoded_len.rs @@ -18,7 +18,7 @@ use crate::{Compact, Encode}; use impl_trait_for_tuples::impl_for_tuples; use core::{mem, marker::PhantomData}; -use allow::boxed::Box; +use crate::alloc::boxed::Box; /// Items implementing `MaxEncodedLen` have a statically known maximum encoded size. /// From d95dca4b876b1f0f8be4b3c9e6530ad6db2f4043 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 15 Jun 2022 12:52:24 +0200 Subject: [PATCH 097/286] Implement MaxEncodedLen on more core lib types (#350) * Implement MaxEncodedLen on more core lib types * Import missing core types --- src/max_encoded_len.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs index 556fedf7..4b40baa6 100644 --- a/src/max_encoded_len.rs +++ b/src/max_encoded_len.rs @@ -17,7 +17,8 @@ use crate::{Compact, Encode}; use impl_trait_for_tuples::impl_for_tuples; -use core::{mem, marker::PhantomData}; +use core::{mem, marker::PhantomData, num::*, ops::Range, time::Duration}; +use std::ops::RangeInclusive; use crate::alloc::boxed::Box; /// Items implementing `MaxEncodedLen` have a statically known maximum encoded size. @@ -45,6 +46,11 @@ macro_rules! impl_primitives { impl_primitives!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, bool); +impl_primitives!( + NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroI8, NonZeroI16, NonZeroI32, + NonZeroI64, NonZeroI128 +); + macro_rules! impl_compact { ($( $t:ty => $e:expr; )*) => { $( @@ -114,6 +120,24 @@ impl MaxEncodedLen for PhantomData { } } +impl MaxEncodedLen for Duration { + fn max_encoded_len() -> usize { + u64::max_encoded_len() + u32::max_encoded_len() + } +} + +impl MaxEncodedLen for Range { + fn max_encoded_len() -> usize { + T::max_encoded_len().saturating_mul(2) + } +} + +impl MaxEncodedLen for RangeInclusive { + fn max_encoded_len() -> usize { + T::max_encoded_len().saturating_mul(2) + } +} + #[cfg(test)] mod tests { use super::*; From 59b383904444d6b934e215e7e68277b8d7d26d9a Mon Sep 17 00:00:00 2001 From: Sergejs Kostjucenko <85877331+sergejparity@users.noreply.github.com> Date: Fri, 17 Jun 2022 17:17:16 +0300 Subject: [PATCH 098/286] Add dependabot (#339) * add dependabot --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..83cf59da --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 + +updates: + - package-ecosystem: github-actions + directory: '/' + schedule: + interval: daily + - package-ecosystem: cargo + directory: '/' + schedule: + interval: 'daily' From c4084fe873d1cf04c06972e2ec5f763f9b9b111a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jun 2022 14:56:20 +0000 Subject: [PATCH 099/286] Bump s3krit/matrix-message-action from 0.0.2 to 0.0.3 (#351) --- .github/workflows/release-bot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-bot.yml b/.github/workflows/release-bot.yml index 08aa9441..ed0a8e54 100644 --- a/.github/workflows/release-bot.yml +++ b/.github/workflows/release-bot.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: send message - uses: s3krit/matrix-message-action@v0.0.2 + uses: s3krit/matrix-message-action@v0.0.3 with: room_id: ${{ secrets.MATRIX_ROOM_ID }} access_token: ${{ secrets.MATRIX_ACCESS_TOKEN }} From a5b527315f77f3f8fdfad957b05a74efd33bf3ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jun 2022 23:36:09 +0200 Subject: [PATCH 100/286] Bump trybuild from 1.0.52 to 1.0.63 (#354) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.52 to 1.0.63. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.52...1.0.63) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 16 ++++++++++------ Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c0711fb8..b5c59155 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -415,6 +415,12 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" + [[package]] name = "oorandom" version = "11.1.3" @@ -638,9 +644,6 @@ name = "serde" version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" -dependencies = [ - "serde_derive", -] [[package]] name = "serde_cbor" @@ -750,13 +753,14 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.52" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "150e726dc059e6fbd4fce3288f5bb3cf70128cf63b0dde23b938a3cad810fb23" +checksum = "764b9e244b482a9b81bde596aa37aa6f1347bf8007adab25e59f901b32b4e0a0" dependencies = [ "glob", - "lazy_static", + "once_cell", "serde", + "serde_derive", "serde_json", "termcolor", "toml", diff --git a/Cargo.toml b/Cargo.toml index aeeae868..bb1b115b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ criterion = "0.3.0" serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" -trybuild = "1.0.42" +trybuild = "1.0.63" paste = "1" [[bench]] From e4a02c3818089a616b2b0739e2df0502d9b184b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jun 2022 22:32:19 +0200 Subject: [PATCH 101/286] Bump syn from 1.0.81 to 1.0.98 (#358) Bumps [syn](https://github.com/dtolnay/syn) from 1.0.81 to 1.0.98. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.81...1.0.98) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 24 ++++++++++++------------ derive/Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5c59155..c01436a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -504,11 +504,11 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -679,13 +679,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.81" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -773,16 +773,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] -name = "unicode-width" -version = "0.1.9" +name = "unicode-ident" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-width" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "version_check" diff --git a/derive/Cargo.toml b/derive/Cargo.toml index c526f67e..d2f7c929 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.56.1" proc-macro = true [dependencies] -syn = { version = "1.0.8", features = ["full", "visit"] } +syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.2" proc-macro2 = "1.0.6" proc-macro-crate = "1.0.0" From 51998e081a1393e9d75bde0f862ef601099e86b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Jul 2022 23:13:37 +0200 Subject: [PATCH 102/286] Bump serde from 1.0.130 to 1.0.139 (#361) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.130 to 1.0.139. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.130...v1.0.139) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c01436a7..7a26e59a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -641,9 +641,9 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.130" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" [[package]] name = "serde_cbor" diff --git a/Cargo.toml b/Cargo.toml index bb1b115b..7d09b39a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.56.1" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.102", optional = true } +serde = { version = "1.0.139", optional = true } parity-scale-codec-derive = { path = "derive", version = "3.1.3", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From de2061aed50f87a14fc8603c6021ca04a14ac94f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 17 Jul 2022 21:45:28 +0200 Subject: [PATCH 103/286] Bump impl-trait-for-tuples from 0.2.1 to 0.2.2 (#362) Bumps [impl-trait-for-tuples](https://github.com/bkchr/impl-trait-for-tuples) from 0.2.1 to 0.2.2. - [Release notes](https://github.com/bkchr/impl-trait-for-tuples/releases) - [Commits](https://github.com/bkchr/impl-trait-for-tuples/compare/v0.2.1...v0.2.2) --- updated-dependencies: - dependency-name: impl-trait-for-tuples dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a26e59a..5ab6c59e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -317,9 +317,9 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5dacb10c5b3bb92d46ba347505a9041e676bb20ad220101326bffb0c93031ee" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 7d09b39a..9f970035 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.0.0", default-features = false } generic-array = { version = "0.14.4", optional = true } arbitrary = { version = "1.0.1", features = ["derive"], optional = true } -impl-trait-for-tuples = "0.2.1" +impl-trait-for-tuples = "0.2.2" [dev-dependencies] criterion = "0.3.0" From af15ea7cf7cc5195eb37d1f5c326f5335eff6631 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Jul 2022 01:00:36 +0200 Subject: [PATCH 104/286] Bump byte-slice-cast from 1.2.0 to 1.2.1 (#359) Bumps [byte-slice-cast](https://github.com/sdroege/bytes-num-slice-cast) from 1.2.0 to 1.2.1. - [Release notes](https://github.com/sdroege/bytes-num-slice-cast/releases) - [Changelog](https://github.com/sdroege/byte-slice-cast/blob/master/CHANGELOG.md) - [Commits](https://github.com/sdroege/bytes-num-slice-cast/compare/1.2.0...1.2.1) --- updated-dependencies: - dependency-name: byte-slice-cast dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ab6c59e..281a66c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,9 +81,9 @@ checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" [[package]] name = "byte-slice-cast" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c751592b77c499e7bce34d99d67c2c11bdc0574e9a488ddade14150a4698" +checksum = "87c5fdd0166095e1d463fc6cc01aa8ce547ad77a4e84d42eb6762b084e28067e" [[package]] name = "bytes" diff --git a/Cargo.toml b/Cargo.toml index 9f970035..673cc091 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ serde = { version = "1.0.139", optional = true } parity-scale-codec-derive = { path = "derive", version = "3.1.3", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } -byte-slice-cast = { version = "1.0.0", default-features = false } +byte-slice-cast = { version = "1.2.1", default-features = false } generic-array = { version = "0.14.4", optional = true } arbitrary = { version = "1.0.1", features = ["derive"], optional = true } impl-trait-for-tuples = "0.2.2" From b5f2b360e2939e8a235423f40591db09e879fdbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Jul 2022 22:47:09 +0200 Subject: [PATCH 105/286] Bump generic-array from 0.14.4 to 0.14.5 (#355) Bumps [generic-array](https://github.com/fizyk20/generic-array) from 0.14.4 to 0.14.5. - [Release notes](https://github.com/fizyk20/generic-array/releases) - [Changelog](https://github.com/fizyk20/generic-array/blob/master/CHANGELOG.md) - [Commits](https://github.com/fizyk20/generic-array/commits) --- updated-dependencies: - dependency-name: generic-array dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 281a66c9..4c932325 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -264,9 +264,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", diff --git a/Cargo.toml b/Cargo.toml index 673cc091..fc4e40dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ parity-scale-codec-derive = { path = "derive", version = "3.1.3", default-featur bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.1", default-features = false } -generic-array = { version = "0.14.4", optional = true } +generic-array = { version = "0.14.5", optional = true } arbitrary = { version = "1.0.1", features = ["derive"], optional = true } impl-trait-for-tuples = "0.2.2" From 46859b803c94f091e3ca644d8468bfadfbd2c539 Mon Sep 17 00:00:00 2001 From: Tannr Date: Tue, 23 Aug 2022 01:03:07 -0700 Subject: [PATCH 106/286] Update README.md (#368) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66877b25..6ff97116 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The encoded data does not include this contextual information. To get a better understanding of how the encoding is done for different types, take a look at the -[low-level data formats overview page at the Substrate docs site](https://docs.substrate.io/v3/advanced/scale-codec/). +[low-level data formats overview page at the Substrate docs site](https://docs.substrate.io/reference/scale-codec/). ## Implementation From ccd0f90c788eb15cdf3811de4cde3f55b62190c0 Mon Sep 17 00:00:00 2001 From: James Wilson Date: Tue, 13 Sep 2022 11:59:33 +0100 Subject: [PATCH 107/286] Don't include bitvec with std feature unless asked for explicitly (#375) --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fc4e40dd..f26064bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" categories = ["encoding"] edition = "2021" -rust-version = "1.56.1" +rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } @@ -38,7 +38,7 @@ bench = false [features] default = ["std"] derive = ["parity-scale-codec-derive"] -std = ["serde", "bitvec/std", "byte-slice-cast/std", "chain-error"] +std = ["serde", "bitvec?/std", "byte-slice-cast/std", "chain-error"] bit-vec = ["bitvec"] fuzz = ["std", "arbitrary"] From c5c64ab9aaf87cc24345d2d5a3393fd9c18e8acc Mon Sep 17 00:00:00 2001 From: James Wilson Date: Tue, 13 Sep 2022 17:51:26 +0100 Subject: [PATCH 108/286] Bump version and bring changelog back uptodate for 3.2.0 release (#376) --- CHANGELOG.md | 40 ++++++++++++++++++++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- src/bit_vec.rs | 1 + 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f262e804..68ae8866 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,46 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.2.0] - 2022-09-13 + +This release (specifically [#375](https://github.com/paritytech/parity-scale-codec/pull/375)) bumps the MSRV to 1.60.0 as it depends on the Cargo.toml weak dependency feature. + +## Changed + +- Don't include bitvec with std feature unless asked for explicitly. [#375](https://github.com/paritytech/parity-scale-codec/pull/375) +- Implement `MaxEncodedLen` on more core lib types. [#350](https://github.com/paritytech/parity-scale-codec/pull/350) + +## [3.1.5] - 2022-06-11 + +A quick release to fix an issue introduced in 3.1.4 that broke compiling on no-std. + +## Changed + +- Fix compiling on no-std. (see https://github.com/paritytech/parity-scale-codec/commit/c25f14a46546c75e4208363ced9d89aa81c85e7f) + +## [3.1.3] - 2022-06-10 + +## Changed + +- Impl `MaxEncodedLen` for `Box`. [#349](https://github.com/paritytech/parity-scale-codec/pull/349) +- Add `decode_from_bytes`. [#342](https://github.com/paritytech/parity-scale-codec/pull/342) + +## [3.1.2] - 2022-03-22 + +Be aware that version 3.0.0. up to 3.1.1 contained some bugs in the `BitVec` encoder that could lead to an invalid encoding. Thus, we yanked these crate version and it is advised to upgrade to 3.1.2. Any release before 3.0.0 wasn't affected by this bug. + +## Changed + +- Optimised the `Decode::decode` for `[T; N]` by @xgreenx. [#299](https://github.com/paritytech/parity-scale-codec/pull/299) +- Add some doc for the derive macro by @thiolliere. [#301](https://github.com/paritytech/parity-scale-codec/pull/301) +- Add bytes::Bytes implementation by @vorot93. [#309](https://github.com/paritytech/parity-scale-codec/pull/309) +- Upgrade to BitVec 1.0 by @bkchr. [#311](https://github.com/paritytech/parity-scale-codec/pull/311) +- BREAKING CHANGE: DecodeLimit and DecodeAll extensions now advance input by @wigy-opensource-developer. [#314](https://github.com/paritytech/parity-scale-codec/pull/314) +- Make `CompactRef` public by @andrenth. [#321](https://github.com/paritytech/parity-scale-codec/pull/321) +- Add ability to re-export parity-scale-codec crate by @gshep. [#325](https://github.com/paritytech/parity-scale-codec/pull/325) +- BitVec: Improve the encoding and consolidate the implementations by @bkchr. [#327](https://github.com/paritytech/parity-scale-codec/pull/327) +- Fix crate access by putting a leading `::` by @bkchr. [#328](https://github.com/paritytech/parity-scale-codec/pull/328) + ## [3.0.0] - 2022-02-02 ### Fix diff --git a/Cargo.lock b/Cargo.lock index 4c932325..3ca7c62e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -429,7 +429,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.1.5" +version = "3.2.0" dependencies = [ "arbitrary", "arrayvec", diff --git a/Cargo.toml b/Cargo.toml index f26064bc..8521b85b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.1.5" +version = "3.2.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" diff --git a/src/bit_vec.rs b/src/bit_vec.rs index b57e793b..4f0f84b5 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -202,6 +202,7 @@ mod tests { (bitvec![u8, Lsb0; 1, 1, 1, 1].encode(), (Compact(4u32), 0b00001111u8).encode()), (bitvec![u8, Lsb0; 1, 1, 1, 1, 1].encode(), (Compact(5u32), 0b00011111u8).encode()), (bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 0].encode(), (Compact(6u32), 0b00011111u8).encode()), + (bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1].encode(), (Compact(12u32), 0b00011111u8, 0b00001011u8).encode()), ]; for (idx, (actual, expected)) in cases.into_iter().enumerate() { From 4b94a47704f960c25e5d7fd2ffee62fdb99af2d0 Mon Sep 17 00:00:00 2001 From: Jay Pavlina Date: Tue, 13 Sep 2022 16:47:26 -0300 Subject: [PATCH 109/286] Use core RangeInclusive instead of std (#378) --- src/max_encoded_len.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs index 4b40baa6..b4c0d878 100644 --- a/src/max_encoded_len.rs +++ b/src/max_encoded_len.rs @@ -17,8 +17,7 @@ use crate::{Compact, Encode}; use impl_trait_for_tuples::impl_for_tuples; -use core::{mem, marker::PhantomData, num::*, ops::Range, time::Duration}; -use std::ops::RangeInclusive; +use core::{mem, marker::PhantomData, num::*, ops::{Range, RangeInclusive}, time::Duration}; use crate::alloc::boxed::Box; /// Items implementing `MaxEncodedLen` have a statically known maximum encoded size. From 4e8d1ab581def9c3c2c330ea8f0c7e45afc64f41 Mon Sep 17 00:00:00 2001 From: James Wilson Date: Wed, 14 Sep 2022 16:08:39 +0100 Subject: [PATCH 110/286] Bump to 3.2.1 (#380) --- CHANGELOG.md | 8 ++++++++ Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68ae8866..931bfc71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.2.1] - 2022-09-14 + +This release fixes compilation on no-std envs. + +## Changed + + - Use core RangeInclusive instead of std [#378](https://github.com/paritytech/parity-scale-codec/pull/378) + ## [3.2.0] - 2022-09-13 This release (specifically [#375](https://github.com/paritytech/parity-scale-codec/pull/375)) bumps the MSRV to 1.60.0 as it depends on the Cargo.toml weak dependency feature. diff --git a/Cargo.toml b/Cargo.toml index 8521b85b..2aa7ba6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.2.0" +version = "3.2.1" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" From 47d98a1c23dabc890fdb548d115a18070082c66e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Sep 2022 10:22:41 +0200 Subject: [PATCH 111/286] Bump bitvec from 1.0.0 to 1.0.1 (#365) Bumps [bitvec](https://github.com/bitvecto-rs/bitvec) from 1.0.0 to 1.0.1. - [Release notes](https://github.com/bitvecto-rs/bitvec/releases) - [Changelog](https://github.com/bitvecto-rs/bitvec/blob/main/CHANGELOG.md) - [Commits](https://github.com/bitvecto-rs/bitvec/commits) --- updated-dependencies: - dependency-name: bitvec dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ca7c62e..e0976140 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,9 +51,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitvec" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ "funty", "radium", From e4e7c9fe0e2ed08e1d82bfd248a4c0c6767802d8 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 21 Oct 2022 03:08:54 +0800 Subject: [PATCH 112/286] Document encode_bound, decode_bound and mel_bound (#374) * Document encode_bound, decode_bound and mel_bound * Rewrite docs --- src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index d99db496..db69b2e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -235,6 +235,14 @@ //! - `codec(index = 0)`: Needs to be placed above an enum variant to make the variant use the given //! index when encoded. By default the index is determined by counting from `0` beginning wth the //! first variant. +//! - `codec(encode_bound)`, `codec(decode_bound)` and `codec(mel_bound)`: All 3 attributes take +//! in a `where` clause for the `Encode`, `Decode` and `MaxEncodedLen` trait implementation for +//! the annotated type respectively. +//! - `codec(encode_bound(skip_type_params))`, `codec(decode_bound(skip_type_params))` and +//! `codec(mel_bound(skip_type_params))`: All 3 sub-attributes take in types as arguments to skip +//! trait derivation of the corresponding trait, e.g. T in +//! `codec(encode_bound(skip_type_params(T)))` will not contain a `Encode` trait bound while +//! `Encode` is being derived for the annotated type. #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] From b97d19b00ddd8fa292411d34f2512c529d006387 Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Fri, 25 Nov 2022 11:24:24 +0100 Subject: [PATCH 113/286] [ci] add cargo-nono (#389) * restart pipeline * add nono to ci * add --no-default-features * add build-no-std job * add comment --- .gitlab-ci.yml | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ee7ae05b..b6ea8dce 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,8 +25,7 @@ workflow: - rustc -vV - rustup show - bash --version - - ./scripts/ci/pre_cache.sh - - sccache -s + rules: - if: $CI_PIPELINE_SOURCE == "trigger" - if: $CI_PIPELINE_SOURCE == "web" @@ -54,7 +53,7 @@ check-rust-stable-no_derive_no_std_full: RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array,full - - sccache -s + check-rust-stable-no_derive_no_std: stage: check @@ -63,7 +62,7 @@ check-rust-stable-no_derive_no_std: RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array - - sccache -s + check-rust-stable-no_std-chain-error: stage: check @@ -72,7 +71,7 @@ check-rust-stable-no_std-chain-error: RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --no-default-features --features chain-error - - sccache -s + check-rust-stable-no_derive_full: stage: check @@ -81,7 +80,7 @@ check-rust-stable-no_derive_full: RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --features bit-vec,bytes,generic-array,full - - sccache -s + #### stage: test @@ -92,7 +91,7 @@ test-rust-stable: RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable test --verbose --all --features bit-vec,bytes,generic-array,derive,max-encoded-len - - sccache -s + test-rust-stable-no_derive: stage: test @@ -101,14 +100,12 @@ test-rust-stable-no_derive: RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable test --verbose --features bit-vec,bytes,generic-array - - sccache -s bench-rust-nightly: stage: test <<: *docker-env script: - time cargo +nightly bench --features bit-vec,bytes,generic-array,derive - - sccache -s miri: stage: test @@ -119,6 +116,18 @@ miri: script: - time cargo +nightly miri test --features bit-vec,bytes,generic-array,arbitrary --release +# check that build is no_std compatible +# more info: https://github.com/paritytech/parity-scale-codec/pull/389 +build-no-std: + stage: test + <<: *docker-env + variables: + RUST_BACKTRACE: 1 + script: + # this target doesn't support std envs; it should flag any unexpected uses of std + - rustup target add thumbv6m-none-eabi + - time cargo build --target thumbv6m-none-eabi --no-default-features + #### stage: build build-linux-ubuntu-amd64: @@ -131,4 +140,4 @@ build-linux-ubuntu-amd64: - if: $CI_COMMIT_REF_NAME == "tags" script: - cargo build --verbose --release --features bit-vec,bytes,generic-array,derive - - sccache -s + From fa0f30c24380e420561941e8a5bfcfcd18ec2e6b Mon Sep 17 00:00:00 2001 From: ashWhiteHat Date: Mon, 5 Dec 2022 20:25:27 +0900 Subject: [PATCH 114/286] update compact encoding link (#394) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ff97116..dadbc926 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Returns an `Err` if the decoding fails. ### CompactAs The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes them even more space/memory efficient. -The compact encoding is described [here](https://docs.substrate.io/v3/advanced/scale-codec/#compactgeneral-integers). +The compact encoding is described [here](https://docs.substrate.io/reference/scale-codec/#fnref-1). * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. The type `As` is defined in the same trait and its implementation should be compact encode-able. From 4993588b96db80341e4a8008861e1db16c5831f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 18 Jan 2023 23:37:59 +0100 Subject: [PATCH 115/286] Bump derive & codec version (#401) This brings support for `codec(skip)` for MEL. --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0976140..45e91cbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -429,7 +429,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.2.0" +version = "3.2.2" dependencies = [ "arbitrary", "arrayvec", @@ -449,7 +449,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.3" +version = "3.1.4" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index 2aa7ba6e..fbc2de6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.2.1" +version = "3.2.2" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.139", optional = true } -parity-scale-codec-derive = { path = "derive", version = "3.1.3", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = "3.1.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.1", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index d2f7c929..6fb552b4 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.1.3" +version = "3.1.4" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" From 31078e5a3b093fdef2fe36e378818dd9eb28084a Mon Sep 17 00:00:00 2001 From: Marcin S Date: Thu, 26 Jan 2023 12:03:37 +0100 Subject: [PATCH 116/286] Export `decode_vec_with_len` (#403) * Export `decode_vec_with_len` This is necessary to implement a custom `Decode` for `BoundedVec`. See: https://github.com/paritytech/polkadot/pull/6603#discussion_r1083461147 > You want to ensure that you don't even start try decoding/allocating when the length of the vector is more than the > allowed maximum. > You first decode length of the vector and then early reject if that is too long. * Actually export `decode_vec_with_len` * Bump version --- CHANGELOG.md | 18 +++++++++++++----- Cargo.lock | 2 +- Cargo.toml | 2 +- src/codec.rs | 4 ++-- src/lib.rs | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 931bfc71..a5912491 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,19 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.3.0] + +This release exports `decode_vec_with_len` to support custom decoding of `Vec`s. + +### Added + +- Export `decode_vec_with_len`. + ## [3.2.1] - 2022-09-14 This release fixes compilation on no-std envs. -## Changed +### Changed - Use core RangeInclusive instead of std [#378](https://github.com/paritytech/parity-scale-codec/pull/378) @@ -17,7 +25,7 @@ This release fixes compilation on no-std envs. This release (specifically [#375](https://github.com/paritytech/parity-scale-codec/pull/375)) bumps the MSRV to 1.60.0 as it depends on the Cargo.toml weak dependency feature. -## Changed +### Changed - Don't include bitvec with std feature unless asked for explicitly. [#375](https://github.com/paritytech/parity-scale-codec/pull/375) - Implement `MaxEncodedLen` on more core lib types. [#350](https://github.com/paritytech/parity-scale-codec/pull/350) @@ -26,13 +34,13 @@ This release (specifically [#375](https://github.com/paritytech/parity-scale-cod A quick release to fix an issue introduced in 3.1.4 that broke compiling on no-std. -## Changed +### Changed - Fix compiling on no-std. (see https://github.com/paritytech/parity-scale-codec/commit/c25f14a46546c75e4208363ced9d89aa81c85e7f) ## [3.1.3] - 2022-06-10 -## Changed +### Changed - Impl `MaxEncodedLen` for `Box`. [#349](https://github.com/paritytech/parity-scale-codec/pull/349) - Add `decode_from_bytes`. [#342](https://github.com/paritytech/parity-scale-codec/pull/342) @@ -41,7 +49,7 @@ A quick release to fix an issue introduced in 3.1.4 that broke compiling on no-s Be aware that version 3.0.0. up to 3.1.1 contained some bugs in the `BitVec` encoder that could lead to an invalid encoding. Thus, we yanked these crate version and it is advised to upgrade to 3.1.2. Any release before 3.0.0 wasn't affected by this bug. -## Changed +### Changed - Optimised the `Decode::decode` for `[T; N]` by @xgreenx. [#299](https://github.com/paritytech/parity-scale-codec/pull/299) - Add some doc for the derive macro by @thiolliere. [#301](https://github.com/paritytech/parity-scale-codec/pull/301) diff --git a/Cargo.lock b/Cargo.lock index 45e91cbb..36dc6b6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -429,7 +429,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.2.2" +version = "3.3.0" dependencies = [ "arbitrary", "arrayvec", diff --git a/Cargo.toml b/Cargo.toml index fbc2de6d..2fad6cd2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.2.2" +version = "3.3.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" diff --git a/src/codec.rs b/src/codec.rs index a84c713f..d2d95d37 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -826,11 +826,11 @@ pub(crate) fn decode_array(input: &mut I) - } } -/// Decode the vec (without prepended the len). +/// Decode the vec (without a prepended len). /// /// This is equivalent to decode all elements one by one, but it is optimized in some /// situation. -pub(crate) fn decode_vec_with_len( +pub fn decode_vec_with_len( input: &mut I, len: usize, ) -> Result, Error> { diff --git a/src/lib.rs b/src/lib.rs index db69b2e8..366f3ab3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -295,7 +295,7 @@ mod max_encoded_len; pub use self::error::Error; pub use self::codec::{ Input, Output, Decode, Encode, Codec, EncodeAsRef, WrapperTypeEncode, WrapperTypeDecode, - OptionBool, DecodeLength, FullCodec, FullEncode, + OptionBool, DecodeLength, FullCodec, FullEncode, decode_vec_with_len }; #[cfg(feature = "std")] pub use self::codec::IoReader; From c8dc187be68c2774e23c28aa181291ab44f21cb7 Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Tue, 31 Jan 2023 13:29:27 +0100 Subject: [PATCH 117/286] [ci] change runners (#406) --- .gitlab-ci.yml | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b6ea8dce..28f3a281 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,14 +9,18 @@ stages: variables: GIT_STRATEGY: fetch GIT_DEPTH: "100" - CARGO_TARGET_DIR: "/ci-cache/${CI_PROJECT_NAME}/targets/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}" CARGO_INCREMENTAL: 0 CI_IMAGE: "paritytech/parity-scale-codec:production" -workflow: - rules: - - if: $CI_COMMIT_TAG - - if: $CI_COMMIT_BRANCH +default: + cache: {} + interruptible: true + retry: + max: 2 + when: + - runner_system_failure + - unknown_failure + - api_failure .docker-env: &docker-env image: $CI_IMAGE @@ -25,7 +29,6 @@ workflow: - rustc -vV - rustup show - bash --version - rules: - if: $CI_PIPELINE_SOURCE == "trigger" - if: $CI_PIPELINE_SOURCE == "web" @@ -34,15 +37,8 @@ workflow: - if: $CI_COMMIT_REF_NAME == "tags" - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - interruptible: true - retry: - max: 2 - when: - - runner_system_failure - - unknown_failure - - api_failure tags: - - linux-docker + - linux-docker-vm-c2 #### stage: check From 400f0fd07fd64ade7ea4e6b437cd6cec66767a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Fri, 10 Feb 2023 04:59:44 -0300 Subject: [PATCH 118/286] Remove `full` feature (#408) * Provide seperate feature for string implementations * Revert "Provide seperate feature for string implementations" This reverts commit 8ead7457c8c77c227122777fe30c9fae9c906c94. * Derive for all types even without `full` feature * Adapt PR --- .gitlab-ci.yml | 23 +++++++++++---------- Cargo.toml | 6 +----- src/codec.rs | 55 +++++++++++++++++++------------------------------- 3 files changed, 34 insertions(+), 50 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 28f3a281..aafa2420 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,15 +42,6 @@ default: #### stage: check -check-rust-stable-no_derive_no_std_full: - stage: check - <<: *docker-env - variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - - time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array,full - - check-rust-stable-no_derive_no_std: stage: check <<: *docker-env @@ -69,13 +60,13 @@ check-rust-stable-no_std-chain-error: - time cargo +stable check --verbose --no-default-features --features chain-error -check-rust-stable-no_derive_full: +check-rust-stable-no_derive: stage: check <<: *docker-env variables: RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - - time cargo +stable check --verbose --features bit-vec,bytes,generic-array,full + - time cargo +stable check --verbose --features bit-vec,bytes,generic-array #### stage: test @@ -124,6 +115,16 @@ build-no-std: - rustup target add thumbv6m-none-eabi - time cargo build --target thumbv6m-none-eabi --no-default-features +build-no-atomic-ptrs: + stage: test + <<: *docker-env + variables: + RUST_BACKTRACE: 1 + script: + # this target doesn't have atomic ptrs. Some parts of alloc are not available there + # we want to make sure that this crate still works on those targets + - cargo +nightly check --target bpfel-unknown-none -Zbuild-std="core,alloc" --no-default-features --features generic-array,derive,max-encoded-len,chain-error + #### stage: build build-linux-ubuntu-amd64: diff --git a/Cargo.toml b/Cargo.toml index 2fad6cd2..1148d086 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,11 +51,7 @@ max-encoded-len = ["parity-scale-codec-derive/max-encoded-len"] # Should not be used in a constrained environment. chain-error = [] -# WARNING: DO _NOT_ USE THIS FEATURE IF YOU ARE WORKING ON CONSENSUS CODE!* -# -# Provides implementations for more data structures than just Vec and Box. -# Concretely it will provide parity-scale-codec implementations for many types -# that can be found in std and/or alloc. +# This does not do anthing anymore. Remove with the next major release. full = [] [workspace] diff --git a/src/codec.rs b/src/codec.rs index d2d95d37..1008e4a0 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -43,19 +43,17 @@ use core::num::{ use byte_slice_cast::{AsByteSlice, AsMutByteSlice, ToMutByteSlice}; -#[cfg(any(feature = "std", feature = "full"))] +#[cfg(target_has_atomic = "ptr")] +use crate::alloc::sync::Arc; use crate::alloc::{ - string::String, - sync::Arc, - rc::Rc, -}; -use crate::alloc::{ - vec::Vec, boxed::Box, borrow::{Cow, ToOwned}, collections::{ BTreeMap, BTreeSet, VecDeque, LinkedList, BinaryHeap - } + }, + rc::Rc, + string::String, + vec::Vec, }; use crate::compact::Compact; use crate::encode_like::EncodeLike; @@ -212,10 +210,7 @@ pub enum TypeInfo { I64, U128, I128, - - #[cfg(feature = "full")] F32, - #[cfg(feature = "full")] F64, } @@ -365,24 +360,23 @@ impl<'a, T: ToOwned + Encode + ?Sized> EncodeLike for Cow<'a, T> {} impl<'a, T: ToOwned + Encode> EncodeLike for Cow<'a, T> {} impl<'a, T: ToOwned + Encode> EncodeLike> for T {} -#[cfg(any(feature = "std", feature = "full"))] -mod feature_full_wrapper_type_encode { - use super::*; +impl WrapperTypeEncode for Rc {} +impl EncodeLike for Rc {} +impl EncodeLike for Rc {} +impl EncodeLike> for T {} + +impl WrapperTypeEncode for String {} +impl EncodeLike for String {} +impl EncodeLike<&str> for String {} +impl EncodeLike for &str {} +#[cfg(target_has_atomic = "ptr")] +mod atomic_ptr_targets { + use super::*; impl WrapperTypeEncode for Arc {} impl EncodeLike for Arc {} impl EncodeLike for Arc {} impl EncodeLike> for T {} - - impl WrapperTypeEncode for Rc {} - impl EncodeLike for Rc {} - impl EncodeLike for Rc {} - impl EncodeLike> for T {} - - impl WrapperTypeEncode for String {} - impl EncodeLike for String {} - impl EncodeLike<&str> for String {} - impl EncodeLike for &str {} } #[cfg(feature = "bytes")] @@ -498,12 +492,11 @@ pub trait WrapperTypeDecode: Sized { impl WrapperTypeDecode for Box { type Wrapped = T; } -#[cfg(any(feature = "std", feature = "full"))] -impl WrapperTypeDecode for Arc { +impl WrapperTypeDecode for Rc { type Wrapped = T; } -#[cfg(any(feature = "std", feature = "full"))] -impl WrapperTypeDecode for Rc { +#[cfg(target_has_atomic = "ptr")] +impl WrapperTypeDecode for Arc { type Wrapped = T; } @@ -540,10 +533,7 @@ macro_rules! with_type_info { TypeInfo::U128 => { $macro!(u128 $( $( , $params )* )? ) }, TypeInfo::I128 => { $macro!(i128 $( $( , $params )* )? ) }, TypeInfo::Unknown => { $( $unknown_variant )* }, - - #[cfg(feature = "full")] TypeInfo::F32 => { $macro!(f32 $( $( , $params )* )? ) }, - #[cfg(feature = "full")] TypeInfo::F64 => { $macro!(f64 $( $( , $params )* )? ) }, } }; @@ -941,7 +931,6 @@ impl Decode for PhantomData { } } -#[cfg(any(feature = "std", feature = "full"))] impl Decode for String { fn decode(input: &mut I) -> Result { Self::from_utf8(Vec::decode(input)?).map_err(|_| "Invalid utf8 sequence".into()) @@ -1345,7 +1334,6 @@ macro_rules! impl_one_byte { impl_endians!(u16; U16, u32; U32, u64; U64, u128; U128, i16; I16, i32; I32, i64; I64, i128; I128); impl_one_byte!(u8; U8, i8; I8); -#[cfg(feature = "full")] impl_endians!(f32; F32, f64; F64); impl EncodeLike for bool {} @@ -1888,7 +1876,6 @@ mod tests { test_array_encode_and_decode!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128); - #[cfg(feature = "full")] test_array_encode_and_decode!(f32, f64); fn test_encoded_size(val: impl Encode) { From 5100ef09fcf5cfca4ab42fb4f4258998ff55a394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Fri, 10 Feb 2023 09:49:30 -0300 Subject: [PATCH 119/286] Bump minor version (#409) --- CHANGELOG.md | 9 +++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5912491..c8e9672e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.4.0] + +This release renders the `full` feature defunct. The implementations guarded behind +this feature are now always provided. + +### Changes + +- All implementations guarded behind `full` are not unconditionally implemented. + ## [3.3.0] This release exports `decode_vec_with_len` to support custom decoding of `Vec`s. diff --git a/Cargo.lock b/Cargo.lock index 36dc6b6b..858d3fc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -429,7 +429,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.3.0" +version = "3.4.0" dependencies = [ "arbitrary", "arrayvec", diff --git a/Cargo.toml b/Cargo.toml index 1148d086..8188e331 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.3.0" +version = "3.4.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" From d9350846dd05cca4d3e496722d42989941239020 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Mar 2023 07:49:09 +0100 Subject: [PATCH 120/286] Bump paste from 1.0.6 to 1.0.12 (#411) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 858d3fc8..a23ba070 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -460,9 +460,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.6" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "plotters" From 1ecacab0d839778fa12ba4162ff541b2a7fc0f5b Mon Sep 17 00:00:00 2001 From: Jeff Burdges Date: Sat, 18 Mar 2023 22:14:25 +0100 Subject: [PATCH 121/286] Array size (#413) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Decode size for arrays * Ssome more sizes * Apply suggestions from code review --------- Co-authored-by: ¨Jeff <¨burdges@gnunet.org¨> Co-authored-by: Bastian Köcher --- src/codec.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/codec.rs b/src/codec.rs index 1008e4a0..db46843b 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -889,6 +889,22 @@ impl Decode for [T; N] { fn decode(input: &mut I) -> Result { decode_array(input) } + + fn skip(input: &mut I) -> Result<(), Error> { + if Self::encoded_fixed_size().is_some() { + // Should skip the bytes, but Input does not support skip. + for _ in 0..N { + T::skip(input)?; + } + } else { + Self::decode(input)?; + } + Ok(()) + } + + fn encoded_fixed_size() -> Option { + Some(::encoded_fixed_size()? * N) + } } impl, U: Encode, const N: usize> EncodeLike<[U; N]> for [T; N] {} @@ -1302,6 +1318,10 @@ macro_rules! impl_endians { input.read(&mut buf)?; Ok(<$t>::from_le_bytes(buf)) } + + fn encoded_fixed_size() -> Option { + Some(mem::size_of::<$t>()) + } } )* } } @@ -1357,6 +1377,10 @@ impl Decode for bool { _ => Err("Invalid boolean representation".into()) } } + + fn encoded_fixed_size() -> Option { + Some(1) + } } impl Encode for Duration { From da9a6f621579878e5efc32d8a9b99c5686ca5769 Mon Sep 17 00:00:00 2001 From: Mira Ressel Date: Wed, 29 Mar 2023 14:42:13 +0200 Subject: [PATCH 122/286] Bump ci image (#422) * Bump ci image to new staging version with rust 1.68 * Update ui tests for rust 1.68 --- .gitlab-ci.yml | 2 +- tests/max_encoded_len_ui/crate_str.stderr | 19 +++++++++++---- .../max_encoded_len_ui/incomplete_attr.stderr | 19 +++++++++++---- .../missing_crate_specifier.stderr | 19 +++++++++++---- tests/max_encoded_len_ui/not_encode.stderr | 19 +++++++++++---- tests/max_encoded_len_ui/not_mel.stderr | 23 +++++-------------- .../unsupported_variant.stderr | 4 ++-- 7 files changed, 65 insertions(+), 40 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aafa2420..c8159a1b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,7 +10,7 @@ variables: GIT_STRATEGY: fetch GIT_DEPTH: "100" CARGO_INCREMENTAL: 0 - CI_IMAGE: "paritytech/parity-scale-codec:production" + CI_IMAGE: "paritytech/parity-scale-codec@sha256:ed3d5632087237511cb5c7a6177167d01822bd9b6d8d31789080e014c4491bae" # staging 2023-03-28 default: cache: {} diff --git a/tests/max_encoded_len_ui/crate_str.stderr b/tests/max_encoded_len_ui/crate_str.stderr index a634de8f..c9c46cb1 100644 --- a/tests/max_encoded_len_ui/crate_str.stderr +++ b/tests/max_encoded_len_ui/crate_str.stderr @@ -5,15 +5,24 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = pa | ^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> tests/max_encoded_len_ui/crate_str.rs:3:18 + --> tests/max_encoded_len_ui/crate_str.rs:5:8 | -3 | #[derive(Encode, MaxEncodedLen)] - | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` +5 | struct Example; + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` | - = note: required because of the requirements on the impl of `Encode` for `Example` + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> + = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { | ^^^^^^ required by this bound in `MaxEncodedLen` - = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr index be8ff298..b9c58104 100644 --- a/tests/max_encoded_len_ui/incomplete_attr.stderr +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -5,15 +5,24 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = pa | ^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> tests/max_encoded_len_ui/incomplete_attr.rs:3:18 + --> tests/max_encoded_len_ui/incomplete_attr.rs:5:8 | -3 | #[derive(Encode, MaxEncodedLen)] - | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` +5 | struct Example; + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` | - = note: required because of the requirements on the impl of `Encode` for `Example` + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> + = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { | ^^^^^^ required by this bound in `MaxEncodedLen` - = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/missing_crate_specifier.stderr b/tests/max_encoded_len_ui/missing_crate_specifier.stderr index 8e9eeb27..c056aec9 100644 --- a/tests/max_encoded_len_ui/missing_crate_specifier.stderr +++ b/tests/max_encoded_len_ui/missing_crate_specifier.stderr @@ -5,15 +5,24 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = pa | ^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> tests/max_encoded_len_ui/missing_crate_specifier.rs:3:18 + --> tests/max_encoded_len_ui/missing_crate_specifier.rs:5:8 | -3 | #[derive(Encode, MaxEncodedLen)] - | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` +5 | struct Example; + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` | - = note: required because of the requirements on the impl of `Encode` for `Example` + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> + = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { | ^^^^^^ required by this bound in `MaxEncodedLen` - = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/not_encode.stderr b/tests/max_encoded_len_ui/not_encode.stderr index 0c23bc9f..3e4e57bc 100644 --- a/tests/max_encoded_len_ui/not_encode.stderr +++ b/tests/max_encoded_len_ui/not_encode.stderr @@ -1,13 +1,22 @@ error[E0277]: the trait bound `NotEncode: WrapperTypeEncode` is not satisfied - --> tests/max_encoded_len_ui/not_encode.rs:3:10 + --> tests/max_encoded_len_ui/not_encode.rs:4:8 | -3 | #[derive(MaxEncodedLen)] - | ^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `NotEncode` +4 | struct NotEncode; + | ^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `NotEncode` | - = note: required because of the requirements on the impl of `Encode` for `NotEncode` + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> + = note: required for `NotEncode` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { | ^^^^^^ required by this bound in `MaxEncodedLen` - = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/not_mel.stderr b/tests/max_encoded_len_ui/not_mel.stderr index 1361561f..d0a0891c 100644 --- a/tests/max_encoded_len_ui/not_mel.stderr +++ b/tests/max_encoded_len_ui/not_mel.stderr @@ -2,34 +2,23 @@ error[E0599]: the function or associated item `max_encoded_len` exists for struc --> tests/max_encoded_len_ui/not_mel.rs:12:29 | 4 | struct NotMel; - | -------------- doesn't satisfy `NotMel: MaxEncodedLen` + | ------------- doesn't satisfy `NotMel: MaxEncodedLen` ... 7 | struct Generic { | ----------------- | | - | function or associated item `max_encoded_len` not found for this + | function or associated item `max_encoded_len` not found for this struct | doesn't satisfy `Generic: MaxEncodedLen` ... 12 | let _ = Generic::::max_encoded_len(); | ^^^^^^^^^^^^^^^ function or associated item cannot be called on `Generic` due to unsatisfied trait bounds | -note: the following trait bounds were not satisfied because of the requirements of the implementation of `MaxEncodedLen` for `_`: - `NotMel: MaxEncodedLen` - --> tests/max_encoded_len_ui/not_mel.rs:6:18 - | -6 | #[derive(Encode, MaxEncodedLen)] - | ^^^^^^^^^^^^^ -7 | struct Generic { - | ^^^^^^^^^^ -note: the following trait must be implemented + = note: trait bound `NotMel: MaxEncodedLen` was not satisfied +note: the trait `MaxEncodedLen` must be implemented --> src/max_encoded_len.rs | - | / pub trait MaxEncodedLen: Encode { - | | /// Upper bound, in bytes, of the maximum encoded size of this item. - | | fn max_encoded_len() -> usize; - | | } - | |_^ + | pub trait MaxEncodedLen: Encode { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `max_encoded_len`, perhaps you need to implement it: candidate #1: `MaxEncodedLen` - = note: this error originates in the derive macro `MaxEncodedLen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/unsupported_variant.stderr b/tests/max_encoded_len_ui/unsupported_variant.stderr index 836c544c..bc4acacc 100644 --- a/tests/max_encoded_len_ui/unsupported_variant.stderr +++ b/tests/max_encoded_len_ui/unsupported_variant.stderr @@ -1,8 +1,8 @@ error[E0599]: no function or associated item named `max_encoded_len` found for struct `NotMel` in the current scope - --> $DIR/unsupported_variant.rs:8:9 + --> tests/max_encoded_len_ui/unsupported_variant.rs:8:9 | 4 | struct NotMel; - | -------------- function or associated item `max_encoded_len` not found for this + | ------------- function or associated item `max_encoded_len` not found for this struct ... 8 | NotMel(NotMel), | ^^^^^^ function or associated item not found in `NotMel` From b0099e80b1f6f09ab5cffe27794a11e134403b49 Mon Sep 17 00:00:00 2001 From: Mira Ressel Date: Wed, 29 Mar 2023 17:26:27 +0200 Subject: [PATCH 123/286] Move back to parity-scale-codec:production image (#423) New production image has gone live. --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c8159a1b..aafa2420 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,7 +10,7 @@ variables: GIT_STRATEGY: fetch GIT_DEPTH: "100" CARGO_INCREMENTAL: 0 - CI_IMAGE: "paritytech/parity-scale-codec@sha256:ed3d5632087237511cb5c7a6177167d01822bd9b6d8d31789080e014c4491bae" # staging 2023-03-28 + CI_IMAGE: "paritytech/parity-scale-codec:production" default: cache: {} From 5c201fb765fa48813f3b0b937a76b258000dae84 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 3 May 2023 22:05:03 +0200 Subject: [PATCH 124/286] Make tests build (#429) * CI: Build only with MEL feature Signed-off-by: Oliver Tale-Yazdi * Add failing CI Signed-off-by: Oliver Tale-Yazdi * Fix tests by aliasing derive Signed-off-by: Oliver Tale-Yazdi * More fixes Signed-off-by: Oliver Tale-Yazdi * Feature ignore examples Signed-off-by: Oliver Tale-Yazdi * Fix doctest imports Signed-off-by: Oliver Tale-Yazdi * Update .gitlab-ci.yml Co-authored-by: Marcin S. --------- Signed-off-by: Oliver Tale-Yazdi Co-authored-by: Marcin S. --- .gitlab-ci.yml | 24 ++++++++++- src/lib.rs | 21 +++------- tests/chain-error.rs | 11 +++-- tests/mod.rs | 59 +++++++++++++-------------- tests/single_field_struct_encoding.rs | 29 ++++++------- tests/skip.rs | 12 +++--- tests/type_inference.rs | 7 ++-- tests/variant_number.rs | 9 ++-- 8 files changed, 89 insertions(+), 83 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aafa2420..7ba348f3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -68,6 +68,13 @@ check-rust-stable-no_derive: script: - time cargo +stable check --verbose --features bit-vec,bytes,generic-array +check-rust-stable-only_mel: + stage: check + <<: *docker-env + variables: + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + script: + - time cargo +stable check --verbose --features max-encoded-len #### stage: test @@ -88,6 +95,22 @@ test-rust-stable-no_derive: script: - time cargo +stable test --verbose --features bit-vec,bytes,generic-array +test-rust-stable-only_mel: + stage: test + <<: *docker-env + variables: + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + script: + - time cargo +stable test --verbose --features max-encoded-len + +test-rust-stable-only_mel-no_default_std: + stage: test + <<: *docker-env + variables: + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + script: + - time cargo +stable test --verbose --features max-encoded-len,std --no-default-features + bench-rust-nightly: stage: test <<: *docker-env @@ -137,4 +160,3 @@ build-linux-ubuntu-amd64: - if: $CI_COMMIT_REF_NAME == "tags" script: - cargo build --verbose --release --features bit-vec,bytes,generic-array,derive - diff --git a/src/lib.rs b/src/lib.rs index 366f3ab3..49539616 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -91,11 +91,8 @@ //! //! ### Simple types //! -//! ``` -//! # // Import macros if derive feature is not used. -//! # #[cfg(not(feature="derive"))] -//! # use parity_scale_codec_derive::{Encode, Decode}; -//! +#![cfg_attr(feature = "derive", doc = "```rust")] +#![cfg_attr(not(feature = "derive"), doc = "*(Only compiled with feature `derive`)*\n```ignore")] //! use parity_scale_codec::{Encode, Decode}; //! //! #[derive(Debug, PartialEq, Encode, Decode)] @@ -142,11 +139,8 @@ //! //! ### Compact type with HasCompact //! -//! ``` -//! # // Import macros if derive feature is not used. -//! # #[cfg(not(feature="derive"))] -//! # use parity_scale_codec_derive::{Encode, Decode}; -//! +#![cfg_attr(feature = "derive", doc = "```rust")] +#![cfg_attr(not(feature = "derive"), doc = "*(Only compiled with feature `derive`)*\n```ignore")] //! use parity_scale_codec::{Encode, Decode, Compact, HasCompact}; //! //! #[derive(Debug, PartialEq, Encode, Decode)] @@ -171,11 +165,8 @@ //! ``` //! ### Type with CompactAs //! -//! ```rust -//! # // Import macros if derive feature is not used. -//! # #[cfg(not(feature="derive"))] -//! # use parity_scale_codec_derive::{Encode, Decode}; -//! +#![cfg_attr(feature = "derive", doc = "```rust")] +#![cfg_attr(not(feature = "derive"), doc = "*(Only compiled with feature `derive`)*\n```ignore")] //! use serde_derive::{Serialize, Deserialize}; //! use parity_scale_codec::{Encode, Decode, Compact, HasCompact, CompactAs, Error}; //! diff --git a/tests/chain-error.rs b/tests/chain-error.rs index 6a106ae2..b8c764be 100644 --- a/tests/chain-error.rs +++ b/tests/chain-error.rs @@ -12,22 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[cfg(not(feature="derive"))] -use parity_scale_codec_derive::Decode; +use parity_scale_codec_derive::Decode as DeriveDecode; use parity_scale_codec::Decode; -#[derive(Decode, Debug)] +#[derive(DeriveDecode, Debug)] struct Wrapper(T); -#[derive(Decode, Debug)] +#[derive(DeriveDecode, Debug)] struct StructNamed { _foo: u16 } -#[derive(Decode, Debug)] +#[derive(DeriveDecode, Debug)] struct StructUnnamed(u16); -#[derive(Decode, Debug)] +#[derive(DeriveDecode, Debug)] enum E { VariantNamed { _foo: u16, }, VariantUnnamed(u16), diff --git a/tests/mod.rs b/tests/mod.rs index 7d6a0ee3..ac6e3fd3 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -15,24 +15,23 @@ use parity_scale_codec::{ Compact, CompactAs, Decode, Encode, EncodeAsRef, Error, HasCompact, Output, }; -#[cfg(not(feature = "derive"))] -use parity_scale_codec_derive::{Decode, Encode}; +use parity_scale_codec_derive::{Decode as DeriveDecode, Encode as DeriveEncode}; use serde_derive::{Deserialize, Serialize}; -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct Unit; -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct Indexed(u32, u64); -#[derive(Debug, PartialEq, Encode, Decode, Default)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] struct Struct { pub a: A, pub b: B, pub c: C, } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct StructWithPhantom { pub a: u32, pub b: u64, @@ -47,7 +46,7 @@ impl Struct { } } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] enum EnumType { #[codec(index = 15)] A, @@ -58,26 +57,26 @@ enum EnumType { }, } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] enum EnumWithDiscriminant { A = 1, B = 15, C = 255, } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct TestHasCompact { #[codec(encoded_as = "::Type")] bar: T, } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct TestCompactHasCompact { #[codec(compact)] bar: T, } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] enum TestHasCompactEnum { Unnamed(#[codec(encoded_as = "::Type")] T), Named { @@ -91,13 +90,13 @@ enum TestHasCompactEnum { }, } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct TestCompactAttribute { #[codec(compact)] bar: u64, } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] enum TestCompactAttributeEnum { Unnamed(#[codec(compact)] u64), Named { @@ -330,7 +329,7 @@ fn associated_type_bounds() { type NonEncodableType; } - #[derive(Encode, Decode, Debug, PartialEq)] + #[derive(DeriveEncode, DeriveDecode, Debug, PartialEq)] struct Struct { field: (Vec, Type), } @@ -372,7 +371,7 @@ fn generic_bound_encoded_as() { type RefType = &'a u32; } - #[derive(Debug, PartialEq, Encode, Decode)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct TestGeneric> where u32: for<'a> EncodeAsRef<'a, A>, @@ -408,7 +407,7 @@ fn generic_bound_hascompact() { } } - #[derive(Debug, PartialEq, Encode, Decode)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] enum TestGenericHasCompact { A { #[codec(compact)] @@ -429,14 +428,14 @@ fn generic_trait() { struct StructNoCodec; - #[derive(Debug, PartialEq, Encode, Decode)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct StructCodec; impl TraitNoCodec for StructNoCodec { type Type = StructCodec; } - #[derive(Debug, PartialEq, Encode, Decode)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct TestGenericTrait { t: T::Type, } @@ -448,7 +447,7 @@ fn generic_trait() { #[test] fn recursive_variant_1_encode_works() { - #[derive(Debug, PartialEq, Encode, Decode, Default)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] struct Recursive { data: N, other: Vec>, @@ -460,7 +459,7 @@ fn recursive_variant_1_encode_works() { #[test] fn recursive_variant_2_encode_works() { - #[derive(Debug, PartialEq, Encode, Decode, Default)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] struct Recursive { data: N, other: Vec>>, @@ -476,10 +475,10 @@ fn private_type_in_where_bound() { // an error. #![deny(warnings)] - #[derive(Debug, PartialEq, Encode, Decode, Default)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] struct Private; - #[derive(Debug, PartialEq, Encode, Decode, Default)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] #[codec(dumb_trait_bound)] pub struct Test { data: Vec<(N, Private)>, @@ -491,7 +490,7 @@ fn private_type_in_where_bound() { #[test] fn encode_decode_empty_enum() { - #[derive(Encode, Decode, PartialEq, Debug)] + #[derive(DeriveEncode, DeriveDecode, PartialEq, Debug)] enum EmptyEnumDerive {} fn impls_encode_decode() {} @@ -513,13 +512,13 @@ fn codec_vec_u8() { #[test] fn recursive_type() { - #[derive(Encode, Decode)] + #[derive(DeriveEncode, DeriveDecode)] pub enum Foo { T(Box), A, } - #[derive(Encode, Decode)] + #[derive(DeriveEncode, DeriveDecode)] pub struct Bar { field: Foo, } @@ -567,7 +566,7 @@ fn weird_derive() { }; } - make_struct!(#[derive(Encode, Decode)]); + make_struct!(#[derive(DeriveEncode, DeriveDecode)]); } #[test] @@ -577,7 +576,7 @@ fn output_trait_object() { #[test] fn custom_trait_bound() { - #[derive(Encode, Decode)] + #[derive(DeriveEncode, DeriveDecode)] #[codec(encode_bound(N: Encode, T: Default))] #[codec(decode_bound(N: Decode, T: Default))] struct Something { @@ -585,7 +584,7 @@ fn custom_trait_bound() { val: N, } - #[derive(Encode, Decode)] + #[derive(DeriveEncode, DeriveDecode)] #[codec(encode_bound())] #[codec(decode_bound())] struct Hello { @@ -620,7 +619,7 @@ fn bit_vec_works() { assert_eq!(original_vec, original_vec_clone); - #[derive(Decode, Encode, PartialEq, Debug)] + #[derive(DeriveDecode, DeriveEncode, PartialEq, Debug)] struct MyStruct { v: BitVec, x: u8, @@ -637,7 +636,7 @@ fn bit_vec_works() { #[test] fn no_warning_for_deprecated() { - #[derive(Encode, Decode)] + #[derive(DeriveEncode, DeriveDecode)] pub enum MyEnum { VariantA, #[deprecated] diff --git a/tests/single_field_struct_encoding.rs b/tests/single_field_struct_encoding.rs index 5f51892c..cbf5cf66 100644 --- a/tests/single_field_struct_encoding.rs +++ b/tests/single_field_struct_encoding.rs @@ -1,17 +1,14 @@ -#[cfg(not(feature="derive"))] -use parity_scale_codec_derive::{Encode, Decode, CompactAs}; -#[cfg(feature="derive")] -use parity_scale_codec::CompactAs; +use parity_scale_codec_derive::{Encode as DeriveEncode, Decode as DeriveDecode, CompactAs as DeriveCompactAs}; use parity_scale_codec::{Compact, Decode, Encode, HasCompact}; use serde_derive::{Serialize, Deserialize}; -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct S { x: u32, } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode, CompactAs)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] struct SSkip { #[codec(skip)] s1: u32, @@ -20,43 +17,43 @@ struct SSkip { s2: u32, } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct Sc { #[codec(compact)] x: u32, } -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct Sh { #[codec(encoded_as = "::Type")] x: T, } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode, CompactAs)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] struct U(u32); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode, CompactAs)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] struct U2 { a: u64 } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode, CompactAs)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] struct USkip(#[codec(skip)] u32, u32, #[codec(skip)] u32); -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct Uc(#[codec(compact)] u32); -#[derive(Debug, PartialEq, Clone, Encode, Decode)] +#[derive(Debug, PartialEq, Clone, DeriveEncode, DeriveDecode)] struct Ucas(#[codec(compact)] U); -#[derive(Debug, PartialEq, Clone, Encode, Decode)] +#[derive(Debug, PartialEq, Clone, DeriveEncode, DeriveDecode)] struct USkipcas(#[codec(compact)] USkip); -#[derive(Debug, PartialEq, Clone, Encode, Decode)] +#[derive(Debug, PartialEq, Clone, DeriveEncode, DeriveDecode)] struct SSkipcas(#[codec(compact)] SSkip); -#[derive(Debug, PartialEq, Encode, Decode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct Uh(#[codec(encoded_as = "::Type")] T); #[test] diff --git a/tests/skip.rs b/tests/skip.rs index f792352d..0c9439cf 100644 --- a/tests/skip.rs +++ b/tests/skip.rs @@ -1,5 +1,4 @@ -#[cfg(not(feature="derive"))] -use parity_scale_codec_derive::{Encode, Decode}; +use parity_scale_codec_derive::{Encode as DeriveEncode, Decode as DeriveDecode}; use parity_scale_codec::{Encode, Decode}; #[test] @@ -10,7 +9,8 @@ fn enum_struct_test() { #[derive(PartialEq, Debug)] struct UncodecUndefaultType; - #[derive(PartialEq, Debug, Encode, Decode)] +use parity_scale_codec_derive::{Encode as DeriveEncode, Decode as DeriveDecode}; + #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode)] enum Enum { #[codec(skip)] A(S), @@ -26,14 +26,14 @@ fn enum_struct_test() { ), } - #[derive(PartialEq, Debug, Encode, Decode)] + #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode)] struct StructNamed { #[codec(skip)] a: T, b: u32, } - #[derive(PartialEq, Debug, Encode, Decode)] + #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode)] struct StructUnnamed( #[codec(skip)] T, @@ -64,7 +64,7 @@ fn skip_enum_struct_inner_variant() { // Make sure the skipping does not generates a warning. #![deny(warnings)] - #[derive(Encode, Decode)] + #[derive(DeriveEncode, DeriveDecode)] enum Enum { Data { some_named: u32, diff --git a/tests/type_inference.rs b/tests/type_inference.rs index acc12e04..97967632 100644 --- a/tests/type_inference.rs +++ b/tests/type_inference.rs @@ -14,8 +14,7 @@ //! Test for type inference issue in decode. -#[cfg(not(feature = "derive"))] -use parity_scale_codec_derive::Decode; +use parity_scale_codec_derive::Decode as DeriveDecode; use parity_scale_codec::Decode; pub trait Trait { @@ -23,7 +22,7 @@ pub trait Trait { type AccountId: Decode; } -#[derive(Decode)] +#[derive(DeriveDecode)] pub enum A { _C( (T::AccountId, T::AccountId), @@ -31,5 +30,5 @@ pub enum A { ), } -#[derive(Decode)] +#[derive(DeriveDecode)] pub struct B((T::AccountId, T::AccountId), Vec<(T::Value, T::Value)>); diff --git a/tests/variant_number.rs b/tests/variant_number.rs index a7113712..54a900d3 100644 --- a/tests/variant_number.rs +++ b/tests/variant_number.rs @@ -1,10 +1,9 @@ -#[cfg(not(feature="derive"))] -use parity_scale_codec_derive::Encode; +use parity_scale_codec_derive::Encode as DeriveEncode; use parity_scale_codec::Encode; #[test] fn discriminant_variant_counted_in_default_index() { - #[derive(Encode)] + #[derive(DeriveEncode)] enum T { A = 1, B, @@ -16,7 +15,7 @@ fn discriminant_variant_counted_in_default_index() { #[test] fn skipped_variant_not_counted_in_default_index() { - #[derive(Encode)] + #[derive(DeriveEncode)] enum T { #[codec(skip)] A, @@ -29,7 +28,7 @@ fn skipped_variant_not_counted_in_default_index() { #[test] fn index_attr_variant_counted_and_reused_in_default_index() { - #[derive(Encode)] + #[derive(DeriveEncode)] enum T { #[codec(index = 1)] A, From 45026784eaad7c8596f55b2ea828ac7933c431ff Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 4 May 2023 12:59:59 +0200 Subject: [PATCH 125/286] Add `ConstEncodedLen` (#428) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add ConstEncodedLen Signed-off-by: Oliver Tale-Yazdi * Update Cargo.lock Seems all to come from the 'proptest'. But the the 'quickcheck' is unmaintained, so rather not using it. Signed-off-by: Oliver Tale-Yazdi * Update src/const_encoded_len.rs Co-authored-by: Bastian Köcher * Import Box Signed-off-by: Oliver Tale-Yazdi * Add CHANGELOG 3.5.0 Signed-off-by: Oliver Tale-Yazdi * Bump to v3.5.0 Signed-off-by: Oliver Tale-Yazdi * Use master Cargo.lock + cargo t Just to ensure that there is no accidential update of the lock. Signed-off-by: Oliver Tale-Yazdi * Make CEL a marker trait Signed-off-by: Oliver Tale-Yazdi --------- Signed-off-by: Oliver Tale-Yazdi Co-authored-by: Bastian Köcher --- CHANGELOG.md | 6 + Cargo.lock | 372 ++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 +- src/const_encoded_len.rs | 159 +++++++++++++++++ src/lib.rs | 5 + 5 files changed, 537 insertions(+), 8 deletions(-) create mode 100644 src/const_encoded_len.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e9672e..482e4684 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.5.0] + +### Added + +- `ConstEncodedLen` marker trait for types that implement `MaxEncodedLen`. [#428](https://github.com/paritytech/parity-scale-codec/pull/428) + ## [3.4.0] This release renders the `full` feature defunct. The implementations guarded behind diff --git a/Cargo.lock b/Cargo.lock index a23ba070..6542fb9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,7 +32,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -43,6 +43,21 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -85,6 +100,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87c5fdd0166095e1d463fc6cc01aa8ce547ad77a4e84d42eb6762b084e28067e" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.1.0" @@ -100,6 +121,12 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" @@ -256,6 +283,42 @@ dependencies = [ "regex", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "funty" version = "2.0.0" @@ -304,6 +367,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "honggfuzz" version = "0.5.54" @@ -326,6 +395,26 @@ dependencies = [ "syn", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "itertools" version = "0.10.1" @@ -358,9 +447,21 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.108" +version = "0.2.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" + +[[package]] +name = "libm" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" + +[[package]] +name = "linux-raw-sys" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" +checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c" [[package]] name = "log" @@ -398,11 +499,12 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -411,7 +513,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] @@ -429,7 +531,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "parity-scale-codec" -version = "3.4.0" +version = "3.5.0" dependencies = [ "arbitrary", "arrayvec", @@ -441,6 +543,7 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec-derive", "paste", + "proptest", "quickcheck", "serde", "serde_derive", @@ -492,6 +595,12 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro-crate" version = "1.1.0" @@ -511,6 +620,39 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f1b898011ce9595050a68e60f90bad083ff2987a695a42357134c8381fba70" +dependencies = [ + "bit-set", + "bitflags", + "byteorder", + "lazy_static", + "num-traits", + "quick-error 2.0.1", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quickcheck" version = "1.0.3" @@ -543,6 +685,18 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", "rand_core", ] @@ -555,6 +709,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + [[package]] name = "rayon" version = "1.5.1" @@ -580,6 +743,15 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.5.6" @@ -612,6 +784,32 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" version = "1.0.5" @@ -694,6 +892,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.45.0", +] + [[package]] name = "termcolor" version = "1.1.2" @@ -772,6 +983,12 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-ident" version = "1.0.1" @@ -790,6 +1007,15 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.3.2" @@ -902,6 +1128,138 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "wyz" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 8188e331..179ea720 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.4.0" +version = "3.5.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -25,6 +25,7 @@ criterion = "0.3.0" serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" +proptest = "1.1.0" trybuild = "1.0.63" paste = "1" diff --git a/src/const_encoded_len.rs b/src/const_encoded_len.rs new file mode 100644 index 00000000..6a0ee33c --- /dev/null +++ b/src/const_encoded_len.rs @@ -0,0 +1,159 @@ +// Copyright (C) 2023 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. + +//! Contains the [`ConstEncodedLen`] trait. + +use crate::MaxEncodedLen; +use core::{ + marker::PhantomData, + num::*, + ops::{Range, RangeInclusive}, + time::Duration, +}; +use crate::alloc::boxed::Box; +use impl_trait_for_tuples::impl_for_tuples; + +/// Types that have a constant encoded length. This implies [`MaxEncodedLen`]. +/// +/// No derive macros is provided; instead use an empty implementation like for a marker trait. +pub trait ConstEncodedLen: MaxEncodedLen {} + +#[impl_for_tuples(18)] +impl ConstEncodedLen for Tuple { } + +impl ConstEncodedLen for [T; N] { } + +/// Mark `T` or `T` as `CEL`. +macro_rules! mark_cel { + ( $($n:ident <$t:ident>),+ ) => { + $( + impl<$t: ConstEncodedLen> ConstEncodedLen for $n<$t> { } + )+ + }; + ( $($t:ty),+ ) => { + $( + impl ConstEncodedLen for $t { } + )+ + }; +} + +mark_cel!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, bool); +mark_cel!(NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128); + +mark_cel!(Duration); +mark_cel!(PhantomData); +mark_cel!(Box); +mark_cel!(Range, RangeInclusive); + +// `Option`, `Result` and `Compact` are sum types, therefore not `CEL`. + +#[cfg(test)] +mod tests { + use super::*; + use crate::Encode; + use proptest::prelude::*; + + /// Test that some random instances of `T` have encoded len `T::max_encoded_len()`. + macro_rules! test_cel_compliance { + ( $( $t:ty ),+ ) => { + $( + paste::paste! { + proptest::proptest! { + #[test] + fn [< cel_compliance_ $t:snake >](x: $t) { + prop_assert_eq!(x.encode().len(), $t::max_encoded_len()); + } + } + } + )* + }; + } + + type Void = (); + test_cel_compliance!(Void); + + test_cel_compliance!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, bool); + + type TupleArithmetic = (u8, u16, u32, u64, u128, i8, i16, i32, i64, i128); + test_cel_compliance!(TupleArithmetic); + + test_cel_compliance!( + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128, + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroI128 + ); + + type TupleNonZero = ( + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128, + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroI128, + ); + test_cel_compliance!(TupleNonZero); + + type ArrayArithmetic = [(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128); 10]; + test_cel_compliance!(ArrayArithmetic); + + test_cel_compliance!(Duration); + + type BoxedArithmetic = Box<(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128)>; + test_cel_compliance!(BoxedArithmetic); + + type PhantomArithmetic = PhantomData<(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128)>; + test_cel_compliance!(PhantomArithmetic); + + type Ranges = (Range, Range, Range, Range, Range); + test_cel_compliance!(Ranges); + + type Ranges2D = ( + Range<(u8, u8)>, + Range<(u16, u16)>, + Range<(u32, u32)>, + Range<(u64, u64)>, + Range<(u128, u128)>, + ); + test_cel_compliance!(Ranges2D); + + type RangesInc = ( + RangeInclusive, + RangeInclusive, + RangeInclusive, + RangeInclusive, + RangeInclusive, + ); + test_cel_compliance!(RangesInc); + + type RangesInc2D = ( + RangeInclusive<(u8, u8)>, + RangeInclusive<(u16, u16)>, + RangeInclusive<(u32, u32)>, + RangeInclusive<(u64, u64)>, + RangeInclusive<(u128, u128)>, + ); + test_cel_compliance!(RangesInc2D); +} diff --git a/src/lib.rs b/src/lib.rs index 49539616..ea999180 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -282,6 +282,8 @@ mod encode_like; mod error; #[cfg(feature = "max-encoded-len")] mod max_encoded_len; +#[cfg(feature = "max-encoded-len")] +mod const_encoded_len; pub use self::error::Error; pub use self::codec::{ @@ -299,6 +301,9 @@ pub use self::encode_append::EncodeAppend; pub use self::encode_like::{EncodeLike, Ref}; #[cfg(feature = "max-encoded-len")] pub use max_encoded_len::MaxEncodedLen; +#[cfg(feature = "max-encoded-len")] +pub use const_encoded_len::ConstEncodedLen; + /// Derive macro for [`MaxEncodedLen`][max_encoded_len::MaxEncodedLen]. /// /// # Examples From 66b828a9809d8b0a4647bc5af734fe514b41fae9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 May 2023 20:53:46 +0200 Subject: [PATCH 126/286] Bump quote from 1.0.10 to 1.0.26 (#420) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- derive/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6542fb9f..5bd30b64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -613,9 +613,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.40" +version = "1.0.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" dependencies = [ "unicode-ident", ] @@ -666,9 +666,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.10" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 6fb552b4..ceee2f4a 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.2" +quote = "1.0.26" proc-macro2 = "1.0.6" proc-macro-crate = "1.0.0" From ecb1ae59778187bb8a8f78804cae9714e2e8821b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 May 2023 23:37:24 +0200 Subject: [PATCH 127/286] Bump proc-macro-crate from 1.1.0 to 1.1.3 (#356) Bumps [proc-macro-crate](https://github.com/bkchr/proc-macro-crate) from 1.1.0 to 1.1.3. - [Release notes](https://github.com/bkchr/proc-macro-crate/releases) - [Commits](https://github.com/bkchr/proc-macro-crate/commits) --- updated-dependencies: - dependency-name: proc-macro-crate dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5bd30b64..1dfbf1d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -603,9 +603,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ "thiserror", "toml", diff --git a/derive/Cargo.toml b/derive/Cargo.toml index ceee2f4a..6c852b63 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.26" proc-macro2 = "1.0.6" -proc-macro-crate = "1.0.0" +proc-macro-crate = "1.1.3" [dev-dependencies] parity-scale-codec = { path = "..", features = ["max-encoded-len"] } From 3ec380bf4add4731c663c93f21ec8d0b47ab1824 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 23:42:27 +0200 Subject: [PATCH 128/286] Bump bumpalo from 3.8.0 to 3.12.0 (#402) Bumps [bumpalo](https://github.com/fitzgen/bumpalo) from 3.8.0 to 3.12.0. - [Release notes](https://github.com/fitzgen/bumpalo/releases) - [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md) - [Commits](https://github.com/fitzgen/bumpalo/compare/3.8.0...3.12.0) --- updated-dependencies: - dependency-name: bumpalo dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1dfbf1d3..8c9352c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,9 +90,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "byte-slice-cast" From f481d79e6a13e3e4810287253e1713fda363dc01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 23:42:45 +0200 Subject: [PATCH 129/286] Bump serde_derive from 1.0.130 to 1.0.162 (#430) Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.130 to 1.0.162. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.130...1.0.162) --- updated-dependencies: - dependency-name: serde_derive dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c9352c1..3648c491 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -264,7 +264,7 @@ checksum = "b24629208e87a2d8b396ff43b15c4afb0a69cea3fbbaa9ed9b92b7c02f0aed73" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -392,7 +392,7 @@ checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -558,7 +558,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -855,13 +855,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.12", ] [[package]] @@ -886,6 +886,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tap" version = "1.0.1" @@ -940,7 +951,7 @@ checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -1054,7 +1065,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 1.0.98", "wasm-bindgen-shared", ] @@ -1076,7 +1087,7 @@ checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From ceeb59ceb1a5c1af0c6bf1706274befc70ec7047 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 May 2023 10:37:11 +0200 Subject: [PATCH 130/286] Bump byte-slice-cast from 1.2.1 to 1.2.2 (#431) Bumps [byte-slice-cast](https://github.com/sdroege/bytes-num-slice-cast) from 1.2.1 to 1.2.2. - [Changelog](https://github.com/sdroege/byte-slice-cast/blob/master/CHANGELOG.md) - [Commits](https://github.com/sdroege/bytes-num-slice-cast/compare/1.2.1...1.2.2) --- updated-dependencies: - dependency-name: byte-slice-cast dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3648c491..0cdf9114 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,9 +96,9 @@ checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "byte-slice-cast" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c5fdd0166095e1d463fc6cc01aa8ce547ad77a4e84d42eb6762b084e28067e" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "byteorder" diff --git a/Cargo.toml b/Cargo.toml index 179ea720..5f3eee71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ serde = { version = "1.0.139", optional = true } parity-scale-codec-derive = { path = "derive", version = "3.1.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } -byte-slice-cast = { version = "1.2.1", default-features = false } +byte-slice-cast = { version = "1.2.2", default-features = false } generic-array = { version = "0.14.5", optional = true } arbitrary = { version = "1.0.1", features = ["derive"], optional = true } impl-trait-for-tuples = "0.2.2" From 2121928e550e8e5058f7bf9ed6222e8d3ba0351e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 23:02:32 +0200 Subject: [PATCH 131/286] Bump serde from 1.0.139 to 1.0.162 (#433) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.139 to 1.0.162. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.139...1.0.162) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0cdf9114..5f7b3645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -839,9 +839,9 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.139" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" [[package]] name = "serde_cbor" diff --git a/Cargo.toml b/Cargo.toml index 5f3eee71..5f8a72e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.139", optional = true } +serde = { version = "1.0.162", optional = true } parity-scale-codec-derive = { path = "derive", version = "3.1.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 02596c4258d548582ab2288a1733b3568bc7bdfe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 23:02:43 +0200 Subject: [PATCH 132/286] Bump trybuild from 1.0.63 to 1.0.80 (#434) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.63 to 1.0.80. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.63...1.0.80) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 15 ++++++++++++--- Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f7b3645..fcfd10c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,6 +43,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "basic-toml" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" +dependencies = [ + "serde", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -975,17 +984,17 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.63" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "764b9e244b482a9b81bde596aa37aa6f1347bf8007adab25e59f901b32b4e0a0" +checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a" dependencies = [ + "basic-toml", "glob", "once_cell", "serde", "serde_derive", "serde_json", "termcolor", - "toml", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5f8a72e5..be67f7c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.1.0" -trybuild = "1.0.63" +trybuild = "1.0.80" paste = "1" [[bench]] From aaea65ab7b7d0cded3e37f42a819ccedb5db645f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 18:14:32 +0200 Subject: [PATCH 133/286] Bump proc-macro2 from 1.0.54 to 1.0.56 (#436) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.54 to 1.0.56. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.54...1.0.56) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fcfd10c3..f55844ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -622,9 +622,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.54" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 6c852b63..bc48c4b3 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.26" -proc-macro2 = "1.0.6" +proc-macro2 = "1.0.56" proc-macro-crate = "1.1.3" [dev-dependencies] From 4170fc7abcc05f1b603c0e21d94684a1f43cba5a Mon Sep 17 00:00:00 2001 From: Koute Date: Wed, 17 May 2023 05:44:38 +0900 Subject: [PATCH 134/286] Implement `MaxEncodedLen` for `Arc` (#439) * Implement `MaxEncodedLen` for `Arc` * Support targets with no `Arc` --- src/max_encoded_len.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs index b4c0d878..c26ccf97 100644 --- a/src/max_encoded_len.rs +++ b/src/max_encoded_len.rs @@ -20,6 +20,9 @@ use impl_trait_for_tuples::impl_for_tuples; use core::{mem, marker::PhantomData, num::*, ops::{Range, RangeInclusive}, time::Duration}; use crate::alloc::boxed::Box; +#[cfg(target_has_atomic = "ptr")] +use crate::alloc::sync::Arc; + /// Items implementing `MaxEncodedLen` have a statically known maximum encoded size. /// /// Some containers, such as `BoundedVec`, have enforced size limits and this trait @@ -97,6 +100,13 @@ impl MaxEncodedLen for Box { } } +#[cfg(target_has_atomic = "ptr")] +impl MaxEncodedLen for Arc { + fn max_encoded_len() -> usize { + T::max_encoded_len() + } +} + impl MaxEncodedLen for Option { fn max_encoded_len() -> usize { T::max_encoded_len().saturating_add(1) From b91d05bfb8cbbe709090cd5b44a0b73b43a79871 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 23:30:37 +0200 Subject: [PATCH 135/286] Bump quote from 1.0.26 to 1.0.27 (#438) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.26 to 1.0.27. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.26...1.0.27) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f55844ea..12f2ed57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -675,9 +675,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index bc48c4b3..139748bf 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.26" +quote = "1.0.27" proc-macro2 = "1.0.56" proc-macro-crate = "1.1.3" From dffa5c79cd5b6d70c33bb2e79032f28db2e5122f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 21:56:31 +0200 Subject: [PATCH 136/286] Bump proc-macro2 from 1.0.56 to 1.0.58 (#440) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.56 to 1.0.58. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.56...1.0.58) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12f2ed57..ad1a004e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -622,9 +622,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 139748bf..07ccb75c 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.27" -proc-macro2 = "1.0.56" +proc-macro2 = "1.0.58" proc-macro-crate = "1.1.3" [dev-dependencies] From 3f3728859888cae8c8515a19b34f0eddfa7cf4da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 23:41:34 +0200 Subject: [PATCH 137/286] Bump serde_derive from 1.0.162 to 1.0.163 (#441) Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.162 to 1.0.163. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.162...v1.0.163) --- updated-dependencies: - dependency-name: serde_derive dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ad1a004e..50d7b457 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -864,9 +864,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", From 9f4e45257f09865315c60e7be4125d68923eed9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 20:30:57 +0200 Subject: [PATCH 138/286] Bump serde from 1.0.162 to 1.0.163 (#442) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.162 to 1.0.163. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.162...v1.0.163) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 50d7b457..a9e426f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -848,9 +848,9 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" [[package]] name = "serde_cbor" diff --git a/Cargo.toml b/Cargo.toml index be67f7c8..5dff0985 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.162", optional = true } +serde = { version = "1.0.163", optional = true } parity-scale-codec-derive = { path = "derive", version = "3.1.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From ad10bddc95ad5810489618f8c5c50cae506dece9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 20:31:10 +0200 Subject: [PATCH 139/286] Bump bytes from 1.1.0 to 1.4.0 (#437) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.1.0 to 1.4.0. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.1.0...v1.4.0) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9e426f2..88e7c888 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,9 +117,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cast" From 44f2093822cafcab823d8734e22d1257adfcc261 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 22:48:25 +0200 Subject: [PATCH 140/286] Bump generic-array from 0.14.5 to 0.14.7 (#444) Bumps [generic-array](https://github.com/fizyk20/generic-array) from 0.14.5 to 0.14.7. - [Release notes](https://github.com/fizyk20/generic-array/releases) - [Changelog](https://github.com/fizyk20/generic-array/blob/master/CHANGELOG.md) - [Commits](https://github.com/fizyk20/generic-array/commits) --- updated-dependencies: - dependency-name: generic-array dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88e7c888..53fe5bcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -336,9 +336,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", diff --git a/Cargo.toml b/Cargo.toml index 5dff0985..913f5281 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ parity-scale-codec-derive = { path = "derive", version = "3.1.4", default-featur bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } -generic-array = { version = "0.14.5", optional = true } +generic-array = { version = "0.14.7", optional = true } arbitrary = { version = "1.0.1", features = ["derive"], optional = true } impl-trait-for-tuples = "0.2.2" From 58bcd723a37397f61026d2301037632031c6784b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 22:50:32 +0200 Subject: [PATCH 141/286] Bump honggfuzz from 0.5.54 to 0.5.55 (#443) Bumps [honggfuzz](https://github.com/rust-fuzz/honggfuzz-rs) from 0.5.54 to 0.5.55. - [Commits](https://github.com/rust-fuzz/honggfuzz-rs/compare/v0.5.54...v0.5.55) --- updated-dependencies: - dependency-name: honggfuzz dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 14 +++++++------- fuzzer/Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53fe5bcb..f3e4681f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,13 +384,14 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "honggfuzz" -version = "0.5.54" +version = "0.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bea09577d948a98a5f59b7c891e274c4fb35ad52f67782b3d0cb53b9c05301f1" +checksum = "848e9c511092e0daa0a35a63e8e6e475a3e8f870741448b9f6028d69b142f18e" dependencies = [ "arbitrary", "lazy_static", - "memmap", + "memmap2", + "rustc_version", ] [[package]] @@ -488,13 +489,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] -name = "memmap" -version = "0.7.0" +name = "memmap2" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", - "winapi", ] [[package]] diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index c3dae4ea..69f8a48e 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -8,6 +8,6 @@ publish = false [dependencies] parity-scale-codec = { path = "..", features = ["derive", "bit-vec", "fuzz"] } -honggfuzz = "0.5.54" +honggfuzz = "0.5.55" arbitrary = { version = "1.0.1", features = ["derive"] } bitvec = { version = "1", features = ["alloc"] } From 155e0673eef523896447bd7328a03b08451cc732 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 23:54:15 +0200 Subject: [PATCH 142/286] Bump proptest from 1.1.0 to 1.2.0 (#445) Bumps [proptest](https://github.com/proptest-rs/proptest) from 1.1.0 to 1.2.0. - [Release notes](https://github.com/proptest-rs/proptest/releases) - [Changelog](https://github.com/proptest-rs/proptest/blob/master/CHANGELOG.md) - [Commits](https://github.com/proptest-rs/proptest/compare/v1.1.0...v1.2.0) --- updated-dependencies: - dependency-name: proptest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 13 +++---------- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3e4681f..035f17c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -631,16 +631,15 @@ dependencies = [ [[package]] name = "proptest" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f1b898011ce9595050a68e60f90bad083ff2987a695a42357134c8381fba70" +checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" dependencies = [ "bit-set", "bitflags", "byteorder", "lazy_static", "num-traits", - "quick-error 2.0.1", "rand", "rand_chacha", "rand_xorshift", @@ -656,12 +655,6 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -[[package]] -name = "quick-error" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" - [[package]] name = "quickcheck" version = "1.0.3" @@ -814,7 +807,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" dependencies = [ "fnv", - "quick-error 1.2.3", + "quick-error", "tempfile", "wait-timeout", ] diff --git a/Cargo.toml b/Cargo.toml index 913f5281..0d5a0339 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ criterion = "0.3.0" serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" -proptest = "1.1.0" +proptest = "1.2.0" trybuild = "1.0.80" paste = "1" From fa57eadfbbb0643f5943864e59e8222c86221eeb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 May 2023 13:38:58 +0200 Subject: [PATCH 143/286] Bump proc-macro2 from 1.0.58 to 1.0.59 (#447) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.58 to 1.0.59. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.58...1.0.59) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 035f17c7..81a8c061 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -622,9 +622,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 07ccb75c..edddd04f 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.27" -proc-macro2 = "1.0.58" +proc-macro2 = "1.0.59" proc-macro-crate = "1.1.3" [dev-dependencies] From 52c9871cf8c71163afb8845589df63ab6c0e10a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 00:56:26 +0200 Subject: [PATCH 144/286] Bump quote from 1.0.27 to 1.0.28 (#446) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.27 to 1.0.28. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.27...1.0.28) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81a8c061..960de9f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -668,9 +668,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index edddd04f..687dd243 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.27" +quote = "1.0.28" proc-macro2 = "1.0.59" proc-macro-crate = "1.1.3" From 766fef1b09e01a60bee5e75074719c9a487f9f8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:35:22 +0200 Subject: [PATCH 145/286] Bump proc-macro2 from 1.0.59 to 1.0.60 (#450) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.59 to 1.0.60. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.59...1.0.60) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 960de9f3..8b258b99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -622,9 +622,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 687dd243..77a330e3 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.28" -proc-macro2 = "1.0.59" +proc-macro2 = "1.0.60" proc-macro-crate = "1.1.3" [dev-dependencies] From 26ec55928f4f139bad88a17bf1acc19f8503f842 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:35:35 +0200 Subject: [PATCH 146/286] Bump serde from 1.0.163 to 1.0.164 (#449) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.163 to 1.0.164. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.163...v1.0.164) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b258b99..c59460a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -841,9 +841,9 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" [[package]] name = "serde_cbor" diff --git a/Cargo.toml b/Cargo.toml index 0d5a0339..7a9fa913 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.163", optional = true } +serde = { version = "1.0.164", optional = true } parity-scale-codec-derive = { path = "derive", version = "3.1.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 0688c04994bdcf7ad817eddd26077625458102c4 Mon Sep 17 00:00:00 2001 From: Koute Date: Thu, 15 Jun 2023 13:32:31 +0100 Subject: [PATCH 147/286] Rework decoding of `Box`es, `Rc`s, `Arc`s, arrays and enums (stack overflow fix) (#426) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Rework decoding of `Box`es, `Rc`s, `Arc`s and arrays * Update changelog * Bump version to 3.5.0 * Fix typo * Reduce the size of an array in tests to make miri not run forever * Make the `TypeInfo` match exhaustive * Update dependencies * Update benchmarks to criterion 0.4 * Update `BitVec` benchmarks too * Fix the benchmarks for real this time * Use `Layout::new` instead of `Layout::from_size_align` Co-authored-by: Squirrel * Move blanket decoding of wrapper types into a default impl * Fix stack overflow when decoding big nested enums * Bump version of `parity-scale-codec-derive` to 3.5.0 * Move the crate-level docs into README and include README as docs * Add a note regarding deserializing big arrays to the README * Update the CHANGELOG again * Remove one of the intermediate casts This cast was a no-op anyway, but it's slightly confusing as the length of the array in the pointer's type was incorrect, so let's just remove it. * README cleanups * Add `rust` markers and make indentation consistent in README snippets * Make `max-encoded-len` feature not force-enable `parity-scale-codec-derive` * Reexport derive macros not when `parity-scale-codec-derive` is enabled but when `derive` is * Update CHANGELOG again * Fix `parity-scale-codec-derive` tests compilation * Update `serde` * Update comment in `src/codec.rs` Co-authored-by: Bastian Köcher * Update comment in `src/codec.rs` Co-authored-by: Roman * Move the version bounds for `parity-scale-codec-derive` * Remove `DecodeContext` * Move the array byte size calculations to compile-time * Add a TODO about `Box::assume_init` * Move `DecodeFinished` into its own module * Add a TODO about `MaybeUninit::slice_assume_init_mut` * Update the changelog * `std` -> `core` so that no_std compiles --------- Co-authored-by: Squirrel Co-authored-by: Bastian Köcher Co-authored-by: Roman --- CHANGELOG.md | 20 +++ Cargo.lock | 170 +++++++++++----------- Cargo.toml | 8 +- README.md | 117 +++++++++------ benches/benches.rs | 189 ++++++++++++++----------- derive/Cargo.toml | 4 +- derive/src/decode.rs | 17 ++- src/codec.rs | 314 +++++++++++++++++++++++++++++------------ src/decode_finished.rs | 36 +++++ src/lib.rs | 233 +----------------------------- tests/mod.rs | 165 ++++++++++++++++++++++ 11 files changed, 738 insertions(+), 535 deletions(-) create mode 100644 src/decode_finished.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 482e4684..c50cad3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,26 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.6.0] - 2023-06-15 + +### Added + +- Added `Decode::decode_into` to allow deserializing into unitialized memory. +- Added a `DecodeFinished` type to be used with `Decode::decode_into`. + +### Fixed + +- Trying to deserialize a big boxed array (e.g. `Box<[u8; 1024 * 1024 * 1024]>`) won't overflow the stack anymore. +- Trying to deserialize big nested enums with many variants won't overflow the stack anymore. +- Elements of partially read arrays will now be properly dropped if the whole array wasn't decoded. + +### Changed + +- The derive macros will now be reexported only when the `derive` feature is enabled, + as opposed to how it was previously where enabling `parity-scale-codec-derive` would suffice. +- The `max-encoded-len` feature won't automatically enable the derive macros nor pull in the + `parity-scale-codec-derive` dependency. + ## [3.5.0] ### Added diff --git a/Cargo.lock b/Cargo.lock index c59460a8..67a320f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "arbitrary" version = "1.0.3" @@ -85,18 +91,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "bstr" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - [[package]] name = "bumpalo" version = "3.12.0" @@ -123,12 +117,9 @@ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cast" -version = "0.2.7" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" -dependencies = [ - "rustc_version", -] +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" @@ -142,15 +133,52 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "ciborium" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" + +[[package]] +name = "ciborium-ll" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "clap" -version = "2.33.3" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "bitflags", + "clap_lex", + "indexmap", "textwrap", - "unicode-width", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -165,15 +193,16 @@ dependencies = [ [[package]] name = "criterion" -version = "0.3.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" dependencies = [ + "anes", "atty", "cast", + "ciborium", "clap", "criterion-plot", - "csv", "itertools", "lazy_static", "num-traits", @@ -182,7 +211,6 @@ dependencies = [ "rayon", "regex", "serde", - "serde_cbor", "serde_derive", "serde_json", "tinytemplate", @@ -191,9 +219,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.4" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", "itertools", @@ -243,28 +271,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - [[package]] name = "derive_arbitrary" version = "1.0.2" @@ -367,6 +373,12 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -405,6 +417,16 @@ dependencies = [ "syn 1.0.98", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "instant" version = "0.1.12" @@ -538,9 +560,15 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "os_str_bytes" +version = "6.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" + [[package]] name = "parity-scale-codec" -version = "3.5.0" +version = "3.6.0" dependencies = [ "arbitrary", "arrayvec", @@ -561,7 +589,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.4" +version = "3.6.0" dependencies = [ "parity-scale-codec", "proc-macro-crate", @@ -765,12 +793,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - [[package]] name = "regex-syntax" version = "0.6.26" @@ -835,35 +857,28 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" -version = "1.0.4" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" - -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ - "half", - "serde", + "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.12", + "syn 2.0.16", ] [[package]] @@ -890,9 +905,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.12" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" dependencies = [ "proc-macro2", "quote", @@ -929,12 +944,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.11.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" @@ -1008,12 +1020,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - [[package]] name = "version_check" version = "0.9.3" diff --git a/Cargo.toml b/Cargo.toml index 7a9fa913..f43c6cf5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.5.0" +version = "3.6.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.164", optional = true } -parity-scale-codec-derive = { path = "derive", version = "3.1.4", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = ">= 3.6.0", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } @@ -21,7 +21,7 @@ arbitrary = { version = "1.0.1", features = ["derive"], optional = true } impl-trait-for-tuples = "0.2.2" [dev-dependencies] -criterion = "0.3.0" +criterion = "0.4.0" serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" @@ -46,7 +46,7 @@ fuzz = ["std", "arbitrary"] # Enables the new `MaxEncodedLen` trait. # NOTE: This is still considered experimental and is exempt from the usual # SemVer guarantees. We do not guarantee no code breakage when using this. -max-encoded-len = ["parity-scale-codec-derive/max-encoded-len"] +max-encoded-len = ["parity-scale-codec-derive?/max-encoded-len"] # Make error fully descriptive with chaining error message. # Should not be used in a constrained environment. diff --git a/README.md b/README.md index dadbc926..8b079051 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,12 @@ SCALE is a light-weight format which allows encoding (and decoding) which makes suitable for resource-constrained execution environments like blockchain runtimes and low-power, low-memory devices. -It is important to note that the encoding context (knowledge of how the types and data structures look) -needs to be known separately at both encoding and decoding ends. +It is important to note that the encoding context (knowledge of how the types and data +structures look) needs to be known separately at both encoding and decoding ends. The encoded data does not include this contextual information. To get a better understanding of how the encoding is done for different types, -take a look at the -[low-level data formats overview page at the Substrate docs site](https://docs.substrate.io/reference/scale-codec/). +take a look at the ["Type encoding (SCALE)" page in Substrate docs](https://docs.substrate.io/reference/scale-codec/). ## Implementation @@ -21,45 +20,52 @@ The codec is implemented using the following traits: ### Encode -The `Encode` trait is used for encoding of data into the SCALE format. The `Encode` trait contains the following functions: +The `Encode` trait is used for encoding of data into the SCALE format. The `Encode` trait +contains the following functions: + * `size_hint(&self) -> usize`: Gets the capacity (in bytes) required for the encoded data. -This is to avoid double-allocation of memory needed for the encoding. -It can be an estimate and does not need to be an exact number. -If the size is not known, even no good maximum, then we can skip this function from the trait implementation. -This is required to be a cheap operation, so should not involve iterations etc. -* `encode_to(&self, dest: &mut T)`: Encodes the value and appends it to a destination buffer. + This is to avoid double-allocation of memory needed for the encoding. It can be an estimate + and does not need to be an exact number. If the size is not known, even no good maximum, then + we can skip this function from the trait implementation. This is required to be a cheap operation, + so should not involve iterations etc. +* `encode_to(&self, dest: &mut T)`: Encodes the value and appends it to a destination + buffer. * `encode(&self) -> Vec`: Encodes the type data and returns a slice. -* `using_encoded R>(&self, f: F) -> R`: Encodes the type data and executes a closure on the encoded value. -Returns the result from the executed closure. +* `using_encoded R>(&self, f: F) -> R`: Encodes the type data and + executes a closure on the encoded value. Returns the result from the executed closure. -**Note:** Implementations should override `using_encoded` for value types and `encode_to` for allocating types. -`size_hint` should be implemented for all types, wherever possible. Wrapper types should override all methods. +**Note:** Implementations should override `using_encoded` for value types and `encode_to` for +allocating types. `size_hint` should be implemented for all types, wherever possible. Wrapper +types should override all methods. ### Decode -The `Decode` trait is used for deserialization/decoding of encoded data into the respective types. +The `Decode` trait is used for deserialization/decoding of encoded data into the respective +types. -* `fn decode(value: &mut I) -> Result`: Tries to decode the value from SCALE format to the type it is called on. -Returns an `Err` if the decoding fails. +* `fn decode(value: &mut I) -> Result`: Tries to decode the value from + SCALE format to the type it is called on. Returns an `Err` if the decoding fails. ### CompactAs -The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes them even more space/memory efficient. -The compact encoding is described [here](https://docs.substrate.io/reference/scale-codec/#fnref-1). +The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes +them even more space/memory efficient. The compact encoding is described [here](https://docs.substrate.io/reference/scale-codec/#fn-1). * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. -The type `As` is defined in the same trait and its implementation should be compact encode-able. -* `decode_from(_: Self::As) -> Result`: Decodes the type (self) from a compact encode-able type. + The type `As` is defined in the same trait and its implementation should be compact encode-able. +* `decode_from(_: Self::As) -> Result`: Decodes the type (self) from a compact + encode-able type. ### HasCompact -The `HasCompact` trait, if implemented, tells that the corresponding type is a compact encode-able type. +The `HasCompact` trait, if implemented, tells that the corresponding type is a compact +encode-able type. ### EncodeLike The `EncodeLike` trait needs to be implemented for each type manually. When using derive, it is -done automatically for you. Basically the trait gives you the opportunity to accept multiple types -to a function that all encode to the same representation. +done automatically for you. Basically the trait gives you the opportunity to accept multiple +types to a function that all encode to the same representation. ## Usage Examples @@ -68,19 +74,21 @@ Following are some examples to demonstrate usage of the codec. ### Simple types ```rust +# // Import macros if derive feature is not used. +# #[cfg(not(feature="derive"))] +# use parity_scale_codec_derive::{Encode, Decode}; use parity_scale_codec::{Encode, Decode}; -use parity_scale_codec_derive::{Encode, Decode}; #[derive(Debug, PartialEq, Encode, Decode)] enum EnumType { - #[codec(index = 15)] - A, - B(u32, u64), - C { - a: u32, - b: u64, - }, + #[codec(index = 15)] + A, + B(u32, u64), + C { + a: u32, + b: u64, + }, } let a = EnumType::A; @@ -111,14 +119,17 @@ assert_eq!(EnumType::decode(&mut dc).ok(), Some(c)); let mut dz: &[u8] = &[0]; assert_eq!(EnumType::decode(&mut dz).ok(), None); +# fn main() { } ``` ### Compact type with HasCompact ```rust +# // Import macros if derive feature is not used. +# #[cfg(not(feature="derive"))] +# use parity_scale_codec_derive::{Encode, Decode}; use parity_scale_codec::{Encode, Decode, Compact, HasCompact}; -use parity_scale_codec_derive::{Encode, Decode}; #[derive(Debug, PartialEq, Encode, Decode)] struct Test1CompactHasCompact { @@ -138,10 +149,15 @@ let encoded = Test1HasCompact { bar: test_val.0 }.encode(); assert_eq!(encoded.len(), test_val.1); assert_eq!(>::decode(&mut &encoded[..]).unwrap().bar, test_val.0); +# fn main() { } ``` + ### Type with CompactAs ```rust +# // Import macros if derive feature is not used. +# #[cfg(not(feature="derive"))] +# use parity_scale_codec_derive::{Encode, Decode}; use serde_derive::{Serialize, Deserialize}; use parity_scale_codec::{Encode, Decode, Compact, HasCompact, CompactAs, Error}; @@ -182,28 +198,41 @@ let a = TestGenericHasCompact::A:: { let encoded = a.encode(); assert_eq!(encoded.len(), 2); +# fn main() { } ``` ## Derive attributes The derive implementation supports the following attributes: -- `codec(dumb_trait_bound)`: This attribute needs to be placed above the type that one of the trait - should be implemented for. It will make the algorithm that determines the to-add trait bounds - fall back to just use the type parameters of the type. This can be useful for situation where - the algorithm includes private types in the public interface. By using this attribute, you should - not get this error/warning again. +- `codec(dumb_trait_bound)`: This attribute needs to be placed above the type that one of the + trait should be implemented for. It will make the algorithm that determines the to-add trait + bounds fall back to just use the type parameters of the type. This can be useful for situation + where the algorithm includes private types in the public interface. By using this attribute, + you should not get this error/warning again. - `codec(skip)`: Needs to be placed above a field or variant and makes it to be skipped while encoding/decoding. - `codec(compact)`: Needs to be placed above a field and makes the field use compact encoding. (The type needs to support compact encoding.) -- `codec(encoded_as = "OtherType")`: Needs to be placed above a field and makes the field being encoded - by using `OtherType`. +- `codec(encoded_as = "OtherType")`: Needs to be placed above a field and makes the field being + encoded by using `OtherType`. - `codec(index = 0)`: Needs to be placed above an enum variant to make the variant use the given index when encoded. By default the index is determined by counting from `0` beginning wth the first variant. -- `codec(crate = path::to::crate)`: Specify a path to the parity-scale-codec crate instance to use - when referring to Codec APIs from generated code. This is normally only applicable when invoking - re-exported Codec derives from a public macro in a different crate. - +- `codec(encode_bound)`, `codec(decode_bound)` and `codec(mel_bound)`: All 3 attributes take + in a `where` clause for the `Encode`, `Decode` and `MaxEncodedLen` trait implementation for + the annotated type respectively. +- `codec(encode_bound(skip_type_params))`, `codec(decode_bound(skip_type_params))` and + `codec(mel_bound(skip_type_params))`: All 3 sub-attributes take in types as arguments to skip + trait derivation of the corresponding trait, e.g. T in + `codec(encode_bound(skip_type_params(T)))` will not contain a `Encode` trait bound while + `Encode` is being derived for the annotated type. + +## Known issues + +Even though this crate supports deserialization of arbitrarily sized array (e.g. `[T; 1024 * 1024 * 1024]`) +using such types is not recommended and will most likely result in a stack overflow. If you have a big +array inside of your structure which you want to decode you should wrap it in a `Box`, e.g. `Box<[T; 1024 * 1024 * 1024]>`. + +------------------------- License: Apache-2.0 diff --git a/benches/benches.rs b/benches/benches.rs index 248147e2..f52e9fbd 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -113,46 +113,57 @@ fn vec_append_with_encode_append(b: &mut Bencher) { } fn encode_decode_vec + Codec>(c: &mut Criterion) where T::Error: std::fmt::Debug { - c.bench_function_over_inputs(&format!("vec_encode_{}", type_name::()), |b, &vec_size| { - let vec: Vec = (0..=127u8) - .cycle() - .take(vec_size) - .map(|v| v.try_into().unwrap()) - .collect(); - - let vec = black_box(vec); - b.iter(|| vec.encode()) - }, vec![1, 2, 5, 32, 1024, 2048, 16384]); - - c.bench_function_over_inputs(&format!("vec_decode_{}", type_name::()), |b, &vec_size| { - let vec: Vec = (0..=127u8) - .cycle() - .take(vec_size) - .map(|v| v.try_into().unwrap()) - .collect(); - - let vec = vec.encode(); - - let vec = black_box(vec); - b.iter(|| { - let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); - }) - }, vec![1, 2, 5, 32, 1024, 2048, 16384]); - - c.bench_function_over_inputs(&format!("vec_decode_no_limit_{}", type_name::()), |b, &vec_size| { - let vec: Vec = (0..=127u8) - .cycle() - .take(vec_size) - .map(|v| v.try_into().unwrap()) - .collect(); - - let vec = vec.encode(); - - let vec = black_box(vec); - b.iter(|| { - let _: Vec = Decode::decode(&mut NoLimitInput(&vec[..])).unwrap(); - }) - }, vec![16384, 131072]); + let mut g = c.benchmark_group("vec_encode"); + for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { + g.bench_with_input(&format!("{}/{}", type_name::(), vec_size), &vec_size, |b, &vec_size| { + let vec: Vec = (0..=127u8) + .cycle() + .take(vec_size) + .map(|v| v.try_into().unwrap()) + .collect(); + + let vec = black_box(vec); + b.iter(|| vec.encode()) + }); + } + + core::mem::drop(g); + let mut g = c.benchmark_group("vec_decode"); + for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { + g.bench_with_input(&format!("{}/{}", type_name::(), vec_size), &vec_size, |b, &vec_size| { + let vec: Vec = (0..=127u8) + .cycle() + .take(vec_size) + .map(|v| v.try_into().unwrap()) + .collect(); + + let vec = vec.encode(); + + let vec = black_box(vec); + b.iter(|| { + let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); + }) + }); + } + + core::mem::drop(g); + let mut g = c.benchmark_group("vec_decode_no_limit"); + for vec_size in [16384, 131072] { + g.bench_with_input(&format!("vec_decode_no_limit_{}/{}", type_name::(), vec_size), &vec_size, |b, &vec_size| { + let vec: Vec = (0..=127u8) + .cycle() + .take(vec_size) + .map(|v| v.try_into().unwrap()) + .collect(); + + let vec = vec.encode(); + + let vec = black_box(vec); + b.iter(|| { + let _: Vec = Decode::decode(&mut NoLimitInput(&vec[..])).unwrap(); + }) + }); + } } fn encode_decode_complex_type(c: &mut Criterion) { @@ -168,25 +179,33 @@ fn encode_decode_complex_type(c: &mut Criterion) { ComplexType { _val: 1000, _other_val: 0980345634635, _vec: vec![1, 2, 3, 5, 6, 7] }, ComplexType { _val: 43564, _other_val: 342342345634635, _vec: vec![1, 2, 3, 5, 6, 7] }, ]; - let complex_types2 = complex_types.clone(); - c.bench_function_over_inputs("vec_encode_complex_type", move |b, &vec_size| { - let vec: Vec = complex_types.clone().into_iter().cycle().take(vec_size).collect(); + let mut g = c.benchmark_group("vec_encode_complex_type"); + for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { + let complex_types = complex_types.clone(); + g.bench_with_input(format!("vec_encode_complex_type/{}", vec_size), &vec_size, move |b, &vec_size| { + let vec: Vec = complex_types.clone().into_iter().cycle().take(vec_size).collect(); - let vec = black_box(vec); - b.iter(|| vec.encode()) - }, vec![1, 2, 5, 32, 1024, 2048, 16384]); + let vec = black_box(vec); + b.iter(|| vec.encode()) + }); + } - c.bench_function_over_inputs("vec_decode_complex_type", move |b, &vec_size| { - let vec: Vec = complex_types2.clone().into_iter().cycle().take(vec_size).collect(); + core::mem::drop(g); + let mut g = c.benchmark_group("vec_decode_complex_type"); + for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { + let complex_types = complex_types.clone(); + g.bench_with_input(format!("vec_decode_complex_type/{}", vec_size), &vec_size, move |b, &vec_size| { + let vec: Vec = complex_types.clone().into_iter().cycle().take(vec_size).collect(); - let vec = vec.encode(); + let vec = vec.encode(); - let vec = black_box(vec); - b.iter(|| { - let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); - }) - }, vec![1, 2, 5, 32, 1024, 2048, 16384]); + let vec = black_box(vec); + b.iter(|| { + let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); + }) + }); + } } fn bench_fn(c: &mut Criterion) { @@ -202,34 +221,44 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { let _ = c; #[cfg(feature = "bit-vec")] - c.bench_function_over_inputs("bitvec_u8_encode - BitVec", |b, &size| { - let vec: BitVec = [true, false] - .iter() - .cloned() - .cycle() - .take(size) - .collect(); - - let vec = black_box(vec); - b.iter(|| vec.encode()) - }, vec![1, 2, 5, 32, 1024]); + { + let mut g = c.benchmark_group("bitvec_u8_encode"); + for size in [1, 2, 5, 32, 1024] { + g.bench_with_input(size.to_string(), &size, |b, &size| { + let vec: BitVec = [true, false] + .iter() + .cloned() + .cycle() + .take(size) + .collect(); + + let vec = black_box(vec); + b.iter(|| vec.encode()) + }); + } + } #[cfg(feature = "bit-vec")] - c.bench_function_over_inputs("bitvec_u8_decode - BitVec", |b, &size| { - let vec: BitVec = [true, false] - .iter() - .cloned() - .cycle() - .take(size) - .collect(); - - let vec = vec.encode(); - - let vec = black_box(vec); - b.iter(|| { - let _: BitVec = Decode::decode(&mut &vec[..]).unwrap(); - }) - }, vec![1, 2, 5, 32, 1024]); + { + let mut g = c.benchmark_group("bitvec_u8_decode"); + for size in [1, 2, 5, 32, 1024] { + g.bench_with_input(size.to_string(), &size, |b, &size| { + let vec: BitVec = [true, false] + .iter() + .cloned() + .cycle() + .take(size) + .collect(); + + let vec = vec.encode(); + + let vec = black_box(vec); + b.iter(|| { + let _: BitVec = Decode::decode(&mut &vec[..]).unwrap(); + }) + }); + } + } } criterion_group!{ diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 77a330e3..575d7565 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.1.4" +version = "3.6.0" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" @@ -17,7 +17,7 @@ proc-macro2 = "1.0.60" proc-macro-crate = "1.1.3" [dev-dependencies] -parity-scale-codec = { path = "..", features = ["max-encoded-len"] } +parity-scale-codec = { path = "..", features = ["derive", "max-encoded-len"] } [features] # Enables the new `MaxEncodedLen` trait. diff --git a/derive/src/decode.rs b/derive/src/decode.rs index df603902..5787ff5b 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -72,7 +72,12 @@ pub fn quote( quote_spanned! { v.span() => __codec_x_edqy if __codec_x_edqy == #index as ::core::primitive::u8 => { - #create + // NOTE: This lambda is necessary to work around an upstream bug + // where each extra branch results in excessive stack usage: + // https://github.com/rust-lang/rust/issues/34283 + return (move || { + #create + })(); }, } }); @@ -90,9 +95,13 @@ pub fn quote( .map_err(|e| e.chain(#read_byte_err_msg))? { #( #recurse )* - _ => ::core::result::Result::Err( - <_ as ::core::convert::Into<_>>::into(#invalid_variant_err_msg) - ), + _ => { + return (move || { + return ::core::result::Result::Err( + <_ as ::core::convert::Into<_>>::into(#invalid_variant_err_msg) + ); + })(); + }, } } diff --git a/src/codec.rs b/src/codec.rs index db46843b..5ccc30ae 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -22,11 +22,9 @@ use core::{ mem, mem::{ MaybeUninit, - forget, }, ops::{Deref, Range, RangeInclusive}, time::Duration, - ptr, }; use core::num::{ NonZeroI8, @@ -56,6 +54,7 @@ use crate::alloc::{ vec::Vec, }; use crate::compact::Compact; +use crate::DecodeFinished; use crate::encode_like::EncodeLike; use crate::Error; @@ -296,6 +295,24 @@ pub trait Decode: Sized { /// Attempt to deserialise the value from input. fn decode(input: &mut I) -> Result; + /// Attempt to deserialize the value from input into a pre-allocated piece of memory. + /// + /// The default implementation will just call [`Decode::decode`]. + /// + /// # Safety + /// + /// If this function returns `Ok` then `dst` **must** be properly initialized. + /// + /// This is enforced by requiring the implementation to return a [`DecodeFinished`] + /// which can only be created by calling [`DecodeFinished::assert_decoding_finished`] which is `unsafe`. + fn decode_into(input: &mut I, dst: &mut MaybeUninit) -> Result { + let value = Self::decode(input)?; + dst.write(value); + + // SAFETY: We've written the decoded value to `dst` so calling this is safe. + unsafe { Ok(DecodeFinished::assert_decoding_finished()) } + } + /// Attempt to skip the encoded value from input. /// /// The default implementation of this function is just calling [`Decode::decode`]. @@ -488,29 +505,101 @@ impl Encode for X where pub trait WrapperTypeDecode: Sized { /// A wrapped type. type Wrapped: Into; + + // !INTERNAL USE ONLY! + // This is a used to specialize `decode` for the wrapped type. + #[doc(hidden)] + #[inline] + fn decode_wrapped(input: &mut I) -> Result where Self::Wrapped: Decode { + input.descend_ref()?; + let result = Ok(Self::Wrapped::decode(input)?.into()); + input.ascend_ref(); + result + } } + impl WrapperTypeDecode for Box { type Wrapped = T; + + fn decode_wrapped(input: &mut I) -> Result where Self::Wrapped: Decode { + input.descend_ref()?; + + // Placement new is not yet stable, but we can just manually allocate a chunk of memory + // and convert it to a `Box` ourselves. + // + // The explicit types here are written out for clarity. + // + // TODO: Use `Box::new_uninit` once that's stable. + let layout = core::alloc::Layout::new::>(); + + let ptr: *mut MaybeUninit = if layout.size() == 0 { + core::ptr::NonNull::dangling().as_ptr() + } else { + + // SAFETY: Layout has a non-zero size so calling this is safe. + let ptr: *mut u8 = unsafe { + crate::alloc::alloc::alloc(layout) + }; + + if ptr.is_null() { + crate::alloc::alloc::handle_alloc_error(layout); + } + + ptr.cast() + }; + + // SAFETY: Constructing a `Box` from a piece of memory allocated with `std::alloc::alloc` + // is explicitly allowed as long as it was allocated with the global allocator + // and the memory layout matches. + // + // Constructing a `Box` from `NonNull::dangling` is also always safe as long + // as the underlying type is zero-sized. + let mut boxed: Box> = unsafe { Box::from_raw(ptr) }; + + T::decode_into(input, &mut boxed)?; + + // Decoding succeeded, so let's get rid of `MaybeUninit`. + // + // TODO: Use `Box::assume_init` once that's stable. + let ptr: *mut MaybeUninit = Box::into_raw(boxed); + let ptr: *mut T = ptr.cast(); + + // SAFETY: `MaybeUninit` doesn't affect the memory layout, so casting the pointer back + // into a `Box` is safe. + let boxed: Box = unsafe { Box::from_raw(ptr) }; + + input.ascend_ref(); + Ok(boxed) + } } + impl WrapperTypeDecode for Rc { type Wrapped = T; + + fn decode_wrapped(input: &mut I) -> Result where Self::Wrapped: Decode { + // TODO: This is inefficient; use `Rc::new_uninit` once that's stable. + Box::::decode(input).map(|output| output.into()) + } } + #[cfg(target_has_atomic = "ptr")] impl WrapperTypeDecode for Arc { type Wrapped = T; + + fn decode_wrapped(input: &mut I) -> Result where Self::Wrapped: Decode { + // TODO: This is inefficient; use `Arc::new_uninit` once that's stable. + Box::::decode(input).map(|output| output.into()) + } } impl Decode for X where T: Decode + Into, X: WrapperTypeDecode, { + #[inline] fn decode(input: &mut I) -> Result { - input.descend_ref()?; - let result = Ok(T::decode(input)?.into()); - input.ascend_ref(); - result + Self::decode_wrapped(input) } - } /// A macro that matches on a [`TypeInfo`] and expands a given macro per variant. @@ -732,90 +821,6 @@ pub(crate) fn encode_slice_no_len(slice: &[T], de } } -/// Decode the array. -/// -/// This is equivalent to decoding all the element one by one, but it is optimized for some types. -#[inline] -pub(crate) fn decode_array(input: &mut I) -> Result<[T; N], Error> { - #[inline] - fn general_array_decode(input: &mut I) -> Result<[T; N], Error> { - let mut uninit = >::uninit(); - // The following line coerces the pointer to the array to a pointer - // to the first array element which is equivalent. - let mut ptr = uninit.as_mut_ptr() as *mut T; - for _ in 0..N { - let decoded = T::decode(input)?; - // SAFETY: We do not read uninitialized array contents - // while initializing them. - unsafe { - ptr::write(ptr, decoded); - } - // SAFETY: Point to the next element after every iteration. - // We do this N times therefore this is safe. - ptr = unsafe { ptr.add(1) }; - } - // SAFETY: All array elements have been initialized above. - let init = unsafe { uninit.assume_init() }; - Ok(init) - } - - // Description for the code below. - // It is not possible to transmute `[u8; N]` into `[T; N]` due to this issue: - // https://github.com/rust-lang/rust/issues/61956 - // - // Workaround: Transmute `&[u8; N]` into `&[T; N]` and interpret that reference as value. - // ``` - // let mut array: [u8; N] = [0; N]; - // let ref_typed: &[T; N] = unsafe { mem::transmute(&array) }; - // let typed: [T; N] = unsafe { ptr::read(ref_typed) }; - // forget(array); - // Here `array` and `typed` points on the same memory. - // Function returns `typed` -> it is not dropped, but `array` will be dropped. - // To avoid that `array` should be forgotten. - // ``` - macro_rules! decode { - ( u8 ) => {{ - let mut array: [u8; N] = [0; N]; - input.read(&mut array[..])?; - let ref_typed: &[T; N] = unsafe { mem::transmute(&array) }; - let typed: [T; N] = unsafe { ptr::read(ref_typed) }; - forget(array); - Ok(typed) - }}; - ( i8 ) => {{ - let mut array: [i8; N] = [0; N]; - let bytes = unsafe { mem::transmute::<&mut [i8], &mut [u8]>(&mut array[..]) }; - input.read(bytes)?; - - let ref_typed: &[T; N] = unsafe { mem::transmute(&array) }; - let typed: [T; N] = unsafe { ptr::read(ref_typed) }; - forget(array); - Ok(typed) - }}; - ( $ty:ty ) => {{ - if cfg!(target_endian = "little") { - let mut array: [$ty; N] = [0 as $ty; N]; - let bytes = <[$ty] as AsMutByteSlice<$ty>>::as_mut_byte_slice(&mut array[..]); - input.read(bytes)?; - let ref_typed: &[T; N] = unsafe { mem::transmute(&array) }; - let typed: [T; N] = unsafe { ptr::read(ref_typed) }; - forget(array); - Ok(typed) - } else { - general_array_decode(input) - } - }}; - } - - with_type_info! { - ::TYPE_INFO, - decode, - { - general_array_decode(input) - }, - } -} - /// Decode the vec (without a prepended len). /// /// This is equivalent to decode all elements one by one, but it is optimized in some @@ -884,10 +889,133 @@ impl Encode for [T; N] { } } +const fn calculate_array_bytesize() -> usize { + struct AssertNotOverflow(core::marker::PhantomData); + + impl AssertNotOverflow { + const OK: () = assert!(core::mem::size_of::().checked_mul(N).is_some(), "array size overflow"); + } + + let () = AssertNotOverflow::::OK; + core::mem::size_of::() * N +} + impl Decode for [T; N] { - #[inline] + #[inline(always)] fn decode(input: &mut I) -> Result { - decode_array(input) + let mut array = MaybeUninit::uninit(); + Self::decode_into(input, &mut array)?; + + // SAFETY: `decode_into` succeeded, so the array is initialized. + unsafe { + Ok(array.assume_init()) + } + } + + fn decode_into(input: &mut I, dst: &mut MaybeUninit) -> Result { + let is_primitive = match ::TYPE_INFO { + | TypeInfo::U8 + | TypeInfo::I8 + => true, + | TypeInfo::U16 + | TypeInfo::I16 + | TypeInfo::U32 + | TypeInfo::I32 + | TypeInfo::U64 + | TypeInfo::I64 + | TypeInfo::U128 + | TypeInfo::I128 + | TypeInfo::F32 + | TypeInfo::F64 + => cfg!(target_endian = "little"), + TypeInfo::Unknown => false + }; + + if is_primitive { + // Let's read the array in bulk as that's going to be a lot + // faster than just reading each element one-by-one. + + let ptr: *mut [T; N] = dst.as_mut_ptr(); + let ptr: *mut u8 = ptr.cast(); + + let bytesize = calculate_array_bytesize::(); + + // TODO: This is potentially slow; it'd be better if `Input` supported + // reading directly into uninitialized memory. + // + // SAFETY: The pointer is valid and points to a memory `bytesize` bytes big. + unsafe { + ptr.write_bytes(0, bytesize); + } + + // SAFETY: We've zero-initialized everything so creating a slice here is safe. + let slice: &mut [u8] = unsafe { + core::slice::from_raw_parts_mut(ptr, bytesize) + }; + + input.read(slice)?; + + // SAFETY: We've initialized the whole slice so calling this is safe. + unsafe { + return Ok(DecodeFinished::assert_decoding_finished()); + } + } + + let slice: &mut [MaybeUninit; N] = { + let ptr: *mut [T; N] = dst.as_mut_ptr(); + let ptr: *mut [MaybeUninit; N] = ptr.cast(); + // SAFETY: Casting `&mut MaybeUninit<[T; N]>` into `&mut [MaybeUninit; N]` is safe. + unsafe { &mut *ptr } + }; + + /// A wrapper type to make sure the partially read elements are always + /// dropped in case an error occurs or the underlying `decode` implementation panics. + struct State<'a, T, const N: usize> { + count: usize, + slice: &'a mut [MaybeUninit; N] + } + + impl<'a, T, const N: usize> Drop for State<'a, T, N> { + fn drop(&mut self) { + if !core::mem::needs_drop::() { + // If the types don't actually need to be dropped then don't even + // try to run the loop below. + // + // Most likely won't make a difference in release mode, but will + // make a difference in debug mode. + return; + } + + // TODO: Use `MaybeUninit::slice_assume_init_mut` + `core::ptr::drop_in_place` + // once `slice_assume_init_mut` is stable. + for item in &mut self.slice[..self.count] { + // SAFETY: Each time we've read a new element we incremented `count`, + // and we only drop at most `count` elements here, + // so all of the elements we drop here are valid. + unsafe { + item.assume_init_drop(); + } + } + } + } + + let mut state = State { + count: 0, + slice + }; + + while state.count < state.slice.len() { + T::decode_into(input, &mut state.slice[state.count])?; + state.count += 1; + } + + // We've successfully read everything, so disarm the `Drop` impl. + core::mem::forget(state); + + // SAFETY: We've initialized the whole slice so calling this is safe. + unsafe { + return Ok(DecodeFinished::assert_decoding_finished()); + } } fn skip(input: &mut I) -> Result<(), Error> { diff --git a/src/decode_finished.rs b/src/decode_finished.rs new file mode 100644 index 00000000..aa6feb98 --- /dev/null +++ b/src/decode_finished.rs @@ -0,0 +1,36 @@ +// 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. + +//! Contains the [`DecodeFinished`] type, sequestered into its own module +//! to prevent its direct construction in the whole crate. + +use core::marker::PhantomData; + +/// A zero-sized type signifying that the decoding finished. +/// +/// To be used in [`Decode::decode_into`] to allow the implementation to explicitly +/// assert that the `MaybeUninit` passed into that function was properly initialized. +pub struct DecodeFinished(PhantomData<*const ()>); + +impl DecodeFinished { + /// Assert that the decoding has finished. + /// + /// Should be used in [`Decode::decode_into`] to signify that + /// the `MaybeUninit` passed into that function was properly initialized. + #[inline] + pub unsafe fn assert_decoding_finished() -> DecodeFinished { + DecodeFinished(PhantomData) + } +} diff --git a/src/lib.rs b/src/lib.rs index ea999180..133c736d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,229 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Parity SCALE Codec -//! -//! Rust implementation of the SCALE (Simple Concatenated Aggregate Little-Endian) data format -//! for types used in the Parity Substrate framework. -//! -//! SCALE is a light-weight format which allows encoding (and decoding) which makes it highly -//! suitable for resource-constrained execution environments like blockchain runtimes and low-power, -//! low-memory devices. -//! -//! It is important to note that the encoding context (knowledge of how the types and data -//! structures look) needs to be known separately at both encoding and decoding ends. -//! The encoded data does not include this contextual information. -//! -//! To get a better understanding of how the encoding is done for different types, -//! take a look at the -//! [SCALE Code page at the Substrate Knowledge Base](https://docs.substrate.io/v3/advanced/scale-codec/). -//! -//! ## Implementation -//! -//! The codec is implemented using the following traits: -//! -//! ### Encode -//! -//! The `Encode` trait is used for encoding of data into the SCALE format. The `Encode` trait -//! contains the following functions: - -//! -//! * `size_hint(&self) -> usize`: Gets the capacity (in bytes) required for the encoded data. -//! This is to avoid double-allocation of memory needed for the encoding. -//! It can be an estimate and does not need to be an exact number. -//! If the size is not known, even no good maximum, then we can skip this function from the trait -//! implementation. This is required to be a cheap operation, so should not involve iterations etc. -//! * `encode_to(&self, dest: &mut T)`: Encodes the value and appends it to a destination -//! buffer. -//! * `encode(&self) -> Vec`: Encodes the type data and returns a slice. -//! * `using_encoded R>(&self, f: F) -> R`: Encodes the type data and -//! executes a closure on the encoded value. -//! Returns the result from the executed closure. -//! -//! **Note:** Implementations should override `using_encoded` for value types and `encode_to` for -//! allocating types. `size_hint` should be implemented for all types, wherever possible. Wrapper -//! types should override all methods. -//! -//! ### Decode -//! -//! The `Decode` trait is used for deserialization/decoding of encoded data into the respective -//! types. -//! -//! * `fn decode(value: &mut I) -> Result`: Tries to decode the value from -//! SCALE format to the type it is called on. -//! Returns an `Err` if the decoding fails. -//! -//! ### CompactAs -//! -//! The `CompactAs` trait is used for wrapping custom types/structs as compact types, which makes -//! them even more space/memory efficient. The compact encoding is described [here](https://docs.substrate.io/v3/advanced/scale-codec/#compactgeneral-integers). -//! -//! * `encode_as(&self) -> &Self::As`: Encodes the type (self) as a compact type. -//! The type `As` is defined in the same trait and its implementation should be compact encode-able. -//! * `decode_from(_: Self::As) -> Result`: Decodes the type (self) from a compact -//! encode-able type. -//! -//! ### HasCompact -//! -//! The `HasCompact` trait, if implemented, tells that the corresponding type is a compact -//! encode-able type. -//! -//! ### EncodeLike -//! -//! The `EncodeLike` trait needs to be implemented for each type manually. When using derive, it is -//! done automatically for you. Basically the trait gives you the opportunity to accept multiple -//! types to a function that all encode to the same representation. -//! -//! ## Usage Examples -//! -//! Following are some examples to demonstrate usage of the codec. -//! -//! ### Simple types -//! -#![cfg_attr(feature = "derive", doc = "```rust")] -#![cfg_attr(not(feature = "derive"), doc = "*(Only compiled with feature `derive`)*\n```ignore")] -//! use parity_scale_codec::{Encode, Decode}; -//! -//! #[derive(Debug, PartialEq, Encode, Decode)] -//! enum EnumType { -//! #[codec(index = 15)] -//! A, -//! B(u32, u64), -//! C { -//! a: u32, -//! b: u64, -//! }, -//! } -//! -//! let a = EnumType::A; -//! let b = EnumType::B(1, 2); -//! let c = EnumType::C { a: 1, b: 2 }; -//! -//! a.using_encoded(|ref slice| { -//! assert_eq!(slice, &b"\x0f"); -//! }); -//! -//! b.using_encoded(|ref slice| { -//! assert_eq!(slice, &b"\x01\x01\0\0\0\x02\0\0\0\0\0\0\0"); -//! }); -//! -//! c.using_encoded(|ref slice| { -//! assert_eq!(slice, &b"\x02\x01\0\0\0\x02\0\0\0\0\0\0\0"); -//! }); -//! -//! let mut da: &[u8] = b"\x0f"; -//! assert_eq!(EnumType::decode(&mut da).ok(), Some(a)); -//! -//! let mut db: &[u8] = b"\x01\x01\0\0\0\x02\0\0\0\0\0\0\0"; -//! assert_eq!(EnumType::decode(&mut db).ok(), Some(b)); -//! -//! let mut dc: &[u8] = b"\x02\x01\0\0\0\x02\0\0\0\0\0\0\0"; -//! assert_eq!(EnumType::decode(&mut dc).ok(), Some(c)); -//! -//! let mut dz: &[u8] = &[0]; -//! assert_eq!(EnumType::decode(&mut dz).ok(), None); -//! -//! # fn main() { } -//! ``` -//! -//! ### Compact type with HasCompact -//! -#![cfg_attr(feature = "derive", doc = "```rust")] -#![cfg_attr(not(feature = "derive"), doc = "*(Only compiled with feature `derive`)*\n```ignore")] -//! use parity_scale_codec::{Encode, Decode, Compact, HasCompact}; -//! -//! #[derive(Debug, PartialEq, Encode, Decode)] -//! struct Test1CompactHasCompact { -//! #[codec(compact)] -//! bar: T, -//! } -//! -//! #[derive(Debug, PartialEq, Encode, Decode)] -//! struct Test1HasCompact { -//! #[codec(encoded_as = "::Type")] -//! bar: T, -//! } -//! -//! let test_val: (u64, usize) = (0u64, 1usize); -//! -//! let encoded = Test1HasCompact { bar: test_val.0 }.encode(); -//! assert_eq!(encoded.len(), test_val.1); -//! assert_eq!(>::decode(&mut &encoded[..]).unwrap().bar, test_val.0); -//! -//! # fn main() { } -//! ``` -//! ### Type with CompactAs -//! -#![cfg_attr(feature = "derive", doc = "```rust")] -#![cfg_attr(not(feature = "derive"), doc = "*(Only compiled with feature `derive`)*\n```ignore")] -//! use serde_derive::{Serialize, Deserialize}; -//! use parity_scale_codec::{Encode, Decode, Compact, HasCompact, CompactAs, Error}; -//! -//! #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -//! #[derive(PartialEq, Eq, Clone)] -//! struct StructHasCompact(u32); -//! -//! impl CompactAs for StructHasCompact { -//! type As = u32; -//! -//! fn encode_as(&self) -> &Self::As { -//! &12 -//! } -//! -//! fn decode_from(_: Self::As) -> Result { -//! Ok(StructHasCompact(12)) -//! } -//! } -//! -//! impl From> for StructHasCompact { -//! fn from(_: Compact) -> Self { -//! StructHasCompact(12) -//! } -//! } -//! -//! #[derive(Debug, PartialEq, Encode, Decode)] -//! enum TestGenericHasCompact { -//! A { -//! #[codec(compact)] a: T -//! }, -//! } -//! -//! let a = TestGenericHasCompact::A:: { -//! a: StructHasCompact(12325678), -//! }; -//! -//! let encoded = a.encode(); -//! assert_eq!(encoded.len(), 2); -//! -//! # fn main() { } -//! ``` -//! -//! ## Derive attributes -//! -//! The derive implementation supports the following attributes: -//! - `codec(dumb_trait_bound)`: This attribute needs to be placed above the type that one of the -//! trait should be implemented for. It will make the algorithm that determines the to-add trait -//! bounds fall back to just use the type parameters of the type. This can be useful for situation -//! where the algorithm includes private types in the public interface. By using this attribute, -//! you should not get this error/warning again. -//! - `codec(skip)`: Needs to be placed above a field or variant and makes it to be skipped while -//! encoding/decoding. -//! - `codec(compact)`: Needs to be placed above a field and makes the field use compact encoding. -//! (The type needs to support compact encoding.) -//! - `codec(encoded_as = "OtherType")`: Needs to be placed above a field and makes the field being -//! encoded by using `OtherType`. -//! - `codec(index = 0)`: Needs to be placed above an enum variant to make the variant use the given -//! index when encoded. By default the index is determined by counting from `0` beginning wth the -//! first variant. -//! - `codec(encode_bound)`, `codec(decode_bound)` and `codec(mel_bound)`: All 3 attributes take -//! in a `where` clause for the `Encode`, `Decode` and `MaxEncodedLen` trait implementation for -//! the annotated type respectively. -//! - `codec(encode_bound(skip_type_params))`, `codec(decode_bound(skip_type_params))` and -//! `codec(mel_bound(skip_type_params))`: All 3 sub-attributes take in types as arguments to skip -//! trait derivation of the corresponding trait, e.g. T in -//! `codec(encode_bound(skip_type_params(T)))` will not contain a `Encode` trait bound while -//! `Encode` is being derived for the annotated type. - +#![doc = include_str!("../README.md")] #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] @@ -243,7 +21,7 @@ #[doc(hidden)] pub extern crate alloc; -#[cfg(feature = "parity-scale-codec-derive")] +#[cfg(feature = "derive")] #[allow(unused_imports)] #[macro_use] extern crate parity_scale_codec_derive; @@ -252,7 +30,7 @@ extern crate parity_scale_codec_derive; #[macro_use] extern crate serde_derive; -#[cfg(feature = "parity-scale-codec-derive")] +#[cfg(feature = "derive")] pub use parity_scale_codec_derive::*; #[cfg(feature = "std")] @@ -265,6 +43,7 @@ pub mod alloc { pub use std::collections; pub use std::sync; pub use std::rc; + pub use std::alloc; } mod codec; @@ -276,6 +55,7 @@ mod bit_vec; #[cfg(feature = "generic-array")] mod generic_array; mod decode_all; +mod decode_finished; mod depth_limit; mod encode_append; mod encode_like; @@ -288,7 +68,7 @@ mod const_encoded_len; pub use self::error::Error; pub use self::codec::{ Input, Output, Decode, Encode, Codec, EncodeAsRef, WrapperTypeEncode, WrapperTypeDecode, - OptionBool, DecodeLength, FullCodec, FullEncode, decode_vec_with_len + OptionBool, DecodeLength, FullCodec, FullEncode, decode_vec_with_len, }; #[cfg(feature = "std")] pub use self::codec::IoReader; @@ -296,6 +76,7 @@ pub use self::compact::{Compact, HasCompact, CompactAs, CompactLen, CompactRef}; pub use self::joiner::Joiner; pub use self::keyedvec::KeyedVec; pub use self::decode_all::DecodeAll; +pub use self::decode_finished::DecodeFinished; pub use self::depth_limit::DecodeLimit; pub use self::encode_append::EncodeAppend; pub use self::encode_like::{EncodeLike, Ref}; diff --git a/tests/mod.rs b/tests/mod.rs index ac6e3fd3..166e6750 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -643,3 +643,168 @@ fn no_warning_for_deprecated() { VariantB, } } + +#[test] +fn decoding_a_huge_array_inside_of_box_does_not_overflow_the_stack() { + let data = &[]; + let _ = Box::<[u8; 100 * 1024 * 1024]>::decode(&mut data.as_slice()); +} + +#[test] +fn decoding_a_huge_array_inside_of_rc_does_not_overflow_the_stack() { + let data = &[]; + let _ = std::rc::Rc::<[u8; 100 * 1024 * 1024]>::decode(&mut data.as_slice()); +} + +#[test] +fn decoding_a_huge_array_inside_of_arc_does_not_overflow_the_stack() { + let data = &[]; + let _ = std::sync::Arc::<[u8; 100 * 1024 * 1024]>::decode(&mut data.as_slice()); +} + +#[test] +fn decoding_an_array_of_boxed_zero_sized_types_works() { + #[cfg(not(miri))] + const SIZE: usize = 100 * 1024 * 1024; + + #[cfg(miri)] + const SIZE: usize = 1024; + + let data = &[]; + assert!(Box::<[(); SIZE]>::decode(&mut data.as_slice()).is_ok()); +} + +#[test] +fn incomplete_decoding_of_an_array_drops_partially_read_elements_if_reading_fails() { + thread_local! { + pub static COUNTER: core::cell::Cell = core::cell::Cell::new(0); + } + + #[derive(DeriveDecode)] + struct Foobar(u8); + + impl Drop for Foobar { + fn drop(&mut self) { + COUNTER.with(|counter| { + counter.set(counter.get() + 1); + }); + } + } + + let data = &[1, 2, 3]; + assert!(<[Foobar; 4]>::decode(&mut data.as_slice()).is_err()); + + COUNTER.with(|counter| { + assert_eq!(counter.get(), 3); + }); +} + +#[test] +fn incomplete_decoding_of_an_array_drops_partially_read_elements_if_reading_panics() { + thread_local! { + pub static COUNTER: core::cell::Cell = core::cell::Cell::new(0); + } + + struct Foobar(u8); + + impl Decode for Foobar { + fn decode(input: &mut I) -> Result { + let mut buffer = [0; 1]; + input.read(&mut buffer).unwrap(); + Ok(Self(buffer[0])) + } + } + + impl Drop for Foobar { + fn drop(&mut self) { + COUNTER.with(|counter| { + counter.set(counter.get() + 1); + }); + } + } + + let data = &[1, 2, 3]; + let result = std::panic::catch_unwind(|| { + let _ = <[Foobar; 4]>::decode(&mut data.as_slice()); + }); + + assert!(result.is_err()); + + COUNTER.with(|counter| { + assert_eq!(counter.get(), 3); + }); +} + +#[test] +fn deserializing_of_big_recursively_nested_enum_works() { + #[derive(PartialEq, Eq, DeriveDecode, DeriveEncode)] + struct Data([u8; 1472]); + + #[derive(PartialEq, Eq, DeriveDecode, DeriveEncode)] + enum Enum { + Nested(Vec), + Data(Data), + Variant1, + Variant2, + Variant3, + Variant4, + Variant5, + Variant6, + Variant7, + Variant8, + Variant9, + Variant10, + Variant11, + Variant12, + Variant13, + Variant14, + Variant15, + Variant16, + Variant17, + Variant18, + Variant19, + Variant20, + Variant21, + Variant22, + Variant23, + Variant24, + Variant25, + Variant26, + Variant27, + Variant28, + Variant29, + Variant30, + Variant31, + Variant32, + Variant33, + Variant34, + Variant35, + Variant36, + Variant37, + Variant38, + Variant39, + Variant40, + Variant41, + } + + fn gen_dummy_data(depth_remaining: usize) -> Enum { + let mut vec = vec![Enum::Data(Data([0; 1472]))]; + if depth_remaining > 0 { + vec.push(gen_dummy_data(depth_remaining - 1)); + } + Enum::Nested(vec) + } + + let obj = gen_dummy_data(32); + let data = obj.encode(); + + // This should not overflow the stack. + let obj_d = Enum::decode(&mut &data[..]).unwrap(); + + // NOTE: Not using `assert_eq` since we don't want to print out such a big object if this fails. + assert!(obj == obj_d); + + use parity_scale_codec::DecodeLimit; + let obj_d2 = Enum::decode_with_depth_limit(40, &mut &data[..]).unwrap(); + assert!(obj == obj_d2); +} From 977624def79f72acde8c1801f5d0d02bc5b88a6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 23:51:47 +0900 Subject: [PATCH 148/286] Bump arrayvec from 0.7.2 to 0.7.3 (#452) Bumps [arrayvec](https://github.com/bluss/arrayvec) from 0.7.2 to 0.7.3. - [Changelog](https://github.com/bluss/arrayvec/blob/master/CHANGELOG.md) - [Commits](https://github.com/bluss/arrayvec/compare/0.7.2...0.7.3) --- updated-dependencies: - dependency-name: arrayvec dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 67a320f1..2271de5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c" [[package]] name = "atty" From 6a81c42c142b2b389556d5d25c15bff04a00aef3 Mon Sep 17 00:00:00 2001 From: Koute Date: Mon, 19 Jun 2023 14:12:54 +0100 Subject: [PATCH 149/286] Fix all clippy warnings and add clippy to the CI (#455) * Prevent a `redundant_closure_call` downstream clippy warning * Bump version to 3.6.1 * Update changelog * Remove unnecessary `return` * Rewrite `append_or_new_vec_with_any_item` (fixes clippy error) * Fix all clippy warnings * Add a clippy job to the CI * Install clippy on the CI * Fail the clippy job if clippy fails * Update comment in `src/compact.rs` Co-authored-by: Oliver Tale-Yazdi * Rename `extend_encoded_vec` to `append_or_new_impl` for consistency * Simplify vec capacity calculation inside `append_or_new_impl` * Update changelog again * Remove unused import * Use `checked_add` in `append_or_new_impl` * Fix clippy warnings in `parity-scale-codec-derive` too * Run clippy for `parity-scale-codec-derive` on the CI * Remove some stray tabs from doc comments * Prevent `unnecessary_cast` clippy warning in derive generated code * Add date to the changelog * Fix one more clippy lint in the derive crate --------- Co-authored-by: Oliver Tale-Yazdi --- .gitlab-ci.yml | 9 ++++ CHANGELOG.md | 6 +++ Cargo.lock | 4 +- Cargo.toml | 4 +- derive/Cargo.toml | 2 +- derive/src/decode.rs | 9 ++-- derive/src/encode.rs | 1 + derive/src/lib.rs | 28 +++++----- derive/src/trait_bounds.rs | 15 +++--- derive/src/utils.rs | 22 ++++---- src/codec.rs | 19 +++---- src/compact.rs | 11 ++-- src/decode_finished.rs | 2 + src/encode_append.rs | 101 +++++++++++++++++-------------------- src/encode_like.rs | 2 +- src/lib.rs | 4 +- tests/clippy.rs | 26 ++++++++++ 17 files changed, 154 insertions(+), 111 deletions(-) create mode 100644 tests/clippy.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7ba348f3..ea0b10ce 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,6 +42,15 @@ default: #### stage: check +check-clippy: + stage: check + <<: *docker-env + script: + - rustup component add clippy --toolchain stable-x86_64-unknown-linux-gnu + - time cargo +stable clippy --locked -- -Dwarnings + - time cargo +stable clippy --locked -p parity-scale-codec-derive -- -Dwarnings + - time cargo +stable clippy --locked --test clippy -- -Dwarnings + check-rust-stable-no_derive_no_std: stage: check <<: *docker-env diff --git a/CHANGELOG.md b/CHANGELOG.md index c50cad3a..20385c56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.6.1] - 2023-06-19 + +### Fixed + +- Deriving `Decode` will not trigger clippy warnings anymore + ## [3.6.0] - 2023-06-15 ### Added diff --git a/Cargo.lock b/Cargo.lock index 2271de5c..f7759abf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parity-scale-codec" -version = "3.6.0" +version = "3.6.1" dependencies = [ "arbitrary", "arrayvec", @@ -589,7 +589,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.0" +version = "3.6.1" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index f43c6cf5..d4ce498f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.6.0" +version = "3.6.1" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.164", optional = true } -parity-scale-codec-derive = { path = "derive", version = ">= 3.6.0", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = ">= 3.6.1", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 575d7565..56547259 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.6.0" +version = "3.6.1" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" diff --git a/derive/src/decode.rs b/derive/src/decode.rs index 5787ff5b..47eb1b92 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -71,10 +71,12 @@ pub fn quote( ); quote_spanned! { v.span() => + #[allow(clippy::unnecessary_cast)] __codec_x_edqy if __codec_x_edqy == #index as ::core::primitive::u8 => { // NOTE: This lambda is necessary to work around an upstream bug // where each extra branch results in excessive stack usage: // https://github.com/rust-lang/rust/issues/34283 + #[allow(clippy::redundant_closure_call)] return (move || { #create })(); @@ -96,10 +98,11 @@ pub fn quote( { #( #recurse )* _ => { + #[allow(clippy::redundant_closure_call)] return (move || { - return ::core::result::Result::Err( + ::core::result::Result::Err( <_ as ::core::convert::Into<_>>::into(#invalid_variant_err_msg) - ); + ) })(); }, } @@ -178,7 +181,7 @@ fn create_instance( let name_ident = &f.ident; let field_name = match name_ident { Some(a) => format!("{}::{}", name_str, a), - None => format!("{}", name_str), // Should never happen, fields are named. + None => name_str.to_string(), // Should never happen, fields are named. }; let decode = create_decode_expr(f, &field_name, input, crate_path); diff --git a/derive/src/encode.rs b/derive/src/encode.rs index b2badc17..06339c40 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -281,6 +281,7 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenS Fields::Unit => { quote_spanned! { f.span() => #type_name :: #name => { + #[allow(clippy::unnecessary_cast)] #dest.push_byte(#index as ::core::primitive::u8); } } diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 9d80304b..c37412a8 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -78,12 +78,12 @@ fn wrap_with_dummy_const( /// # use parity_scale_codec::{Encode as _, HasCompact}; /// #[derive(Encode)] /// struct StructType { -/// #[codec(skip)] -/// a: u32, -/// #[codec(compact)] -/// b: u32, -/// #[codec(encoded_as = "::Type")] -/// c: u32, +/// #[codec(skip)] +/// a: u32, +/// #[codec(compact)] +/// b: u32, +/// #[codec(encoded_as = "::Type")] +/// c: u32, /// } /// ``` /// @@ -108,12 +108,12 @@ fn wrap_with_dummy_const( /// # use parity_scale_codec::Encode as _; /// #[derive(Encode)] /// enum EnumType { -/// #[codec(index = 15)] -/// A, -/// #[codec(skip)] -/// B, -/// C = 3, -/// D, +/// #[codec(index = 15)] +/// A, +/// #[codec(skip)] +/// B, +/// C = 3, +/// D, /// } /// /// assert_eq!(EnumType::A.encode(), vec![15]); @@ -282,7 +282,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr Fields::Named(ref fields) if utils::filter_skip_named(fields).count() == 1 => { let recurse = fields.named.iter().map(|f| { let name_ident = &f.ident; - let val_or_default = val_or_default(&f); + let val_or_default = val_or_default(f); quote_spanned!(f.span()=> #name_ident: #val_or_default) }); let field = utils::filter_skip_named(fields).next().expect("Exactly one field"); @@ -292,7 +292,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr }, Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => { let recurse = fields.unnamed.iter().enumerate().map(|(_, f)| { - let val_or_default = val_or_default(&f); + let val_or_default = val_or_default(f); quote_spanned!(f.span()=> #val_or_default) }); let (id, field) = diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index f808588d..6b044efe 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -87,7 +87,7 @@ struct FindTypePathsNotStartOrContainIdent<'a> { impl<'a, 'ast> Visit<'ast> for FindTypePathsNotStartOrContainIdent<'a> { fn visit_type_path(&mut self, i: &'ast TypePath) { - if type_path_or_sub_starts_with_ident(i, &self.ident) { + if type_path_or_sub_starts_with_ident(i, self.ident) { visit::visit_type_path(self, i); } else { self.result.push(i.clone()); @@ -104,6 +104,7 @@ fn find_type_paths_not_start_or_contain_ident(ty: &Type, ident: &Ident) -> Vec( input_ident: &Ident, @@ -138,7 +139,7 @@ pub fn add( let codec_types = get_types_to_add_trait_bound(input_ident, data, &ty_params, dumb_trait_bounds)?; - let compact_types = collect_types(&data, utils::is_compact)? + let compact_types = collect_types(data, utils::is_compact)? .into_iter() // Only add a bound if the type uses a generic .filter(|ty| type_contain_idents(ty, &ty_params)) @@ -146,7 +147,7 @@ pub fn add( let skip_types = if codec_skip_bound.is_some() { let needs_default_bound = |f: &syn::Field| utils::should_skip(&f.attrs); - collect_types(&data, needs_default_bound)? + collect_types(data, needs_default_bound)? .into_iter() // Only add a bound if the type uses a generic .filter(|ty| type_contain_idents(ty, &ty_params)) @@ -191,18 +192,18 @@ fn get_types_to_add_trait_bound( utils::get_encoded_as_type(f).is_none() && !utils::should_skip(&f.attrs) }; - let res = collect_types(&data, needs_codec_bound)? + let res = collect_types(data, needs_codec_bound)? .into_iter() // Only add a bound if the type uses a generic - .filter(|ty| type_contain_idents(ty, &ty_params)) + .filter(|ty| type_contain_idents(ty, ty_params)) // If a struct contains itself as field type, we can not add this type into the where // clause. This is required to work a round the following compiler bug: https://github.com/rust-lang/rust/issues/47032 .flat_map(|ty| { find_type_paths_not_start_or_contain_ident(&ty, input_ident) .into_iter() - .map(|ty| Type::Path(ty.clone())) + .map(Type::Path) // Remove again types that do not contain any of our generic parameters - .filter(|ty| type_contain_idents(ty, &ty_params)) + .filter(|ty| type_contain_idents(ty, ty_params)) // Add back the original type, as we don't want to loose it. .chain(iter::once(ty)) }) diff --git a/derive/src/utils.rs b/derive/src/utils.rs index 585ce9a0..88779520 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -60,7 +60,7 @@ pub fn variant_index(v: &Variant, i: usize) -> TokenStream { index.map(|i| quote! { #i }).unwrap_or_else(|| { v.discriminant .as_ref() - .map(|&(_, ref expr)| quote! { #expr }) + .map(|(_, expr)| quote! { #expr }) .unwrap_or_else(|| quote! { #i }) }) } @@ -133,7 +133,7 @@ fn crate_access() -> syn::Result { const DEF_CRATE: &str = "parity-scale-codec"; match crate_name(DEF_CRATE) { Ok(FoundCrate::Itself) => { - let name = DEF_CRATE.to_string().replace("-", "_"); + let name = DEF_CRATE.to_string().replace('-', "_"); Ok(syn::Ident::new(&name, Span::call_site())) }, Ok(FoundCrate::Name(name)) => Ok(Ident::new(&name, Span::call_site())), @@ -256,15 +256,15 @@ pub fn custom_mel_trait_bound(attrs: &[Attribute]) -> Option(fields: &'a syn::FieldsNamed) -> impl Iterator + 'a { +pub fn filter_skip_named(fields: &syn::FieldsNamed) -> impl Iterator { fields.named.iter().filter(|f| !should_skip(&f.attrs)) } /// Given a set of unnamed fields, return an iterator of `(index, Field)` where all fields /// marked `#[codec(skip)]` are filtered out. -pub fn filter_skip_unnamed<'a>( - fields: &'a syn::FieldsUnnamed, -) -> impl Iterator + 'a { +pub fn filter_skip_unnamed( + fields: &syn::FieldsUnnamed, +) -> impl Iterator { fields.unnamed.iter().enumerate().filter(|(_, f)| !should_skip(&f.attrs)) } @@ -359,10 +359,10 @@ fn check_field_attribute(attr: &Attribute) -> syn::Result<()> { .map(|_| ()) .map_err(|_e| syn::Error::new(lit_str.span(), "Invalid token stream")), - elt @ _ => Err(syn::Error::new(elt.span(), field_error)), + elt => Err(syn::Error::new(elt.span(), field_error)), } }, - meta @ _ => Err(syn::Error::new(meta.span(), field_error)), + meta => Err(syn::Error::new(meta.span(), field_error)), } } else { Ok(()) @@ -393,10 +393,10 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { .map(|_| ()) .map_err(|_| syn::Error::new(lit_int.span(), "Index must be in 0..255")), - elt @ _ => Err(syn::Error::new(elt.span(), variant_error)), + elt => Err(syn::Error::new(elt.span(), variant_error)), } }, - meta @ _ => Err(syn::Error::new(meta.span(), variant_error)), + meta => Err(syn::Error::new(meta.span(), variant_error)), } } else { Ok(()) @@ -422,7 +422,7 @@ fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => Ok(()), - elt @ _ => Err(syn::Error::new(elt.span(), top_error)), + elt => Err(syn::Error::new(elt.span(), top_error)), } }, _ => Err(syn::Error::new(attr.span(), top_error)), diff --git a/src/codec.rs b/src/codec.rs index 5ccc30ae..386f4fc9 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -483,19 +483,19 @@ impl Encode for X where X: WrapperTypeEncode, { fn size_hint(&self) -> usize { - (&**self).size_hint() + (**self).size_hint() } fn using_encoded R>(&self, f: F) -> R { - (&**self).using_encoded(f) + (**self).using_encoded(f) } fn encode(&self) -> Vec { - (&**self).encode() + (**self).encode() } fn encode_to(&self, dest: &mut W) { - (&**self).encode_to(dest) + (**self).encode_to(dest) } } @@ -896,6 +896,7 @@ const fn calculate_array_bytesize() -> usize { const OK: () = assert!(core::mem::size_of::().checked_mul(N).is_some(), "array size overflow"); } + #[allow(clippy::let_unit_value)] let () = AssertNotOverflow::::OK; core::mem::size_of::() * N } @@ -1014,7 +1015,7 @@ impl Decode for [T; N] { // SAFETY: We've initialized the whole slice so calling this is safe. unsafe { - return Ok(DecodeFinished::assert_decoding_finished()); + Ok(DecodeFinished::assert_decoding_finished()) } } @@ -1093,7 +1094,7 @@ pub(crate) fn compact_encode_len_to(dest: &mut W, len: usize impl Encode for [T] { fn size_hint(&self) -> usize { - mem::size_of::() + mem::size_of::() * self.len() + mem::size_of::() + core::mem::size_of_val(self) } fn encode_to(&self, dest: &mut W) { @@ -1115,7 +1116,7 @@ where debug_assert!(MAX_PREALLOCATION >= mem::size_of::(), "Invalid precondition"); let byte_len = items_len.checked_mul(mem::size_of::()) - .ok_or_else(|| "Item is too big and cannot be allocated")?; + .ok_or("Item is too big and cannot be allocated")?; let input_len = input.remaining_len()?; @@ -1131,8 +1132,8 @@ where let r = if input_len.is_some() || byte_len < MAX_PREALLOCATION { // Here we pre-allocate the whole buffer. let mut items: Vec = vec![Default::default(); items_len]; - let mut bytes_slice = items.as_mut_byte_slice(); - input.read(&mut bytes_slice)?; + let bytes_slice = items.as_mut_byte_slice(); + input.read(bytes_slice)?; items } else { diff --git a/src/compact.rs b/src/compact.rs index 89a7ea2c..a23d09db 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -493,7 +493,7 @@ impl Decode for Compact { return Err(U32_OUT_OF_RANGE.into()); } }, - 3|_ => { // |_. yeah, i know. + 3 => { if prefix >> 2 == 0 { // just 4 bytes. ok. let x = u32::decode(input)?; @@ -506,7 +506,8 @@ impl Decode for Compact { // Out of range for a 32-bit quantity. return Err(U32_OUT_OF_RANGE.into()); } - } + }, + _ => unreachable!(), })) } } @@ -532,7 +533,7 @@ impl Decode for Compact { return Err(U64_OUT_OF_RANGE.into()); } }, - 3|_ => match (prefix >> 2) + 4 { + 3 => match (prefix >> 2) + 4 { 4 => { let x = u32::decode(input)?; if x > u32::max_value() >> 2 { @@ -562,6 +563,7 @@ impl Decode for Compact { } }, }, + _ => unreachable!(), })) } } @@ -587,7 +589,7 @@ impl Decode for Compact { return Err(U128_OUT_OF_RANGE.into()); } }, - 3|_ => match (prefix >> 2) + 4 { + 3 => match (prefix >> 2) + 4 { 4 => { let x = u32::decode(input)?; if x > u32::max_value() >> 2 { @@ -625,6 +627,7 @@ impl Decode for Compact { } }, }, + _ => unreachable!(), })) } } diff --git a/src/decode_finished.rs b/src/decode_finished.rs index aa6feb98..c7bdeee3 100644 --- a/src/decode_finished.rs +++ b/src/decode_finished.rs @@ -27,6 +27,8 @@ pub struct DecodeFinished(PhantomData<*const ()>); impl DecodeFinished { /// Assert that the decoding has finished. /// + /// # Safety + /// /// Should be used in [`Decode::decode_into`] to signify that /// the `MaybeUninit` passed into that function was properly initialized. #[inline] diff --git a/src/encode_append.rs b/src/encode_append.rs index 11fbf1cb..6f60f6aa 100644 --- a/src/encode_append.rs +++ b/src/encode_append.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use core::{iter::ExactSizeIterator, mem}; +use core::iter::ExactSizeIterator; use crate::alloc::vec::Vec; use crate::{Encode, Decode, Error}; @@ -64,7 +64,7 @@ impl EncodeAppend for Vec { EncodeLikeItem: EncodeLike, I::IntoIter: ExactSizeIterator, { - append_or_new_vec_with_any_item(self_encoded, iter) + append_or_new_impl(self_encoded, iter) } } @@ -80,25 +80,15 @@ impl EncodeAppend for crate::alloc::collections::VecDeque { EncodeLikeItem: EncodeLike, I::IntoIter: ExactSizeIterator, { - append_or_new_vec_with_any_item(self_encoded, iter) + append_or_new_impl(self_encoded, iter) } } -fn extract_length_data(data: &[u8], input_len: usize) -> Result<(u32, usize, usize), Error> { - let len = u32::from(Compact::::decode(&mut &data[..])?); - let new_len = len - .checked_add(input_len as u32) - .ok_or_else(|| "New vec length greater than `u32::TEST_VALUE()`.")?; - - let encoded_len = Compact::::compact_len(&len); - let encoded_new_len = Compact::::compact_len(&new_len); - - Ok((new_len, encoded_len, encoded_new_len)) -} - -// Item must have same encoding as encoded value in the encoded vec. -fn append_or_new_vec_with_any_item( - mut self_encoded: Vec, +/// Extends a SCALE-encoded vector with elements from the given `iter`. +/// +/// `vec` must either be empty, or contain a valid SCALE-encoded `Vec` payload. +fn append_or_new_impl( + mut vec: Vec, iter: I, ) -> Result, Error> where @@ -107,46 +97,47 @@ where I::IntoIter: ExactSizeIterator, { let iter = iter.into_iter(); - let input_len = iter.len(); - - // No data present, just encode the given input data. - if self_encoded.is_empty() { - crate::codec::compact_encode_len_to(&mut self_encoded, iter.len())?; - iter.for_each(|e| e.encode_to(&mut self_encoded)); - return Ok(self_encoded); - } - - let (new_len, encoded_len, encoded_new_len) = extract_length_data(&self_encoded, input_len)?; - - let replace_len = |dest: &mut Vec| { - Compact(new_len).using_encoded(|e| { - dest[..encoded_new_len].copy_from_slice(e); - }) - }; - - let append_new_elems = |dest: &mut Vec| iter.for_each(|a| a.encode_to(dest)); + let items_to_append = iter.len(); - // If old and new encoded len is equal, we don't need to copy the - // already encoded data. - if encoded_len == encoded_new_len { - replace_len(&mut self_encoded); - append_new_elems(&mut self_encoded); - - Ok(self_encoded) + if vec.is_empty() { + crate::codec::compact_encode_len_to(&mut vec, items_to_append)?; } else { - let size = encoded_new_len + self_encoded.len() - encoded_len; - - let mut res = Vec::with_capacity(size + input_len * mem::size_of::()); - unsafe { res.set_len(size); } - - // Insert the new encoded len, copy the already encoded data and - // add the new element. - replace_len(&mut res); - res[encoded_new_len..size].copy_from_slice(&self_encoded[encoded_len..]); - append_new_elems(&mut res); - - Ok(res) + let old_item_count = u32::from(Compact::::decode(&mut &vec[..])?); + let new_item_count = old_item_count + .checked_add(items_to_append as u32) + .ok_or("cannot append new items into a SCALE-encoded vector: length overflow due to too many items")?; + + let old_item_count_encoded_bytesize = Compact::::compact_len(&old_item_count); + let new_item_count_encoded_bytesize = Compact::::compact_len(&new_item_count); + + if old_item_count_encoded_bytesize == new_item_count_encoded_bytesize { + // The size of the length as encoded by SCALE didn't change, so we can just + // keep the old buffer as-is. We just need to update the length prefix. + Compact(new_item_count).using_encoded(|length_encoded| + vec[..old_item_count_encoded_bytesize].copy_from_slice(length_encoded) + ); + } else { + // We can't update the length as the new length prefix will take up more + // space when encoded, so we need to move our data to make space for it. + + // If this overflows then it means that `vec` is bigger that half of the + // total address space, which means that it will be impossible to allocate + // enough memory for another vector of at least the same size. + // + // So let's just immediately bail with an error if this happens. + let new_capacity = vec.len().checked_mul(2) + .ok_or("cannot append new items into a SCALE-encoded vector: new vector won't fit in memory")?; + let mut new_vec = Vec::with_capacity(new_capacity); + + crate::codec::compact_encode_len_to(&mut new_vec, new_item_count as usize)?; + new_vec.extend_from_slice(&vec[old_item_count_encoded_bytesize..]); + vec = new_vec; + } } + + // And now we just need to append the new items. + iter.for_each(|e| e.encode_to(&mut vec)); + Ok(vec) } #[cfg(test)] diff --git a/src/encode_like.rs b/src/encode_like.rs index 01c6d673..36023dd9 100644 --- a/src/encode_like.rs +++ b/src/encode_like.rs @@ -89,7 +89,7 @@ pub trait EncodeLike: Sized + Encode {} pub struct Ref<'a, T: EncodeLike, U: Encode>(&'a T, core::marker::PhantomData); impl<'a, T: EncodeLike, U: Encode> core::ops::Deref for Ref<'a, T, U> { type Target = T; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { self.0 } } impl<'a, T: EncodeLike, U: Encode> From<&'a T> for Ref<'a, T, U> { diff --git a/src/lib.rs b/src/lib.rs index 133c736d..fb247601 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -107,8 +107,8 @@ pub use const_encoded_len::ConstEncodedLen; /// # use parity_scale_codec::{Encode, MaxEncodedLen}; /// #[derive(Encode, MaxEncodedLen)] /// enum GenericEnum { -/// A, -/// B(T), +/// A, +/// B(T), /// } /// /// assert_eq!(GenericEnum::::max_encoded_len(), u8::max_encoded_len() + u8::max_encoded_len()); diff --git a/tests/clippy.rs b/tests/clippy.rs new file mode 100644 index 00000000..f1cb7e6d --- /dev/null +++ b/tests/clippy.rs @@ -0,0 +1,26 @@ +// 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. + +//! This file is checked by clippy to make sure that the code generated by the derive macro +//! doesn't spew out warnings/errors in users' code. + +use parity_scale_codec_derive::{Decode, Encode}; + +#[repr(u8)] +#[derive(Decode, Encode)] +pub enum CLike { + Foo = 0, + Bar = 1, +} From 07c7e2c5a34da36684339710d46e2ea02a478dd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 21:27:34 +0200 Subject: [PATCH 150/286] Bump arrayvec from 0.7.3 to 0.7.4 (#460) Bumps [arrayvec](https://github.com/bluss/arrayvec) from 0.7.3 to 0.7.4. - [Changelog](https://github.com/bluss/arrayvec/blob/master/CHANGELOG.md) - [Commits](https://github.com/bluss/arrayvec/compare/0.7.3...0.7.4) --- updated-dependencies: - dependency-name: arrayvec dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7759abf..3f520769 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "atty" From c16f3b1212f57e3a552c3f14f1909dd9faaa691c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Jun 2023 01:36:23 +0200 Subject: [PATCH 151/286] Bump quote from 1.0.28 to 1.0.29 (#463) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.28 to 1.0.29. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.28...1.0.29) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- derive/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f520769..7ef594ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,9 +650,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] @@ -696,9 +696,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 56547259..1c885418 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.28" +quote = "1.0.29" proc-macro2 = "1.0.60" proc-macro-crate = "1.1.3" From 86e51621b69907d91f8e4ab84936f0eae21220f2 Mon Sep 17 00:00:00 2001 From: Koute Date: Fri, 30 Jun 2023 13:01:09 +0100 Subject: [PATCH 152/286] Fix stack overflow when decoding big array newtypes wrapped in a `Box` (#462) * Fix stack overflow when decoding big array newtypes wrapped in a `Box` * Bump version to 3.6.2 * Update changelog * Fix indentation * Add an extra assert to make sure the number of non-ZST fields is correct * Add even more tests * Add release date to changelog --- CHANGELOG.md | 6 ++++ Cargo.lock | 4 +-- Cargo.toml | 4 +-- derive/Cargo.toml | 2 +- derive/src/decode.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++ derive/src/lib.rs | 22 ++++++++++++ derive/src/utils.rs | 22 +++++++++++- tests/mod.rs | 82 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 221 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20385c56..3f94e636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.6.2] - 2023-06-30 + +### Fixed + +- Trying to deserialize a boxed newtype containing a big array won't overflow the stack anymore. + ## [3.6.1] - 2023-06-19 ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 7ef594ea..58dd425a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parity-scale-codec" -version = "3.6.1" +version = "3.6.2" dependencies = [ "arbitrary", "arrayvec", @@ -589,7 +589,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.1" +version = "3.6.2" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index d4ce498f..ce276305 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.6.1" +version = "3.6.2" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.164", optional = true } -parity-scale-codec-derive = { path = "derive", version = ">= 3.6.1", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = ">= 3.6.2", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 1c885418..86d0028a 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.6.1" +version = "3.6.2" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" diff --git a/derive/src/decode.rs b/derive/src/decode.rs index 47eb1b92..81029bc1 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -113,6 +113,91 @@ pub fn quote( } } +pub fn quote_decode_into( + data: &Data, + crate_path: &syn::Path, + input: &TokenStream, + attrs: &[syn::Attribute] +) -> Option { + // Make sure the type is `#[repr(transparent)]`, as this guarantees that + // there can be only one field that is not zero-sized. + if !crate::utils::is_transparent(attrs) { + return None; + } + + let fields = match data { + Data::Struct( + syn::DataStruct { + fields: Fields::Named(syn::FieldsNamed { named: fields, .. }) | + Fields::Unnamed(syn::FieldsUnnamed { unnamed: fields, .. }), + .. + } + ) => { + fields + }, + _ => return None + }; + + if fields.is_empty() { + return None; + } + + // Bail if there are any extra attributes which could influence how the type is decoded. + if fields.iter().any(|field| + utils::get_encoded_as_type(field).is_some() || + utils::is_compact(field) || + utils::should_skip(&field.attrs) + ) { + return None; + } + + // Go through each field and call `decode_into` on it. + // + // Normally if there's more than one field in the struct this would be incorrect, + // however since the struct's marked as `#[repr(transparent)]` we're guaranteed that + // there's at most one non zero-sized field, so only one of these `decode_into` calls + // should actually do something, and the rest should just be dummy calls that do nothing. + let mut decode_fields = Vec::new(); + let mut sizes = Vec::new(); + let mut non_zst_field_count = Vec::new(); + for field in fields { + let field_type = &field.ty; + decode_fields.push(quote! {{ + let dst_: &mut ::core::mem::MaybeUninit = dst_; // To make sure the type is what we expect. + + // Here we cast `&mut MaybeUninit` into a `&mut MaybeUninit<#field_type>`. + // + // SAFETY: The struct is marked as `#[repr(transparent)]` so the address of every field will + // be the same as the address of the struct itself. + let dst_: &mut ::core::mem::MaybeUninit<#field_type> = unsafe { + &mut *dst_.as_mut_ptr().cast::<::core::mem::MaybeUninit<#field_type>>() + }; + <#field_type as #crate_path::Decode>::decode_into(#input, dst_)?; + }}); + + if !sizes.is_empty() { + sizes.push(quote! { + }); + } + sizes.push(quote! { ::core::mem::size_of::<#field_type>() }); + + if !non_zst_field_count.is_empty() { + non_zst_field_count.push(quote! { + }); + } + non_zst_field_count.push(quote! { if ::core::mem::size_of::<#field_type>() > 0 { 1 } else { 0 } }); + } + + Some(quote!{ + // Just a sanity check. These should always be true and will be optimized-out. + assert_eq!(#(#sizes)*, ::core::mem::size_of::()); + assert!(#(#non_zst_field_count)* <= 1); + + #(#decode_fields)* + + // SAFETY: We've successfully called `decode_into` for all of the fields. + unsafe { Ok(#crate_path::DecodeFinished::assert_decoding_finished()) } + }) +} + fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_path: &syn::Path) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); let compact = utils::is_compact(field); diff --git a/derive/src/lib.rs b/derive/src/lib.rs index c37412a8..2dba4610 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -208,6 +208,26 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let decoding = decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_, &crate_path); + let decode_into_body = decode::quote_decode_into( + &input.data, + &crate_path, + &input_, + &input.attrs + ); + + let impl_decode_into = if let Some(body) = decode_into_body { + quote! { + fn decode_into<__CodecInputEdqy: #crate_path::Input>( + #input_: &mut __CodecInputEdqy, + dst_: &mut ::core::mem::MaybeUninit, + ) -> ::core::result::Result<#crate_path::DecodeFinished, #crate_path::Error> { + #body + } + } + } else { + quote! {} + }; + let impl_block = quote! { #[automatically_derived] impl #impl_generics #crate_path::Decode for #name #ty_generics #where_clause { @@ -216,6 +236,8 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream ) -> ::core::result::Result { #decoding } + + #impl_decode_into } }; diff --git a/derive/src/utils.rs b/derive/src/utils.rs index 88779520..5a2fa45d 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -20,7 +20,7 @@ use std::str::FromStr; use proc_macro2::TokenStream; -use quote::quote; +use quote::{ToTokens, quote}; use syn::{ parse::Parse, punctuated::Punctuated, spanned::Spanned, token, Attribute, Data, DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, MetaNameValue, NestedMeta, Path, Variant, @@ -431,3 +431,23 @@ fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { Ok(()) } } + +fn check_repr(attrs: &[syn::Attribute], value: &str) -> bool { + let mut result = false; + for raw_attr in attrs { + let path = raw_attr.path.clone().into_token_stream().to_string(); + if path != "repr" { + continue; + } + + result = raw_attr.tokens.clone().into_token_stream().to_string() == value; + } + + result +} + +/// Checks whether the given attributes contain a `#[repr(transparent)]`. +pub fn is_transparent(attrs: &[syn::Attribute]) -> bool { + // TODO: When migrating to syn 2 the `"(transparent)"` needs to be changed into `"transparent"`. + check_repr(attrs, "(transparent)") +} diff --git a/tests/mod.rs b/tests/mod.rs index 166e6750..e422c0a8 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -662,6 +662,88 @@ fn decoding_a_huge_array_inside_of_arc_does_not_overflow_the_stack() { let _ = std::sync::Arc::<[u8; 100 * 1024 * 1024]>::decode(&mut data.as_slice()); } +#[test] +fn decoding_a_huge_boxed_newtype_array_does_not_overflow_the_stack() { + #[derive(DeriveDecode)] + #[repr(transparent)] + struct HugeArrayNewtype([u8; 100 * 1024 * 1024]); + + #[derive(DeriveDecode)] + struct HugeArrayNewtypeBox(Box); + + let data = &[]; + assert!(HugeArrayNewtypeBox::decode(&mut data.as_slice()).is_err()); +} + +#[test] +fn decoding_two_indirectly_boxed_arrays_works() { + // This test will fail if the check for `#[repr(transparent)]` in the derive crate + // doesn't work when implementing `Decode::decode_into`. + #[derive(DeriveDecode)] + #[derive(PartialEq, Eq, Debug)] + struct SmallArrays([u8; 2], [u8; 2]); + + #[derive(DeriveDecode)] + struct SmallArraysBox(Box); + + let data = &[1, 2, 3, 4]; + assert_eq!(*SmallArraysBox::decode(&mut data.as_slice()).unwrap().0, SmallArrays([1, 2], [3, 4])); +} + +#[test] +fn zero_sized_types_are_properly_decoded_in_a_transparent_boxed_struct() { + #[derive(DeriveDecode)] + #[repr(transparent)] + struct ZstTransparent; + + #[derive(DeriveDecode)] + struct ZstNonTransparent; + + struct ConsumeByte; + + #[derive(DeriveDecode)] + #[repr(transparent)] + struct NewtypeWithZst { + _zst_1: ConsumeByte, + _zst_2: ZstTransparent, + _zst_3: ZstNonTransparent, + field: [u8; 1], + _zst_4: ConsumeByte + } + + #[derive(DeriveDecode)] + struct NewtypeWithZstBox(Box); + + impl Decode for ConsumeByte { + fn decode(input: &mut I) -> Result { + let mut buffer = [0; 1]; + input.read(&mut buffer).unwrap(); + Ok(Self) + } + } + + let data = &[1, 2, 3]; + assert_eq!(NewtypeWithZst::decode(&mut data.as_slice()).unwrap().field, [2]); +} + +#[test] +fn boxed_zero_sized_newtype_with_everything_being_transparent_is_decoded_correctly() { + #[derive(DeriveDecode)] + #[repr(transparent)] + struct Zst; + + #[derive(DeriveDecode)] + #[repr(transparent)] + struct NewtypeWithZst(Zst); + + #[derive(DeriveDecode)] + #[repr(transparent)] + struct NewtypeWithZstBox(Box); + + let data = &[]; + assert!(NewtypeWithZst::decode(&mut data.as_slice()).is_ok()); +} + #[test] fn decoding_an_array_of_boxed_zero_sized_types_works() { #[cfg(not(miri))] From a7c00496475cef1f79acf61f1f2275a516b70213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 3 Jul 2023 13:25:56 +0200 Subject: [PATCH 153/286] Fix prelude imports in `decode_into` (#464) --- CHANGELOG.md | 7 +++++++ Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- derive/src/decode.rs | 6 +++--- tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs | 6 ++++++ 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f94e636..44d5d49a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.6.3] - 2023-07-03 + +### Fixed + +- Provide full path to elements from `::core` in `Decode` derivation (caused compilation error when + `no-implicit-prelude` was used). + ## [3.6.2] - 2023-06-30 ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 58dd425a..19c9856f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parity-scale-codec" -version = "3.6.2" +version = "3.6.3" dependencies = [ "arbitrary", "arrayvec", @@ -589,7 +589,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.2" +version = "3.6.3" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index ce276305..fc1c8359 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.6.2" +version = "3.6.3" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.164", optional = true } -parity-scale-codec-derive = { path = "derive", version = ">= 3.6.2", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = ">= 3.6.3", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 86d0028a..f266ef5a 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.6.2" +version = "3.6.3" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" diff --git a/derive/src/decode.rs b/derive/src/decode.rs index 81029bc1..38d5565a 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -188,13 +188,13 @@ pub fn quote_decode_into( Some(quote!{ // Just a sanity check. These should always be true and will be optimized-out. - assert_eq!(#(#sizes)*, ::core::mem::size_of::()); - assert!(#(#non_zst_field_count)* <= 1); + ::core::assert_eq!(#(#sizes)*, ::core::mem::size_of::()); + ::core::assert!(#(#non_zst_field_count)* <= 1); #(#decode_fields)* // SAFETY: We've successfully called `decode_into` for all of the fields. - unsafe { Ok(#crate_path::DecodeFinished::assert_decoding_finished()) } + unsafe { ::core::result::Result::Ok(#crate_path::DecodeFinished::assert_decoding_finished()) } }) } diff --git a/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs b/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs index 69f01440..a022ed22 100644 --- a/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs +++ b/tests/scale_codec_ui/pass/decode-no-implicit-prelude.rs @@ -9,6 +9,12 @@ pub struct Struct { field_4: i64, } +#[derive(::parity_scale_codec::Decode)] +#[repr(transparent)] +struct Transparent { + a: u8 +} + #[derive(::parity_scale_codec::Decode)] #[codec(crate = ::parity_scale_codec)] pub enum Enum { From dbdab6040e7c3c92eaf3c17a40f858fd97bfa155 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jul 2023 00:04:23 +0200 Subject: [PATCH 154/286] Bump serde from 1.0.164 to 1.0.165 (#466) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.164 to 1.0.165. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.164...v1.0.165) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 14 +++++++------- Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19c9856f..5103bf07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,22 +863,22 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.165" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "c939f902bb7d0ccc5bce4f03297e161543c2dcb30914faf032c2bd0b7a0d48fc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.165" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "6eaae920e25fffe4019b75ff65e7660e72091e59dd204cb5849bbd6a3fd343d7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.23", ] [[package]] @@ -905,9 +905,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.16" +version = "2.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index fc1c8359..c8a2a701 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.164", optional = true } +serde = { version = "1.0.165", optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.3", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From d7b505a47c5955861a8bbd32d659be3db05ef8fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 11:50:23 +0200 Subject: [PATCH 155/286] Bump paste from 1.0.12 to 1.0.13 (#469) Bumps [paste](https://github.com/dtolnay/paste) from 1.0.12 to 1.0.13. - [Release notes](https://github.com/dtolnay/paste/releases) - [Commits](https://github.com/dtolnay/paste/compare/1.0.12...1.0.13) --- updated-dependencies: - dependency-name: paste dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5103bf07..43708470 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -600,9 +600,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" [[package]] name = "plotters" From 705f4c301d8761cb32f190783cbf0a02a6907641 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 15:11:23 +0200 Subject: [PATCH 156/286] Bump serde from 1.0.165 to 1.0.166 (#468) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.165 to 1.0.166. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.165...v1.0.166) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43708470..166a1acd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,18 +863,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.165" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c939f902bb7d0ccc5bce4f03297e161543c2dcb30914faf032c2bd0b7a0d48fc" +checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.165" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaae920e25fffe4019b75ff65e7660e72091e59dd204cb5849bbd6a3fd343d7" +checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index c8a2a701..d7a358fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.165", optional = true } +serde = { version = "1.0.166", optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.3", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 5b4aee4882cea6184174ce72fd93c4197f534542 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 10:28:33 +0200 Subject: [PATCH 157/286] Bump trybuild from 1.0.80 to 1.0.81 (#470) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.80 to 1.0.81. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.80...1.0.81) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 166a1acd..3a318317 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -458,9 +458,9 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.8" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "js-sys" @@ -883,9 +883,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.71" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" dependencies = [ "itoa", "ryu", @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a" +checksum = "04366e99ff743345622cd00af2af01d711dc2d1ef59250d7347698d21b546729" dependencies = [ "basic-toml", "glob", diff --git a/Cargo.toml b/Cargo.toml index d7a358fe..bdc27a3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.2.0" -trybuild = "1.0.80" +trybuild = "1.0.81" paste = "1" [[bench]] From 2ed83ff11752e4498ed611fa61b3461dcecb4031 Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Fri, 7 Jul 2023 16:49:01 +0300 Subject: [PATCH 158/286] code cleanup (#474) --- benches/benches.rs | 6 ++-- derive/src/encode.rs | 2 +- derive/src/lib.rs | 4 +-- src/codec.rs | 22 ++++++------ src/compact.rs | 80 ++++++++++++++++++++++---------------------- src/decode_all.rs | 2 +- src/keyedvec.rs | 2 +- tests/mod.rs | 10 +++--- 8 files changed, 64 insertions(+), 64 deletions(-) diff --git a/benches/benches.rs b/benches/benches.rs index f52e9fbd..902be9e0 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -127,7 +127,7 @@ fn encode_decode_vec + Codec>(c: &mut Criterion) where T::Error: }); } - core::mem::drop(g); + drop(g); let mut g = c.benchmark_group("vec_decode"); for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { g.bench_with_input(&format!("{}/{}", type_name::(), vec_size), &vec_size, |b, &vec_size| { @@ -146,7 +146,7 @@ fn encode_decode_vec + Codec>(c: &mut Criterion) where T::Error: }); } - core::mem::drop(g); + drop(g); let mut g = c.benchmark_group("vec_decode_no_limit"); for vec_size in [16384, 131072] { g.bench_with_input(&format!("vec_decode_no_limit_{}/{}", type_name::(), vec_size), &vec_size, |b, &vec_size| { @@ -191,7 +191,7 @@ fn encode_decode_complex_type(c: &mut Criterion) { }); } - core::mem::drop(g); + drop(g); let mut g = c.benchmark_group("vec_decode_complex_type"); for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { let complex_types = complex_types.clone(); diff --git a/derive/src/encode.rs b/derive/src/encode.rs index 06339c40..c4f0012c 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -26,7 +26,7 @@ use crate::utils; type FieldsList = Punctuated; -// Encode a signle field by using using_encoded, must not have skip attribute +// Encode a single field by using using_encoded, must not have skip attribute fn encode_single_field( field: &Field, field_name: TokenStream, diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 2dba4610..3c868e27 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -92,9 +92,9 @@ fn wrap_with_dummy_const( /// The variable is encoded with one byte for the variant and then the variant struct encoding. /// The variant number is: /// * if variant has attribute: `#[codec(index = "$n")]` then n -/// * else if variant has discrimant (like 3 in `enum T { A = 3 }`) then the discrimant. +/// * else if variant has discriminant (like 3 in `enum T { A = 3 }`) then the discriminant. /// * else its position in the variant set, excluding skipped variants, but including variant with -/// discrimant or attribute. Warning this position does collision with discrimant or attribute +/// discriminant or attribute. Warning this position does collision with discriminant or attribute /// index. /// /// variant attributes: diff --git a/src/codec.rs b/src/codec.rs index 386f4fc9..a86bf3ad 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -890,15 +890,15 @@ impl Encode for [T; N] { } const fn calculate_array_bytesize() -> usize { - struct AssertNotOverflow(core::marker::PhantomData); + struct AssertNotOverflow(PhantomData); impl AssertNotOverflow { - const OK: () = assert!(core::mem::size_of::().checked_mul(N).is_some(), "array size overflow"); + const OK: () = assert!(mem::size_of::().checked_mul(N).is_some(), "array size overflow"); } #[allow(clippy::let_unit_value)] let () = AssertNotOverflow::::OK; - core::mem::size_of::() * N + mem::size_of::() * N } impl Decode for [T; N] { @@ -978,7 +978,7 @@ impl Decode for [T; N] { impl<'a, T, const N: usize> Drop for State<'a, T, N> { fn drop(&mut self) { - if !core::mem::needs_drop::() { + if !mem::needs_drop::() { // If the types don't actually need to be dropped then don't even // try to run the loop below. // @@ -1011,7 +1011,7 @@ impl Decode for [T; N] { } // We've successfully read everything, so disarm the `Drop` impl. - core::mem::forget(state); + mem::forget(state); // SAFETY: We've initialized the whole slice so calling this is safe. unsafe { @@ -1084,7 +1084,7 @@ impl Decode for String { /// Writes the compact encoding of `len` do `dest`. pub(crate) fn compact_encode_len_to(dest: &mut W, len: usize) -> Result<(), Error> { - if len > u32::max_value() as usize { + if len > u32::MAX as usize { return Err("Attempted to serialize a collection with too many elements.".into()); } @@ -1094,7 +1094,7 @@ pub(crate) fn compact_encode_len_to(dest: &mut W, len: usize impl Encode for [T] { fn size_hint(&self) -> usize { - mem::size_of::() + core::mem::size_of_val(self) + mem::size_of::() + mem::size_of_val(self) } fn encode_to(&self, dest: &mut W) { @@ -1853,8 +1853,8 @@ mod tests { #[test] fn shared_references_implement_encode() { - std::sync::Arc::new(10u32).encode(); - std::rc::Rc::new(10u32).encode(); + Arc::new(10u32).encode(); + Rc::new(10u32).encode(); } #[test] @@ -1973,7 +1973,7 @@ mod tests { #[test] fn u64_max() { - let num_secs = u64::max_value(); + let num_secs = u64::MAX; let num_nanos = 0; let duration = Duration::new(num_secs, num_nanos); let expected = (num_secs, num_nanos).encode(); @@ -1984,7 +1984,7 @@ mod tests { #[test] fn decoding_does_not_overflow() { - let num_secs = u64::max_value(); + let num_secs = u64::MAX; let num_nanos = A_BILLION; // `num_nanos`' carry should make `num_secs` overflow if we were to call `Duration::new()`. diff --git a/src/compact.rs b/src/compact.rs index a23d09db..2432af97 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -487,7 +487,7 @@ impl Decode for Compact { }, 2 => { let x = u32::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; - if x > 0b0011_1111_1111_1111 && x <= u32::max_value() >> 2 { + if x > 0b0011_1111_1111_1111 && x <= u32::MAX >> 2 { x } else { return Err(U32_OUT_OF_RANGE.into()); @@ -497,7 +497,7 @@ impl Decode for Compact { if prefix >> 2 == 0 { // just 4 bytes. ok. let x = u32::decode(input)?; - if x > u32::max_value() >> 2 { + if x > u32::MAX >> 2 { x } else { return Err(U32_OUT_OF_RANGE.into()); @@ -527,7 +527,7 @@ impl Decode for Compact { }, 2 => { let x = u32::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; - if x > 0b0011_1111_1111_1111 && x <= u32::max_value() >> 2 { + if x > 0b0011_1111_1111_1111 && x <= u32::MAX >> 2 { u64::from(x) } else { return Err(U64_OUT_OF_RANGE.into()); @@ -536,7 +536,7 @@ impl Decode for Compact { 3 => match (prefix >> 2) + 4 { 4 => { let x = u32::decode(input)?; - if x > u32::max_value() >> 2 { + if x > u32::MAX >> 2 { u64::from(x) } else { return Err(U64_OUT_OF_RANGE.into()); @@ -544,7 +544,7 @@ impl Decode for Compact { }, 8 => { let x = u64::decode(input)?; - if x > u64::max_value() >> 8 { + if x > u64::MAX >> 8 { x } else { return Err(U64_OUT_OF_RANGE.into()); @@ -556,7 +556,7 @@ impl Decode for Compact { for i in 0..bytes_needed { res |= u64::from(input.read_byte()?) << (i * 8); } - if res > u64::max_value() >> ((8 - bytes_needed + 1) * 8) { + if res > u64::MAX >> ((8 - bytes_needed + 1) * 8) { res } else { return Err(U64_OUT_OF_RANGE.into()); @@ -583,7 +583,7 @@ impl Decode for Compact { }, 2 => { let x = u32::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; - if x > 0b0011_1111_1111_1111 && x <= u32::max_value() >> 2 { + if x > 0b0011_1111_1111_1111 && x <= u32::MAX >> 2 { u128::from(x) } else { return Err(U128_OUT_OF_RANGE.into()); @@ -592,7 +592,7 @@ impl Decode for Compact { 3 => match (prefix >> 2) + 4 { 4 => { let x = u32::decode(input)?; - if x > u32::max_value() >> 2 { + if x > u32::MAX >> 2 { u128::from(x) } else { return Err(U128_OUT_OF_RANGE.into()); @@ -600,7 +600,7 @@ impl Decode for Compact { }, 8 => { let x = u64::decode(input)?; - if x > u64::max_value() >> 8 { + if x > u64::MAX >> 8 { u128::from(x) } else { return Err(U128_OUT_OF_RANGE.into()); @@ -608,7 +608,7 @@ impl Decode for Compact { }, 16 => { let x = u128::decode(input)?; - if x > u128::max_value() >> 8 { + if x > u128::MAX >> 8 { x } else { return Err(U128_OUT_OF_RANGE.into()); @@ -620,7 +620,7 @@ impl Decode for Compact { for i in 0..bytes_needed { res |= u128::from(input.read_byte()?) << (i * 8); } - if res > u128::max_value() >> ((16 - bytes_needed + 1) * 8) { + if res > u128::MAX >> ((16 - bytes_needed + 1) * 8) { res } else { return Err(U128_OUT_OF_RANGE.into()); @@ -644,7 +644,7 @@ mod tests { (1073741824, 5), ((1 << 32) - 1, 5), (1 << 32, 6), (1 << 40, 7), (1 << 48, 8), ((1 << 56) - 1, 8), (1 << 56, 9), ((1 << 64) - 1, 9), (1 << 64, 10), (1 << 72, 11), (1 << 80, 12), (1 << 88, 13), (1 << 96, 14), (1 << 104, 15), - (1 << 112, 16), ((1 << 120) - 1, 16), (1 << 120, 17), (u128::max_value(), 17) + (1 << 112, 16), ((1 << 120) - 1, 16), (1 << 120, 17), (u128::MAX, 17) ]; for &(n, l) in &tests { let encoded = Compact(n as u128).encode(); @@ -660,7 +660,7 @@ mod tests { (0u64, 1usize), (63, 1), (64, 2), (16383, 2), (16384, 4), (1073741823, 4), (1073741824, 5), ((1 << 32) - 1, 5), - (1 << 32, 6), (1 << 40, 7), (1 << 48, 8), ((1 << 56) - 1, 8), (1 << 56, 9), (u64::max_value(), 9) + (1 << 32, 6), (1 << 40, 7), (1 << 48, 8), ((1 << 56) - 1, 8), (1 << 56, 9), (u64::MAX, 9) ]; for &(n, l) in &tests { let encoded = Compact(n as u64).encode(); @@ -672,7 +672,7 @@ mod tests { #[test] fn compact_32_encoding_works() { - let tests = [(0u32, 1usize), (63, 1), (64, 2), (16383, 2), (16384, 4), (1073741823, 4), (1073741824, 5), (u32::max_value(), 5)]; + let tests = [(0u32, 1usize), (63, 1), (64, 2), (16383, 2), (16384, 4), (1073741823, 4), (1073741824, 5), (u32::MAX, 5)]; for &(n, l) in &tests { let encoded = Compact(n as u32).encode(); assert_eq!(encoded.len(), l); @@ -725,7 +725,7 @@ mod tests { (1 << 48, "0f 00 00 00 00 00 00 01"), ((1 << 56) - 1, "0f ff ff ff ff ff ff ff"), (1 << 56, "13 00 00 00 00 00 00 00 01"), - (u64::max_value(), "13 ff ff ff ff ff ff ff ff") + (u64::MAX, "13 ff ff ff ff ff ff ff ff") ]; for &(n, s) in &tests { // Verify u64 encoding @@ -734,19 +734,19 @@ mod tests { assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); // Verify encodings for lower-size uints are compatible with u64 encoding - if n <= u32::max_value() as u64 { + if n <= u32::MAX as u64 { assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u32); let encoded = Compact(n as u32).encode(); assert_eq!(hexify(&encoded), s); assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u64); } - if n <= u16::max_value() as u64 { + if n <= u16::MAX as u64 { assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u16); let encoded = Compact(n as u16).encode(); assert_eq!(hexify(&encoded), s); assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u64); } - if n <= u8::max_value() as u64 { + if n <= u8::MAX as u64 { assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u8); let encoded = Compact(n as u8).encode(); assert_eq!(hexify(&encoded), s); @@ -800,17 +800,17 @@ mod tests { #[test] fn compact_using_encoded_arrayvec_size() { - Compact(std::u8::MAX).using_encoded(|_| {}); - Compact(std::u16::MAX).using_encoded(|_| {}); - Compact(std::u32::MAX).using_encoded(|_| {}); - Compact(std::u64::MAX).using_encoded(|_| {}); - Compact(std::u128::MAX).using_encoded(|_| {}); + Compact(u8::MAX).using_encoded(|_| {}); + Compact(u16::MAX).using_encoded(|_| {}); + Compact(u32::MAX).using_encoded(|_| {}); + Compact(u64::MAX).using_encoded(|_| {}); + Compact(u128::MAX).using_encoded(|_| {}); - CompactRef(&std::u8::MAX).using_encoded(|_| {}); - CompactRef(&std::u16::MAX).using_encoded(|_| {}); - CompactRef(&std::u32::MAX).using_encoded(|_| {}); - CompactRef(&std::u64::MAX).using_encoded(|_| {}); - CompactRef(&std::u128::MAX).using_encoded(|_| {}); + CompactRef(&u8::MAX).using_encoded(|_| {}); + CompactRef(&u16::MAX).using_encoded(|_| {}); + CompactRef(&u32::MAX).using_encoded(|_| {}); + CompactRef(&u64::MAX).using_encoded(|_| {}); + CompactRef(&u128::MAX).using_encoded(|_| {}); } #[test] @@ -833,7 +833,7 @@ mod tests { )* }; ( $m:expr, $ty:ty, $typ1:ty, $ty2:ty, $ty2_err:expr) => { - let enc = ((<$ty>::max_value() >> 2) as $typ1 << 2) | $m; + let enc = ((<$ty>::MAX >> 2) as $typ1 << 2) | $m; assert_eq!(Compact::<$ty2>::decode(&mut &enc.to_le_bytes()[..]), Err($ty2_err.into())); }; @@ -859,7 +859,7 @@ mod tests { let mut dest = Vec::new(); dest.push(0b11 + (($s - 4) << 2) as u8); for _ in 0..($s - 1) { - dest.push(u8::max_value()); + dest.push(u8::MAX); } dest.push(0); assert_eq!(Compact::<$ty2>::decode(&mut &dest[..]), @@ -870,12 +870,12 @@ mod tests { #[test] fn compact_u64_test() { for a in [ - u64::max_value(), - u64::max_value() - 1, - u64::max_value() << 8, - (u64::max_value() << 8) - 1, - u64::max_value() << 16, - (u64::max_value() << 16) - 1, + u64::MAX, + u64::MAX - 1, + u64::MAX << 8, + (u64::MAX << 8) - 1, + u64::MAX << 16, + (u64::MAX << 16) - 1, ].iter() { let e = Compact::::encode(&Compact(*a)); let d = Compact::::decode(&mut &e[..]).unwrap().0; @@ -886,10 +886,10 @@ mod tests { #[test] fn compact_u128_test() { for a in [ - u64::max_value() as u128, - (u64::max_value() - 10) as u128, - u128::max_value(), - u128::max_value() - 10, + u64::MAX as u128, + (u64::MAX - 10) as u128, + u128::MAX, + u128::MAX - 10, ].iter() { let e = Compact::::encode(&Compact(*a)); let d = Compact::::decode(&mut &e[..]).unwrap().0; diff --git a/src/decode_all.rs b/src/decode_all.rs index fb29c66c..448afbd5 100644 --- a/src/decode_all.rs +++ b/src/decode_all.rs @@ -17,7 +17,7 @@ use crate::{Decode, Error}; /// The error message returned when `decode_all` fails. pub(crate) const DECODE_ALL_ERR_MSG: &str = "Input buffer has still data left after decoding!"; -/// Extension trait to [`Decode`] that ensures that the given input data is consumed completly while +/// Extension trait to [`Decode`] that ensures that the given input data is consumed completely while /// decoding. pub trait DecodeAll: Sized { /// Decode `Self` and consume all of the given input data. diff --git a/src/keyedvec.rs b/src/keyedvec.rs index 74e06865..20e76e71 100644 --- a/src/keyedvec.rs +++ b/src/keyedvec.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Serialiser and prepender. +//! Serializer and prepender. use core::iter::Extend; diff --git a/tests/mod.rs b/tests/mod.rs index e422c0a8..93d2595b 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -35,7 +35,7 @@ struct Struct { struct StructWithPhantom { pub a: u32, pub b: u64, - _c: ::std::marker::PhantomData, + _c: std::marker::PhantomData, } type TestType = Struct>; @@ -240,7 +240,7 @@ const U64_TEST_COMPACT_VALUES: &[(u64, usize)] = &[ (1 << 48, 8), (1 << 56 - 1, 8), (1 << 56, 9), - (u64::max_value(), 9), + (u64::MAX, 9), ]; const U64_TEST_COMPACT_VALUES_FOR_ENUM: &[(u64, usize)] = &[ @@ -257,7 +257,7 @@ const U64_TEST_COMPACT_VALUES_FOR_ENUM: &[(u64, usize)] = &[ (1 << 48, 9), (1 << 56 - 1, 9), (1 << 56, 10), - (u64::max_value(), 10), + (u64::MAX, 10), ]; #[test] @@ -527,7 +527,7 @@ fn recursive_type() { #[test] fn crafted_input_for_vec_u8() { assert_eq!( - Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]) + Vec::::decode(&mut &Compact(u32::MAX).encode()[..]) .err() .unwrap() .to_string(), @@ -545,7 +545,7 @@ fn crafted_input_for_vec_t() { }; assert_eq!( - Vec::::decode(&mut &Compact(u32::max_value()).encode()[..]) + Vec::::decode(&mut &Compact(u32::MAX).encode()[..]) .err() .unwrap() .to_string(), From cbd1fa854f991197bdf1f6694f2c3299b0afba4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 19:18:38 +0200 Subject: [PATCH 159/286] Bump serde from 1.0.166 to 1.0.167 (#476) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.166 to 1.0.167. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.166...v1.0.167) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a318317..bd87ab3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,18 +863,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.166" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" +checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.166" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" +checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index bdc27a3b..f95acf93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.166", optional = true } +serde = { version = "1.0.167", optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.3", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 10dea5ee55952f1e13d2acfbc57cb39bc750274f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 22:06:10 +0200 Subject: [PATCH 160/286] Bump serde from 1.0.167 to 1.0.171 (#478) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.167 to 1.0.171. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.167...v1.0.171) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 14 +++++++------- Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd87ab3e..155b5270 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,22 +863,22 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.167" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.167" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -905,9 +905,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index f95acf93..abd21749 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.167", optional = true } +serde = { version = "1.0.171", optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.3", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 00d7339630fd30506e503e7972704d94d1bcf2ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 22:06:20 +0200 Subject: [PATCH 161/286] Bump proc-macro2 from 1.0.63 to 1.0.64 (#477) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.63 to 1.0.64. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.63...1.0.64) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 155b5270..777a1aba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,9 +650,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index f266ef5a..84278fe2 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.29" -proc-macro2 = "1.0.60" +proc-macro2 = "1.0.64" proc-macro-crate = "1.1.3" [dev-dependencies] From 04558a37d1da8b8395fd21d3c524c10b870f5c7e Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Fri, 14 Jul 2023 12:43:37 +0300 Subject: [PATCH 162/286] feat(derive): implement `size_hint()` method for `struct` and `enum` (#472) --- derive/src/encode.rs | 244 ++++++++++++++++++++++++++++++++----------- tests/size_hint.rs | 78 ++++++++++++++ 2 files changed, 261 insertions(+), 61 deletions(-) create mode 100644 tests/size_hint.rs diff --git a/derive/src/encode.rs b/derive/src/encode.rs index c4f0012c..eaeee462 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -75,6 +75,10 @@ fn encode_single_field( let i_self = quote! { self }; quote_spanned! { field.span() => + fn size_hint(&#i_self) -> usize { + #crate_path::Encode::size_hint(&#final_field_variable) + } + fn encode_to<__CodecOutputEdqy: #crate_path::Output + ?::core::marker::Sized>( &#i_self, __codec_dest_edqy: &mut __CodecOutputEdqy @@ -92,15 +96,25 @@ fn encode_single_field( } } -fn encode_fields( - dest: &TokenStream, +enum FieldAttribute<'a> { + None(&'a Field), + Compact(&'a Field), + EncodedAs { field: &'a Field, encoded_as: &'a TokenStream }, + Skip(&'a Field), +} + +fn iterate_over_fields( fields: &FieldsList, field_name: F, - crate_path: &syn::Path, -) -> TokenStream where + field_handler: H, + field_joiner: J, +) -> TokenStream +where F: Fn(usize, &Option) -> TokenStream, + H: Fn(TokenStream, FieldAttribute) -> TokenStream, + J: Fn(&mut dyn Iterator) -> TokenStream, { - let recurse = fields.iter().enumerate().map(|(i, f)| { + let mut recurse = fields.iter().enumerate().map(|(i, f)| { let field = field_name(i, &f.ident); let encoded_as = utils::get_encoded_as_type(f); let compact = utils::is_compact(f); @@ -113,9 +127,36 @@ fn encode_fields( ).to_compile_error(); } - // Based on the seen attribute, we generate the code that encodes the field. - // We call `push` from the `Output` trait on `dest`. + // Based on the seen attribute, we call a handler that generates code for a specific + // attribute type. if compact { + field_handler(field, FieldAttribute::Compact(f)) + } else if let Some(ref encoded_as) = encoded_as { + field_handler(field, FieldAttribute::EncodedAs { field: f, encoded_as }) + } else if skip { + field_handler(field, FieldAttribute::Skip(f)) + } else { + field_handler(field, FieldAttribute::None(f)) + } + }); + + field_joiner(&mut recurse) +} + +fn encode_fields( + dest: &TokenStream, + fields: &FieldsList, + field_name: F, + crate_path: &syn::Path, +) -> TokenStream +where + F: Fn(usize, &Option) -> TokenStream, +{ + iterate_over_fields(fields, field_name, |field, field_attribute| match field_attribute { + FieldAttribute::None(f) => quote_spanned! { f.span() => + #crate_path::Encode::encode_to(#field, #dest); + }, + FieldAttribute::Compact(f) => { let field_type = &f.ty; quote_spanned! { f.span() => { @@ -128,7 +169,8 @@ fn encode_fields( ); } } - } else if let Some(encoded_as) = encoded_as { + }, + FieldAttribute::EncodedAs { field: f, encoded_as } => { let field_type = &f.ty; quote_spanned! { f.span() => { @@ -141,20 +183,49 @@ fn encode_fields( ); } } - } else if skip { - quote! { - let _ = #field; + }, + FieldAttribute::Skip(_) => quote! { + let _ = #field; + }, + }, |recurse| quote! { + #( #recurse )* + }) +} + +fn size_hint_fields(fields: &FieldsList, field_name: F, crate_path: &syn::Path) -> TokenStream +where + F: Fn(usize, &Option) -> TokenStream, +{ + iterate_over_fields(fields, field_name, |field, field_attribute| match field_attribute { + FieldAttribute::None(f) => quote_spanned! { f.span() => + .saturating_add(#crate_path::Encode::size_hint(#field)) + }, + FieldAttribute::Compact(f) => { + let field_type = &f.ty; + quote_spanned! { + f.span() => .saturating_add(#crate_path::Encode::size_hint( + &< + <#field_type as #crate_path::HasCompact>::Type as + #crate_path::EncodeAsRef<'_, #field_type> + >::RefType::from(#field), + )) } - } else { - quote_spanned! { f.span() => - #crate_path::Encode::encode_to(#field, #dest); + }, + FieldAttribute::EncodedAs { field: f, encoded_as } => { + let field_type = &f.ty; + quote_spanned! { + f.span() => .saturating_add(#crate_path::Encode::size_hint( + &< + #encoded_as as + #crate_path::EncodeAsRef<'_, #field_type> + >::RefType::from(#field), + )) } - } - }); - - quote! { - #( #recurse )* - } + }, + FieldAttribute::Skip(_) => quote!(), + }, |recurse| quote! { + 0_usize #( #recurse )* + }) } fn try_impl_encode_single_field_optimisation(data: &Data, crate_path: &syn::Path) -> Option { @@ -190,25 +261,31 @@ fn try_impl_encode_single_field_optimisation(data: &Data, crate_path: &syn::Path fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenStream { let self_ = quote!(self); let dest = "e!(__codec_dest_edqy); - let encoding = match *data { + let [hinting, encoding] = match *data { Data::Struct(ref data) => { match data.fields { - Fields::Named(ref fields) => encode_fields( - dest, - &fields.named, - |_, name| quote!(&#self_.#name), - crate_path, - ), - Fields::Unnamed(ref fields) => encode_fields( - dest, - &fields.unnamed, - |i, _| { + Fields::Named(ref fields) => { + let fields = &fields.named; + let field_name = |_, name: &Option| quote!(&#self_.#name); + + let hinting = size_hint_fields(fields, field_name, crate_path); + let encoding = encode_fields(dest, fields, field_name, crate_path); + + [hinting, encoding] + }, + Fields::Unnamed(ref fields) => { + let fields = &fields.unnamed; + let field_name = |i, _: &Option| { let i = syn::Index::from(i); quote!(&#self_.#i) - }, - crate_path, - ), - Fields::Unit => quote!(), + }; + + let hinting = size_hint_fields(fields, field_name, crate_path); + let encoding = encode_fields(dest, fields, field_name, crate_path); + + [hinting, encoding] + }, + Fields::Unit => [quote! { 0_usize }, quote!()], } }, Data::Enum(ref data) => { @@ -232,76 +309,121 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenS match f.fields { Fields::Named(ref fields) => { + let fields = &fields.named; let field_name = |_, ident: &Option| quote!(#ident); - let names = fields.named + + let names = fields .iter() .enumerate() .map(|(i, f)| field_name(i, &f.ident)); - let encode_fields = encode_fields( - dest, - &fields.named, - |a, b| field_name(a, b), - crate_path, - ); + let field_name = |a, b: &Option| field_name(a, b); + + let size_hint_fields = size_hint_fields(fields, field_name, crate_path); + let encode_fields = encode_fields(dest, fields, field_name, crate_path); + + let hinting_names = names.clone(); + let hinting = quote_spanned! { f.span() => + #type_name :: #name { #( ref #hinting_names, )* } => { + #size_hint_fields + } + }; - quote_spanned! { f.span() => - #type_name :: #name { #( ref #names, )* } => { + let encoding_names = names.clone(); + let encoding = quote_spanned! { f.span() => + #type_name :: #name { #( ref #encoding_names, )* } => { #dest.push_byte(#index as ::core::primitive::u8); #encode_fields } - } + }; + + [hinting, encoding] }, Fields::Unnamed(ref fields) => { + let fields = &fields.unnamed; let field_name = |i, _: &Option| { let data = stringify(i as u8); let ident = from_utf8(&data).expect("We never go beyond ASCII"); let ident = Ident::new(ident, Span::call_site()); quote!(#ident) }; - let names = fields.unnamed + + let names = fields .iter() .enumerate() .map(|(i, f)| field_name(i, &f.ident)); - let encode_fields = encode_fields( - dest, - &fields.unnamed, - |a, b| field_name(a, b), - crate_path, - ); + let field_name = |a, b: &Option| field_name(a, b); - quote_spanned! { f.span() => - #type_name :: #name ( #( ref #names, )* ) => { + let size_hint_fields = size_hint_fields(fields, field_name, crate_path); + let encode_fields = encode_fields(dest, fields, field_name, crate_path); + + let hinting_names = names.clone(); + let hinting = quote_spanned! { f.span() => + #type_name :: #name ( #( ref #hinting_names, )* ) => { + #size_hint_fields + } + }; + + let encoding_names = names.clone(); + let encoding = quote_spanned! { f.span() => + #type_name :: #name ( #( ref #encoding_names, )* ) => { #dest.push_byte(#index as ::core::primitive::u8); #encode_fields } - } + }; + + [hinting, encoding] }, Fields::Unit => { - quote_spanned! { f.span() => + let hinting = quote_spanned! { f.span() => + #type_name :: #name => { + 0_usize + } + }; + + let encoding = quote_spanned! { f.span() => #type_name :: #name => { #[allow(clippy::unnecessary_cast)] #dest.push_byte(#index as ::core::primitive::u8); } - } + }; + + [hinting, encoding] }, } }); - quote! { + let recurse_hinting = recurse.clone().map(|[hinting, _]| hinting); + let recurse_encoding = recurse.clone().map(|[_, encoding]| encoding); + + let hinting = quote! { + // The variant index uses 1 byte. + 1_usize + match *#self_ { + #( #recurse_hinting )*, + _ => 0_usize, + } + }; + + let encoding = quote! { match *#self_ { - #( #recurse )*, + #( #recurse_encoding )*, _ => (), } - } + }; + + [hinting, encoding] }, - Data::Union(ref data) => Error::new( + Data::Union(ref data) => return Error::new( data.union_token.span(), "Union types are not supported." ).to_compile_error(), }; quote! { + fn size_hint(&#self_) -> usize { + #hinting + } + fn encode_to<__CodecOutputEdqy: #crate_path::Output + ?::core::marker::Sized>( &#self_, #dest: &mut __CodecOutputEdqy diff --git a/tests/size_hint.rs b/tests/size_hint.rs new file mode 100644 index 00000000..5191c6e1 --- /dev/null +++ b/tests/size_hint.rs @@ -0,0 +1,78 @@ +use parity_scale_codec::Encode; +use parity_scale_codec_derive::Encode as DeriveEncode; + +#[test] +fn size_hint_for_struct() { + #[derive(DeriveEncode)] + struct Struct { + pub a: A, + pub b: B, + #[codec(skip)] + pub c: C, + } + + let v = Struct::, u32> { a: String::from("foo"), b: vec![1, 2, 3], c: 0 }; + assert_eq!(v.size_hint(), 23); +} + +#[test] +fn size_hint_for_tuple_struct() { + #[derive(DeriveEncode)] + struct Tuple(String, Vec, #[codec(skip)] u32); + + let v = Tuple(String::from("foo"), vec![1, 2, 3], 0); + assert_eq!(v.size_hint(), 23); +} + +#[test] +fn size_hint_for_unit_struct() { + #[derive(DeriveEncode)] + struct Unit; + + let v = Unit; + assert_eq!(v.size_hint(), 0); +} + +#[test] +fn size_hint_for_simple_enum() { + #[derive(DeriveEncode)] + enum EnumType { + #[codec(index = 15)] + A, + B(u32, u64), + C { + a: u32, + b: u64, + }, + } + + let v = EnumType::A; + assert_eq!(v.size_hint(), 1); + + let v = EnumType::B(1, 2); + assert_eq!(v.size_hint(), 13); + + let v = EnumType::C { a: 0, b: 0 }; + assert_eq!(v.size_hint(), 13); +} + +#[test] +fn size_hint_for_enum_with_discriminant() { + #[derive(DeriveEncode)] + enum EnumWithDiscriminant { + A = 1, + B = 15, + C = 255, + } + + let discriminant = core::mem::size_of::(); + + let v = EnumWithDiscriminant::A; + assert_eq!(v.size_hint(), discriminant); + + let v = EnumWithDiscriminant::B; + assert_eq!(v.size_hint(), discriminant); + + let v = EnumWithDiscriminant::C; + assert_eq!(v.size_hint(), discriminant); +} From d43c30f40954936a115f5a93afb136d6b2ed3a5d Mon Sep 17 00:00:00 2001 From: Evgeny Snitko Date: Mon, 17 Jul 2023 18:34:47 +0300 Subject: [PATCH 163/286] ci-unified:bullseye-1.70.0-2023-05-23 image for ci (#473) --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ea0b10ce..9c29dca5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,7 +10,7 @@ variables: GIT_STRATEGY: fetch GIT_DEPTH: "100" CARGO_INCREMENTAL: 0 - CI_IMAGE: "paritytech/parity-scale-codec:production" + CI_IMAGE: "paritytech/ci-unified:bullseye-1.70.0-2023-05-23" default: cache: {} From 9e42a5e94319cce25052a0b8a580cbf1d7e7ee0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 18:07:26 +0200 Subject: [PATCH 164/286] Bump quote from 1.0.29 to 1.0.30 (#483) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.29 to 1.0.30. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.29...1.0.30) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 777a1aba..7fad04b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -696,9 +696,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5907a1b7c277254a8b15170f6e7c97cfa60ee7872a3217663bb81151e48184bb" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 84278fe2..11a95ef6 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.29" +quote = "1.0.30" proc-macro2 = "1.0.64" proc-macro-crate = "1.1.3" From b6ad0c14dd70eb0cb6b7e5048de26691abd0d3f1 Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:47:29 +0300 Subject: [PATCH 165/286] chore(versioning): bump version to 3.6.4 and fill the changelog (#481) * chore(versioning): bump version to 3.6.4 and fill the changelog * also bump parity-scale-codec-derive to 3.6.4 * also bump version in `[dependencies]` --- CHANGELOG.md | 7 +++++++ Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44d5d49a..6a09d55d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this crate are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.6.4] - 2023-07-14 + +### Added + +- Now `#[derive(Encode)]` implements the `size_hint()` method for structures and enumerations. + This improves the performance of the `encode()` method by pre-allocating memory. + ## [3.6.3] - 2023-07-03 ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 7fad04b2..afb99bcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parity-scale-codec" -version = "3.6.3" +version = "3.6.4" dependencies = [ "arbitrary", "arrayvec", @@ -589,7 +589,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.3" +version = "3.6.4" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index abd21749..7f87c2e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.6.3" +version = "3.6.4" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.171", optional = true } -parity-scale-codec-derive = { path = "derive", version = ">= 3.6.3", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = ">= 3.6.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 11a95ef6..3aa19fdc 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.6.3" +version = "3.6.4" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" From 0b1a104c6384bdc5ceaf88b3070a89b2b6d3feb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 15:47:59 +0900 Subject: [PATCH 166/286] Bump paste from 1.0.13 to 1.0.14 (#482) Bumps [paste](https://github.com/dtolnay/paste) from 1.0.13 to 1.0.14. - [Release notes](https://github.com/dtolnay/paste/releases) - [Commits](https://github.com/dtolnay/paste/compare/1.0.13...1.0.14) --- updated-dependencies: - dependency-name: paste dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index afb99bcd..bd2551a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -600,9 +600,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "plotters" From a9bc815f26c733f639792423c8bb9ea69d273c2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 15:48:29 +0900 Subject: [PATCH 167/286] Bump proc-macro2 from 1.0.64 to 1.0.66 (#484) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.64 to 1.0.66. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.64...1.0.66) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd2551a6..971ac4f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,9 +650,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 3aa19fdc..0d5c9ffa 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.30" -proc-macro2 = "1.0.64" +proc-macro2 = "1.0.66" proc-macro-crate = "1.1.3" [dev-dependencies] From 45dd8a3e7c2f4eef0eff87512e609d96ab763184 Mon Sep 17 00:00:00 2001 From: Evgeny Snitko Date: Tue, 18 Jul 2023 17:13:54 +0300 Subject: [PATCH 168/286] Move CI_IMAGE to external snippet via !reference --- .gitlab-ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9c29dca5..5c2ff28b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,12 @@ # .gitlab-ci.yml # +include: + - project: parity/infrastructure/ci_cd/shared + ref: main + file: /common/ci-unified.yml + + stages: - check - test @@ -10,7 +16,7 @@ variables: GIT_STRATEGY: fetch GIT_DEPTH: "100" CARGO_INCREMENTAL: 0 - CI_IMAGE: "paritytech/ci-unified:bullseye-1.70.0-2023-05-23" + CI_IMAGE: !reference [.ci-unified, variables, CI_IMAGE] default: cache: {} From 4eda0809ab46ec230f8a56215fe5b936eb3b97f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 16:18:53 +0200 Subject: [PATCH 169/286] Bump quote from 1.0.30 to 1.0.31 (#486) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.30 to 1.0.31. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.30...1.0.31) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 971ac4f9..115dec01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -696,9 +696,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5907a1b7c277254a8b15170f6e7c97cfa60ee7872a3217663bb81151e48184bb" +checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 0d5c9ffa..a41f3ff1 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.30" +quote = "1.0.31" proc-macro2 = "1.0.66" proc-macro-crate = "1.1.3" From 779772d65dbb2b0bc9e7343bc1ab1feb6fd5d33e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jul 2023 09:23:54 +0200 Subject: [PATCH 170/286] Bump serde from 1.0.171 to 1.0.173 (#487) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.171 to 1.0.173. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.171...v1.0.173) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 115dec01..c3257d2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,18 +863,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.171" +version = "1.0.173" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "e91f70896d6720bc714a4a57d22fc91f1db634680e65c8efe13323f1fa38d53f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.173" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "a6250dde8342e0232232be9ca3db7aa40aceb5a3e5dd9bddbc00d99a007cde49" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 7f87c2e7..74130f21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.171", optional = true } +serde = { version = "1.0.173", optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 12e99c0bb018848de29761800a8b8244e4b579da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jul 2023 22:55:56 +0200 Subject: [PATCH 171/286] Bump serde from 1.0.173 to 1.0.174 (#489) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.173 to 1.0.174. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.173...v1.0.174) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3257d2b..cc38b8d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,18 +863,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.173" +version = "1.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91f70896d6720bc714a4a57d22fc91f1db634680e65c8efe13323f1fa38d53f" +checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.173" +version = "1.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6250dde8342e0232232be9ca3db7aa40aceb5a3e5dd9bddbc00d99a007cde49" +checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 74130f21..6c1cab06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.173", optional = true } +serde = { version = "1.0.174", optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From e960eb9be27059ab0458cef68b80f9ed0db6e757 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jul 2023 22:56:24 +0200 Subject: [PATCH 172/286] Bump trybuild from 1.0.81 to 1.0.82 (#488) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.81 to 1.0.82. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.81...1.0.82) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc38b8d4..d0f79555 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04366e99ff743345622cd00af2af01d711dc2d1ef59250d7347698d21b546729" +checksum = "a84e0202ea606ba5ebee8507ab2bfbe89b98551ed9b8f0be198109275cff284b" dependencies = [ "basic-toml", "glob", diff --git a/Cargo.toml b/Cargo.toml index 6c1cab06..95dfd901 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.2.0" -trybuild = "1.0.81" +trybuild = "1.0.82" paste = "1" [[bench]] From 621993b5928369b6ba1a59bd82647d0615ef04b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Aug 2023 00:23:18 +0900 Subject: [PATCH 173/286] Bump serde from 1.0.174 to 1.0.183 (#497) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.174 to 1.0.183. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.174...v1.0.183) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 14 +++++++------- Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0f79555..2e2eaec8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,22 +863,22 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.174" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.174" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.28", ] [[package]] @@ -905,9 +905,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.25" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 95dfd901..903a152a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.174", optional = true } +serde = { version = "1.0.183", optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From ac88df0ce13d1c4957e5d797a29822b5eb3e6e1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:03:40 +0200 Subject: [PATCH 174/286] Bump quote from 1.0.31 to 1.0.32 (#491) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.31 to 1.0.32. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.31...1.0.32) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e2eaec8..34073643 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -696,9 +696,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index a41f3ff1..dcd69401 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.31" +quote = "1.0.32" proc-macro2 = "1.0.66" proc-macro-crate = "1.1.3" From 03f6c23076d0c516e0e716a130b56f261e53e9a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 21:38:59 +0200 Subject: [PATCH 175/286] Bump trybuild from 1.0.82 to 1.0.83 (#500) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.82 to 1.0.83. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.82...1.0.83) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34073643..7f6139db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84e0202ea606ba5ebee8507ab2bfbe89b98551ed9b8f0be198109275cff284b" +checksum = "6df60d81823ed9c520ee897489573da4b1d79ffbe006b8134f46de1a1aa03555" dependencies = [ "basic-toml", "glob", diff --git a/Cargo.toml b/Cargo.toml index 903a152a..d0dc5494 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.2.0" -trybuild = "1.0.82" +trybuild = "1.0.83" paste = "1" [[bench]] From 8d141aa0496453a1ec38f4434073ff9c37ece271 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 21:54:30 +0200 Subject: [PATCH 176/286] Bump quote from 1.0.32 to 1.0.33 (#501) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.32 to 1.0.33. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.32...1.0.33) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f6139db..7e71632c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -696,9 +696,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index dcd69401..5c92753d 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.32" +quote = "1.0.33" proc-macro2 = "1.0.66" proc-macro-crate = "1.1.3" From 4cbd87b6f78fd0e4c98ae869d204630beb434d10 Mon Sep 17 00:00:00 2001 From: Eran Rundstein Date: Thu, 17 Aug 2023 15:14:24 -0700 Subject: [PATCH 177/286] Prevent serde from bringing in `std` unless the `std` feature is enabled for this crate (#499) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Prevent serde from bringing in `std` unless the `std` feature is enabled for this crate. * simplify serde usage * Apply suggestions from code review Co-authored-by: Bastian Köcher --------- Co-authored-by: Bastian Köcher --- Cargo.toml | 4 ++-- src/compact.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d0dc5494..6fa36e3d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.183", optional = true } +serde = { version = "1.0.183", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } @@ -39,7 +39,7 @@ bench = false [features] default = ["std"] derive = ["parity-scale-codec-derive"] -std = ["serde", "bitvec?/std", "byte-slice-cast/std", "chain-error"] +std = ["serde/std", "bitvec?/std", "byte-slice-cast/std", "chain-error"] bit-vec = ["bitvec"] fuzz = ["std", "arbitrary"] diff --git a/src/compact.rs b/src/compact.rs index 2432af97..f19ea977 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -192,14 +192,14 @@ impl core::fmt::Debug for Compact where T: core::fmt::Debug { } } -#[cfg(feature = "std")] +#[cfg(feature = "serde")] impl serde::Serialize for Compact where T: serde::Serialize { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { T::serialize(&self.0, serializer) } } -#[cfg(feature = "std")] +#[cfg(feature = "serde")] impl<'de, T> serde::Deserialize<'de> for Compact where T: serde::Deserialize<'de> { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { T::deserialize(deserializer).map(Compact) From b93b5cc7345f679cacd842fca4d37b9c38e808b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 17:33:38 +0200 Subject: [PATCH 178/286] Bump serde from 1.0.183 to 1.0.185 (#502) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.183 to 1.0.185. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.183...v1.0.185) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e71632c..52189fcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,18 +863,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.183" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 6fa36e3d..7e5f59c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.183", default-features = false, optional = true } +serde = { version = "1.0.185", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 6a50b9f760e0a60873492271e0cc80ac620a68a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 12:13:19 +0200 Subject: [PATCH 179/286] Bump serde from 1.0.185 to 1.0.186 (#503) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.185 to 1.0.186. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.185...v1.0.186) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52189fcf..ffd32a61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,18 +863,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.185" +version = "1.0.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" +checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.185" +version = "1.0.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" +checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 7e5f59c3..bf90b20c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.185", default-features = false, optional = true } +serde = { version = "1.0.186", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 6f9d7f57b967334962ab8069b5f9068c9c23fa7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 18:24:36 +0200 Subject: [PATCH 180/286] Bump serde from 1.0.186 to 1.0.188 (#504) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.186 to 1.0.188. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.186...v1.0.188) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ffd32a61..719d948c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,18 +863,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.186" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.186" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index bf90b20c..61e846e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.186", default-features = false, optional = true } +serde = { version = "1.0.188", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.4", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 690b2d7121bded9ff2a0333b9147d8b181cbe6bd Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Tue, 29 Aug 2023 12:25:50 +0300 Subject: [PATCH 181/286] `EncodeLike` for `NonZero*` (#505) * `EncodeLike` for `NonZero*` * Add test for `impl EncodeLike for NonZeroU32` --- src/codec.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index a86bf3ad..08f4640b 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -254,8 +254,8 @@ pub trait Encode { /// /// # Note /// - /// This works by using a special [`Output`] that only tracks the size. So, there are no allocations inside the - /// output. However, this can not prevent allocations that some types are doing inside their own encoding. + /// This works by using a special [`Output`] that only tracks the size. So, there are no allocations inside the + /// output. However, this can not prevent allocations that some types are doing inside their own encoding. fn encoded_size(&self) -> usize { let mut size_tracker = SizeTracker { written: 0 }; self.encode_to(&mut size_tracker); @@ -773,6 +773,8 @@ macro_rules! impl_for_non_zero { } } + impl EncodeLike for $name {} + impl Decode for $name { fn decode(input: &mut I) -> Result { Self::new(Decode::decode(input)?) @@ -1904,6 +1906,7 @@ mod tests { fn t() {} t::<&[u8]>(); t::<&str>(); + t::(); } #[test] From 76c5c4a30bdd769429d62d2a7591204f20157467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 29 Aug 2023 15:41:46 +0200 Subject: [PATCH 182/286] Release 3.6.5 (#506) --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 719d948c..63695382 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parity-scale-codec" -version = "3.6.4" +version = "3.6.5" dependencies = [ "arbitrary", "arrayvec", @@ -589,7 +589,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.4" +version = "3.6.5" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index 61e846e7..e9a7842e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.6.4" +version = "3.6.5" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.188", default-features = false, optional = true } -parity-scale-codec-derive = { path = "derive", version = ">= 3.6.4", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = ">= 3.6.5", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 5c92753d..625e0e13 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.6.4" +version = "3.6.5" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" From 1516bb9758ae49acc68559ff375755eca71cc121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 4 Sep 2023 07:09:56 +0200 Subject: [PATCH 183/286] Use unique encoded generic parameter names in derive (#509) This ensures that we don't clash with the generic parameter names of the user. --- derive/src/encode.rs | 280 ++++++++++++++++++++++--------------------- 1 file changed, 142 insertions(+), 138 deletions(-) diff --git a/derive/src/encode.rs b/derive/src/encode.rs index eaeee462..e1ec680c 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -15,12 +15,7 @@ use std::str::from_utf8; use proc_macro2::{Ident, Span, TokenStream}; -use syn::{ - punctuated::Punctuated, - spanned::Spanned, - token::Comma, - Data, Field, Fields, Error, -}; +use syn::{punctuated::Punctuated, spanned::Spanned, token::Comma, Data, Error, Field, Fields}; use crate::utils; @@ -38,15 +33,17 @@ fn encode_single_field( if utils::should_skip(&field.attrs) { return Error::new( Span::call_site(), - "Internal error: cannot encode single field optimisation if skipped" - ).to_compile_error(); + "Internal error: cannot encode single field optimisation if skipped", + ) + .to_compile_error() } if encoded_as.is_some() && compact { return Error::new( Span::call_site(), - "`encoded_as` and `compact` can not be used at the same time!" - ).to_compile_error(); + "`encoded_as` and `compact` can not be used at the same time!", + ) + .to_compile_error() } let final_field_variable = if compact { @@ -90,7 +87,13 @@ fn encode_single_field( #crate_path::Encode::encode(&#final_field_variable) } - fn using_encoded R>(&#i_self, f: F) -> R { + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8] + ) -> __CodecOutputReturn + >(&#i_self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn + { #crate_path::Encode::using_encoded(&#final_field_variable, f) } } @@ -123,8 +126,9 @@ where if encoded_as.is_some() as u8 + compact as u8 + skip as u8 > 1 { return Error::new( f.span(), - "`encoded_as`, `compact` and `skip` can only be used one at a time!" - ).to_compile_error(); + "`encoded_as`, `compact` and `skip` can only be used one at a time!", + ) + .to_compile_error() } // Based on the seen attribute, we call a handler that generates code for a specific @@ -152,107 +156,114 @@ fn encode_fields( where F: Fn(usize, &Option) -> TokenStream, { - iterate_over_fields(fields, field_name, |field, field_attribute| match field_attribute { - FieldAttribute::None(f) => quote_spanned! { f.span() => - #crate_path::Encode::encode_to(#field, #dest); + iterate_over_fields( + fields, + field_name, + |field, field_attribute| match field_attribute { + FieldAttribute::None(f) => quote_spanned! { f.span() => + #crate_path::Encode::encode_to(#field, #dest); + }, + FieldAttribute::Compact(f) => { + let field_type = &f.ty; + quote_spanned! { + f.span() => { + #crate_path::Encode::encode_to( + &< + <#field_type as #crate_path::HasCompact>::Type as + #crate_path::EncodeAsRef<'_, #field_type> + >::RefType::from(#field), + #dest, + ); + } + } + }, + FieldAttribute::EncodedAs { field: f, encoded_as } => { + let field_type = &f.ty; + quote_spanned! { + f.span() => { + #crate_path::Encode::encode_to( + &< + #encoded_as as + #crate_path::EncodeAsRef<'_, #field_type> + >::RefType::from(#field), + #dest, + ); + } + } + }, + FieldAttribute::Skip(_) => quote! { + let _ = #field; + }, + }, + |recurse| { + quote! { + #( #recurse )* + } }, - FieldAttribute::Compact(f) => { - let field_type = &f.ty; - quote_spanned! { - f.span() => { - #crate_path::Encode::encode_to( + ) +} + +fn size_hint_fields(fields: &FieldsList, field_name: F, crate_path: &syn::Path) -> TokenStream +where + F: Fn(usize, &Option) -> TokenStream, +{ + iterate_over_fields( + fields, + field_name, + |field, field_attribute| match field_attribute { + FieldAttribute::None(f) => quote_spanned! { f.span() => + .saturating_add(#crate_path::Encode::size_hint(#field)) + }, + FieldAttribute::Compact(f) => { + let field_type = &f.ty; + quote_spanned! { + f.span() => .saturating_add(#crate_path::Encode::size_hint( &< <#field_type as #crate_path::HasCompact>::Type as #crate_path::EncodeAsRef<'_, #field_type> >::RefType::from(#field), - #dest, - ); + )) } - } - }, - FieldAttribute::EncodedAs { field: f, encoded_as } => { - let field_type = &f.ty; - quote_spanned! { - f.span() => { - #crate_path::Encode::encode_to( + }, + FieldAttribute::EncodedAs { field: f, encoded_as } => { + let field_type = &f.ty; + quote_spanned! { + f.span() => .saturating_add(#crate_path::Encode::size_hint( &< #encoded_as as #crate_path::EncodeAsRef<'_, #field_type> >::RefType::from(#field), - #dest, - ); + )) } - } + }, + FieldAttribute::Skip(_) => quote!(), }, - FieldAttribute::Skip(_) => quote! { - let _ = #field; - }, - }, |recurse| quote! { - #( #recurse )* - }) -} - -fn size_hint_fields(fields: &FieldsList, field_name: F, crate_path: &syn::Path) -> TokenStream -where - F: Fn(usize, &Option) -> TokenStream, -{ - iterate_over_fields(fields, field_name, |field, field_attribute| match field_attribute { - FieldAttribute::None(f) => quote_spanned! { f.span() => - .saturating_add(#crate_path::Encode::size_hint(#field)) - }, - FieldAttribute::Compact(f) => { - let field_type = &f.ty; - quote_spanned! { - f.span() => .saturating_add(#crate_path::Encode::size_hint( - &< - <#field_type as #crate_path::HasCompact>::Type as - #crate_path::EncodeAsRef<'_, #field_type> - >::RefType::from(#field), - )) + |recurse| { + quote! { + 0_usize #( #recurse )* } }, - FieldAttribute::EncodedAs { field: f, encoded_as } => { - let field_type = &f.ty; - quote_spanned! { - f.span() => .saturating_add(#crate_path::Encode::size_hint( - &< - #encoded_as as - #crate_path::EncodeAsRef<'_, #field_type> - >::RefType::from(#field), - )) - } - }, - FieldAttribute::Skip(_) => quote!(), - }, |recurse| quote! { - 0_usize #( #recurse )* - }) + ) } -fn try_impl_encode_single_field_optimisation(data: &Data, crate_path: &syn::Path) -> Option { +fn try_impl_encode_single_field_optimisation( + data: &Data, + crate_path: &syn::Path, +) -> Option { match *data { - Data::Struct(ref data) => { - match data.fields { - Fields::Named(ref fields) if utils::filter_skip_named(fields).count() == 1 => { - let field = utils::filter_skip_named(fields).next().unwrap(); - let name = &field.ident; - Some(encode_single_field( - field, - quote!(&self.#name), - crate_path, - )) - }, - Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => { - let (id, field) = utils::filter_skip_unnamed(fields).next().unwrap(); - let id = syn::Index::from(id); - - Some(encode_single_field( - field, - quote!(&self.#id), - crate_path, - )) - }, - _ => None, - } + Data::Struct(ref data) => match data.fields { + Fields::Named(ref fields) if utils::filter_skip_named(fields).count() == 1 => { + let field = utils::filter_skip_named(fields).next().unwrap(); + let name = &field.ident; + Some(encode_single_field(field, quote!(&self.#name), crate_path)) + }, + Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => { + let (id, field) = utils::filter_skip_unnamed(fields).next().unwrap(); + let id = syn::Index::from(id); + + Some(encode_single_field(field, quote!(&self.#id), crate_path)) + }, + _ => None, }, _ => None, } @@ -262,45 +273,45 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenS let self_ = quote!(self); let dest = "e!(__codec_dest_edqy); let [hinting, encoding] = match *data { - Data::Struct(ref data) => { - match data.fields { - Fields::Named(ref fields) => { - let fields = &fields.named; - let field_name = |_, name: &Option| quote!(&#self_.#name); - - let hinting = size_hint_fields(fields, field_name, crate_path); - let encoding = encode_fields(dest, fields, field_name, crate_path); - - [hinting, encoding] - }, - Fields::Unnamed(ref fields) => { - let fields = &fields.unnamed; - let field_name = |i, _: &Option| { - let i = syn::Index::from(i); - quote!(&#self_.#i) - }; - - let hinting = size_hint_fields(fields, field_name, crate_path); - let encoding = encode_fields(dest, fields, field_name, crate_path); - - [hinting, encoding] - }, - Fields::Unit => [quote! { 0_usize }, quote!()], - } + Data::Struct(ref data) => match data.fields { + Fields::Named(ref fields) => { + let fields = &fields.named; + let field_name = |_, name: &Option| quote!(&#self_.#name); + + let hinting = size_hint_fields(fields, field_name, crate_path); + let encoding = encode_fields(dest, fields, field_name, crate_path); + + [hinting, encoding] + }, + Fields::Unnamed(ref fields) => { + let fields = &fields.unnamed; + let field_name = |i, _: &Option| { + let i = syn::Index::from(i); + quote!(&#self_.#i) + }; + + let hinting = size_hint_fields(fields, field_name, crate_path); + let encoding = encode_fields(dest, fields, field_name, crate_path); + + [hinting, encoding] + }, + Fields::Unit => [quote! { 0_usize }, quote!()], }, Data::Enum(ref data) => { - let data_variants = || data.variants.iter().filter(|variant| !utils::should_skip(&variant.attrs)); + let data_variants = + || data.variants.iter().filter(|variant| !utils::should_skip(&variant.attrs)); if data_variants().count() > 256 { return Error::new( data.variants.span(), - "Currently only enums with at most 256 variants are encodable." - ).to_compile_error(); + "Currently only enums with at most 256 variants are encodable.", + ) + .to_compile_error() } // If the enum has no variants, we don't need to encode anything. if data_variants().count() == 0 { - return quote!(); + return quote!() } let recurse = data_variants().enumerate().map(|(i, f)| { @@ -312,10 +323,7 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenS let fields = &fields.named; let field_name = |_, ident: &Option| quote!(#ident); - let names = fields - .iter() - .enumerate() - .map(|(i, f)| field_name(i, &f.ident)); + let names = fields.iter().enumerate().map(|(i, f)| field_name(i, &f.ident)); let field_name = |a, b: &Option| field_name(a, b); @@ -348,10 +356,7 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenS quote!(#ident) }; - let names = fields - .iter() - .enumerate() - .map(|(i, f)| field_name(i, &f.ident)); + let names = fields.iter().enumerate().map(|(i, f)| field_name(i, &f.ident)); let field_name = |a, b: &Option| field_name(a, b); @@ -414,10 +419,9 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenS [hinting, encoding] }, - Data::Union(ref data) => return Error::new( - data.union_token.span(), - "Union types are not supported." - ).to_compile_error(), + Data::Union(ref data) => + return Error::new(data.union_token.span(), "Union types are not supported.") + .to_compile_error(), }; quote! { fn size_hint(&#self_) -> usize { From ddf9439de7253b632210072155dfc5caed0ed18a Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Mon, 4 Sep 2023 09:16:44 +0200 Subject: [PATCH 184/286] Fix max_encoded_len for Compact fields (#508) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix max_encoded_len for Compact fields * fix * Add missing test * nit * Apply suggestions from code review Co-authored-by: Bastian Köcher * fix ui-test output --------- Co-authored-by: Bastian Köcher --- derive/src/max_encoded_len.rs | 51 +++++++++++-------- tests/max_encoded_len.rs | 25 ++++++++- .../unsupported_variant.stderr | 20 +++++--- 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index bf8b20f7..f2db291b 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -17,10 +17,10 @@ use crate::{ trait_bounds, - utils::{codec_crate_path, custom_mel_trait_bound, has_dumb_trait_bound, should_skip}, + utils::{self, codec_crate_path, custom_mel_trait_bound, has_dumb_trait_bound, should_skip}, }; use quote::{quote, quote_spanned}; -use syn::{parse_quote, spanned::Spanned, Data, DeriveInput, Fields, Type}; +use syn::{parse_quote, spanned::Spanned, Data, DeriveInput, Field, Fields}; /// impl for `#[derive(MaxEncodedLen)]` pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream { @@ -43,13 +43,13 @@ pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::Tok parse_quote!(#crate_path::MaxEncodedLen), None, has_dumb_trait_bound(&input.attrs), - &crate_path + &crate_path, ) { return e.to_compile_error().into() } let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - let data_expr = data_length_expr(&input.data); + let data_expr = data_length_expr(&input.data, &crate_path); quote::quote!( const _: () = { @@ -64,22 +64,22 @@ pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::Tok } /// generate an expression to sum up the max encoded length from several fields -fn fields_length_expr(fields: &Fields) -> proc_macro2::TokenStream { - let type_iter: Box> = match fields { - Fields::Named(ref fields) => Box::new( - fields.named.iter().filter_map(|field| if should_skip(&field.attrs) { +fn fields_length_expr(fields: &Fields, crate_path: &syn::Path) -> proc_macro2::TokenStream { + let fields_iter: Box> = match fields { + Fields::Named(ref fields) => Box::new(fields.named.iter().filter_map(|field| { + if should_skip(&field.attrs) { None } else { - Some(&field.ty) - }) - ), - Fields::Unnamed(ref fields) => Box::new( - fields.unnamed.iter().filter_map(|field| if should_skip(&field.attrs) { + Some(field) + } + })), + Fields::Unnamed(ref fields) => Box::new(fields.unnamed.iter().filter_map(|field| { + if should_skip(&field.attrs) { None } else { - Some(&field.ty) - }) - ), + Some(field) + } + })), Fields::Unit => Box::new(std::iter::empty()), }; // expands to an expression like @@ -92,9 +92,16 @@ fn fields_length_expr(fields: &Fields) -> proc_macro2::TokenStream { // `max_encoded_len` call. This way, if one field's type doesn't implement // `MaxEncodedLen`, the compiler's error message will underline which field // caused the issue. - let expansion = type_iter.map(|ty| { - quote_spanned! { - ty.span() => .saturating_add(<#ty>::max_encoded_len()) + let expansion = fields_iter.map(|field| { + let ty = &field.ty; + if utils::is_compact(&field) { + quote_spanned! { + ty.span() => .saturating_add(<#crate_path::Compact::<#ty> as #crate_path::MaxEncodedLen>::max_encoded_len()) + } + } else { + quote_spanned! { + ty.span() => .saturating_add(<#ty as #crate_path::MaxEncodedLen>::max_encoded_len()) + } } }); quote! { @@ -103,9 +110,9 @@ fn fields_length_expr(fields: &Fields) -> proc_macro2::TokenStream { } // generate an expression to sum up the max encoded length of each field -fn data_length_expr(data: &Data) -> proc_macro2::TokenStream { +fn data_length_expr(data: &Data, crate_path: &syn::Path) -> proc_macro2::TokenStream { match *data { - Data::Struct(ref data) => fields_length_expr(&data.fields), + Data::Struct(ref data) => fields_length_expr(&data.fields, crate_path), Data::Enum(ref data) => { // We need an expression expanded for each variant like // @@ -121,7 +128,7 @@ fn data_length_expr(data: &Data) -> proc_macro2::TokenStream { // Each variant expression's sum is computed the way an equivalent struct's would be. let expansion = data.variants.iter().map(|variant| { - let variant_expression = fields_length_expr(&variant.fields); + let variant_expression = fields_length_expr(&variant.fields, crate_path); quote! { .max(#variant_expression) } diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs index b34ec12e..09d71a6f 100644 --- a/tests/max_encoded_len.rs +++ b/tests/max_encoded_len.rs @@ -16,7 +16,7 @@ //! Tests for MaxEncodedLen derive macro #![cfg(all(feature = "derive", feature = "max-encoded-len"))] -use parity_scale_codec::{MaxEncodedLen, Compact, Decode, Encode}; +use parity_scale_codec::{Compact, Decode, Encode, MaxEncodedLen}; #[derive(Encode, MaxEncodedLen)] struct Primitives { @@ -64,6 +64,29 @@ fn generic_max_length() { assert_eq!(Generic::::max_encoded_len(), u32::max_encoded_len() * 2); } +#[derive(Encode, MaxEncodedLen)] +struct CompactField { + #[codec(compact)] + t: u64, + v: u64, +} + +#[test] +fn compact_field_max_length() { + assert_eq!( + CompactField::max_encoded_len(), + Compact::::max_encoded_len() + u64::max_encoded_len() + ); +} + +#[derive(Encode, MaxEncodedLen)] +struct CompactStruct(#[codec(compact)] u64); + +#[test] +fn compact_struct_max_length() { + assert_eq!(CompactStruct::max_encoded_len(), Compact::::max_encoded_len()); +} + #[derive(Encode, MaxEncodedLen)] struct TwoGenerics { t: T, diff --git a/tests/max_encoded_len_ui/unsupported_variant.stderr b/tests/max_encoded_len_ui/unsupported_variant.stderr index bc4acacc..c4a48c60 100644 --- a/tests/max_encoded_len_ui/unsupported_variant.stderr +++ b/tests/max_encoded_len_ui/unsupported_variant.stderr @@ -1,12 +1,16 @@ -error[E0599]: no function or associated item named `max_encoded_len` found for struct `NotMel` in the current scope +error[E0277]: the trait bound `NotMel: MaxEncodedLen` is not satisfied --> tests/max_encoded_len_ui/unsupported_variant.rs:8:9 | -4 | struct NotMel; - | ------------- function or associated item `max_encoded_len` not found for this struct -... 8 | NotMel(NotMel), - | ^^^^^^ function or associated item not found in `NotMel` + | ^^^^^^ the trait `MaxEncodedLen` is not implemented for `NotMel` | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `max_encoded_len`, perhaps you need to implement it: - candidate #1: `MaxEncodedLen` + = help: the following other types implement trait `MaxEncodedLen`: + () + (TupleElement0, TupleElement1) + (TupleElement0, TupleElement1, TupleElement2) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) + and $N others From 3f933df0b7696e2d377bec9500c7de9274578a0d Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Mon, 4 Sep 2023 09:45:37 +0200 Subject: [PATCH 185/286] Release 3.6.6 (#510) --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 63695382..77b2131e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.6" dependencies = [ "arbitrary", "arrayvec", @@ -589,7 +589,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.6" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index e9a7842e..b34c1b3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.6.5" +version = "3.6.6" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.188", default-features = false, optional = true } -parity-scale-codec-derive = { path = "derive", version = ">= 3.6.5", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = ">= 3.6.6", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 625e0e13..8de22acc 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.6.5" +version = "3.6.6" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" From 1e3f80c1e047ec67f79f12e6a8067692edb14e9d Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 8 Sep 2023 11:02:20 +0200 Subject: [PATCH 186/286] Update MaxEncodedLen derive macro (#512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the generated code for MaxEncoded derive trait --------- Co-authored-by: Bastian Köcher --- derive/src/max_encoded_len.rs | 4 +++- src/compact.rs | 27 +++++++++++++++++++++++++-- src/max_encoded_len.rs | 3 +-- tests/max_encoded_len.rs | 17 +++++++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index f2db291b..763e8ceb 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -96,7 +96,9 @@ fn fields_length_expr(fields: &Fields, crate_path: &syn::Path) -> proc_macro2::T let ty = &field.ty; if utils::is_compact(&field) { quote_spanned! { - ty.span() => .saturating_add(<#crate_path::Compact::<#ty> as #crate_path::MaxEncodedLen>::max_encoded_len()) + ty.span() => .saturating_add( + <<#ty as #crate_path::HasCompact>::Type as #crate_path::MaxEncodedLen>::max_encoded_len() + ) } } else { quote_spanned! { diff --git a/src/compact.rs b/src/compact.rs index f19ea977..91e632e5 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -20,6 +20,8 @@ use crate::alloc::vec::Vec; use crate::codec::{Encode, Decode, Input, Output, EncodeAsRef}; use crate::encode_like::EncodeLike; use crate::Error; +#[cfg(feature = "max-encoded-len")] +use crate::MaxEncodedLen; #[cfg(feature = "fuzz")] use arbitrary::Arbitrary; @@ -206,18 +208,39 @@ impl<'de, T> serde::Deserialize<'de> for Compact where T: serde::Deserialize< } } +/// Requires the presence of `MaxEncodedLen` when the `max-encoded-len` feature is active. +// Remove this trait when the feature is removed. +#[cfg(feature = "max-encoded-len")] +pub trait MaybeMaxEncodedLen: MaxEncodedLen {} +#[cfg(feature = "max-encoded-len")] +impl MaybeMaxEncodedLen for T {} + +/// Requires the presence of `MaxEncodedLen` when the `max-encoded-len` feature is active. +// Remove this trait when the feature is removed. +#[cfg(not(feature = "max-encoded-len"))] +pub trait MaybeMaxEncodedLen {} +#[cfg(not(feature = "max-encoded-len"))] +impl MaybeMaxEncodedLen for T {} + /// Trait that tells you if a given type can be encoded/decoded in a compact way. pub trait HasCompact: Sized { /// The compact type; this can be - type Type: for<'a> EncodeAsRef<'a, Self> + Decode + From + Into; + type Type: for<'a> EncodeAsRef<'a, Self> + Decode + From + Into + MaybeMaxEncodedLen; } impl<'a, T: 'a> EncodeAsRef<'a, T> for Compact where CompactRef<'a, T>: Encode + From<&'a T> { type RefType = CompactRef<'a, T>; } +#[cfg(feature = "max-encoded-len")] +impl MaxEncodedLen for Compact where T: CompactAs, Compact: MaxEncodedLen, Compact: Encode { + fn max_encoded_len() -> usize { + Compact::::max_encoded_len() + } +} + impl HasCompact for T where - Compact: for<'a> EncodeAsRef<'a, T> + Decode + From + Into + Compact: for<'a> EncodeAsRef<'a, T> + Decode + From + Into + MaybeMaxEncodedLen { type Type = Compact; } diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs index c26ccf97..184eaa60 100644 --- a/src/max_encoded_len.rs +++ b/src/max_encoded_len.rs @@ -46,9 +46,8 @@ macro_rules! impl_primitives { }; } -impl_primitives!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, bool); - impl_primitives!( + u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, bool, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128 ); diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs index 09d71a6f..6924aa37 100644 --- a/tests/max_encoded_len.rs +++ b/tests/max_encoded_len.rs @@ -73,12 +73,29 @@ struct CompactField { #[test] fn compact_field_max_length() { + assert_eq!(CompactField::max_encoded_len(), 17); assert_eq!( CompactField::max_encoded_len(), Compact::::max_encoded_len() + u64::max_encoded_len() ); } + +#[derive(Encode, MaxEncodedLen)] +struct CompactFieldGenerics { + #[codec(compact)] + t: T, + v: u64, +} + +#[test] +fn compact_field_generics_max_length() { + assert_eq!( + CompactFieldGenerics::::max_encoded_len(), + CompactField::max_encoded_len() + ); +} + #[derive(Encode, MaxEncodedLen)] struct CompactStruct(#[codec(compact)] u64); From e2c4ff3f12b836b1ffcc05f57192f4aa4b471c58 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 8 Sep 2023 12:45:45 +0200 Subject: [PATCH 187/286] Bump to 3.6.7 (#515) --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77b2131e..f40ecfdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parity-scale-codec" -version = "3.6.6" +version = "3.6.7" dependencies = [ "arbitrary", "arrayvec", @@ -589,7 +589,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.6" +version = "3.6.7" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index b34c1b3a..e076b7f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.6.6" +version = "3.6.7" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.188", default-features = false, optional = true } -parity-scale-codec-derive = { path = "derive", version = ">= 3.6.6", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = ">= 3.6.7", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 8de22acc..86c1b7cc 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.6.6" +version = "3.6.7" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" From 37a6e7629f0f7b3e105e3aaff247b779dd244cda Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Sat, 9 Sep 2023 10:25:49 +0200 Subject: [PATCH 188/286] impl compact<()> for MaxEncodedLen (#516) --- src/max_encoded_len.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs index 184eaa60..1e857595 100644 --- a/src/max_encoded_len.rs +++ b/src/max_encoded_len.rs @@ -65,6 +65,7 @@ macro_rules! impl_compact { } impl_compact!( + () => 0; // github.com/paritytech/parity-scale-codec/blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/src/compact.rs#L261 u8 => 2; // github.com/paritytech/parity-scale-codec/blob/f0341dabb01aa9ff0548558abb6dcc5c31c669a1/src/compact.rs#L291 From 38d18bd9e4d4b6badc307b1646e4ccfa2c0356d4 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Mon, 11 Sep 2023 11:17:56 +0200 Subject: [PATCH 189/286] bump 3.6.8 (#518) * alpha-1 * rm alpha.1 --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- derive/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f40ecfdf..82392b4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parity-scale-codec" -version = "3.6.7" +version = "3.6.8" dependencies = [ "arbitrary", "arrayvec", @@ -589,7 +589,7 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.7" +version = "3.6.8" dependencies = [ "parity-scale-codec", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index e076b7f3..72cb7fb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.6.7" +version = "3.6.8" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.188", default-features = false, optional = true } -parity-scale-codec-derive = { path = "derive", version = ">= 3.6.7", default-features = false, optional = true } +parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 86c1b7cc..f56e6880 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parity-scale-codec-derive" description = "Serialization and deserialization derive macro for Parity SCALE Codec" -version = "3.6.7" +version = "3.6.8" authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" From b4da5fb752237def806d07350b4ef11f0235e19b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 09:43:44 +0200 Subject: [PATCH 190/286] Bump trybuild from 1.0.83 to 1.0.84 (#519) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.83 to 1.0.84. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.83...1.0.84) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82392b4e..00c14144 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.83" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6df60d81823ed9c520ee897489573da4b1d79ffbe006b8134f46de1a1aa03555" +checksum = "a5c89fd17b7536f2cf66c97cff6e811e89e728ca0ed13caeed610c779360d8b4" dependencies = [ "basic-toml", "glob", diff --git a/Cargo.toml b/Cargo.toml index 72cb7fb6..90484c1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.2.0" -trybuild = "1.0.83" +trybuild = "1.0.84" paste = "1" [[bench]] From 4d635fcb1997bff775eddb768fee6368d3d8e0c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 Sep 2023 00:19:02 +0200 Subject: [PATCH 191/286] Bump proc-macro2 from 1.0.66 to 1.0.67 (#523) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.66 to 1.0.67. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.66...1.0.67) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00c14144..808f5482 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,9 +650,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index f56e6880..7bc63cbb 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.33" -proc-macro2 = "1.0.66" +proc-macro2 = "1.0.67" proc-macro-crate = "1.1.3" [dev-dependencies] From 3f2716148f2ed801aa9c339a63dd00fe356c8758 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 16:07:11 +0200 Subject: [PATCH 192/286] Bump trybuild from 1.0.84 to 1.0.85 (#524) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.84 to 1.0.85. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.84...1.0.85) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 808f5482..43a4f8c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.84" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5c89fd17b7536f2cf66c97cff6e811e89e728ca0ed13caeed610c779360d8b4" +checksum = "196a58260a906cedb9bf6d8034b6379d0c11f552416960452f267402ceeddff1" dependencies = [ "basic-toml", "glob", diff --git a/Cargo.toml b/Cargo.toml index 90484c1a..ea0f4712 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.2.0" -trybuild = "1.0.84" +trybuild = "1.0.85" paste = "1" [[bench]] From b3128960757c9cfa2121b65819452fb7a8c4abd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 09:15:04 +0200 Subject: [PATCH 193/286] Bump proptest from 1.2.0 to 1.3.1 (#525) Bumps [proptest](https://github.com/proptest-rs/proptest) from 1.2.0 to 1.3.1. - [Release notes](https://github.com/proptest-rs/proptest/releases) - [Changelog](https://github.com/proptest-rs/proptest/blob/master/CHANGELOG.md) - [Commits](https://github.com/proptest-rs/proptest/compare/v1.2.0...v1.3.1) --- updated-dependencies: - dependency-name: proptest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 36 +++++++++++++++++++++--------------- Cargo.toml | 2 +- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43a4f8c0..d75abc59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,6 +79,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "bitvec" version = "1.0.1" @@ -103,12 +109,6 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "bytes" version = "1.4.0" @@ -166,7 +166,7 @@ version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ - "bitflags", + "bitflags 1.3.2", "clap_lex", "indexmap", "textwrap", @@ -659,19 +659,19 @@ dependencies = [ [[package]] name = "proptest" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" +checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" dependencies = [ "bit-set", - "bitflags", - "byteorder", + "bit-vec", + "bitflags 2.4.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax", + "regex-syntax 0.7.5", "rusty-fork", "tempfile", "unarray", @@ -779,7 +779,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -790,7 +790,7 @@ checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.6.26", ] [[package]] @@ -799,6 +799,12 @@ version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + [[package]] name = "rustc_version" version = "0.4.0" @@ -814,7 +820,7 @@ version = "0.37.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", diff --git a/Cargo.toml b/Cargo.toml index ea0f4712..307e252c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ criterion = "0.4.0" serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" -proptest = "1.2.0" +proptest = "1.3.1" trybuild = "1.0.85" paste = "1" From 83262563b12a79316d12af71e9b90685945ec8ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 10:34:50 +0200 Subject: [PATCH 194/286] Bump bytes from 1.4.0 to 1.5.0 (#513) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d75abc59..3ae454f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cast" From 02593af85cdded9d6f00941b65ad2ca8ff594c29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Oct 2023 22:12:47 +0200 Subject: [PATCH 195/286] Bump proc-macro2 from 1.0.67 to 1.0.68 (#526) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.67 to 1.0.68. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.67...1.0.68) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ae454f9..73bdea07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,9 +650,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "5b1106fec09662ec6dd98ccac0f81cef56984d0b49f75c92d8cbad76e20c005c" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 7bc63cbb..fff4855f 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.33" -proc-macro2 = "1.0.67" +proc-macro2 = "1.0.68" proc-macro-crate = "1.1.3" [dev-dependencies] From 3abbdf901e8a191f8ac5de87656731988b4a9356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 13 Oct 2023 17:40:43 +0200 Subject: [PATCH 196/286] Update UI tests for 1.73.0 (#530) --- derive/src/trait_bounds.rs | 5 +-- tests/max_encoded_len_ui.rs | 3 -- tests/max_encoded_len_ui/crate_str.stderr | 40 +++++++++---------- .../max_encoded_len_ui/incomplete_attr.stderr | 40 +++++++++---------- .../missing_crate_specifier.stderr | 40 +++++++++---------- tests/max_encoded_len_ui/not_encode.stderr | 40 +++++++++---------- tests/max_encoded_len_ui/union.stderr | 2 +- .../unsupported_variant.stderr | 16 ++++---- 8 files changed, 91 insertions(+), 95 deletions(-) diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index 6b044efe..f803990d 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -128,9 +128,8 @@ pub fn add( let ty_params = generics .type_params() - .filter_map(|tp| { - skip_type_params.iter().all(|skip| skip != &tp.ident).then(|| tp.ident.clone()) - }) + .filter(|tp| skip_type_params.iter().all(|skip| skip != &tp.ident)) + .map(|tp| tp.ident.clone()) .collect::>(); if ty_params.is_empty() { return Ok(()) diff --git a/tests/max_encoded_len_ui.rs b/tests/max_encoded_len_ui.rs index 2bf41457..c4c4cf4e 100644 --- a/tests/max_encoded_len_ui.rs +++ b/tests/max_encoded_len_ui.rs @@ -16,9 +16,6 @@ #[test] #[cfg(feature = "derive")] fn derive_no_bound_ui() { - // As trybuild is using `cargo check`, we don't need the real WASM binaries. - std::env::set_var("SKIP_WASM_BUILD", "1"); - let t = trybuild::TestCases::new(); t.compile_fail("tests/max_encoded_len_ui/*.rs"); t.pass("tests/max_encoded_len_ui/pass/*.rs"); diff --git a/tests/max_encoded_len_ui/crate_str.stderr b/tests/max_encoded_len_ui/crate_str.stderr index c9c46cb1..23a451f6 100644 --- a/tests/max_encoded_len_ui/crate_str.stderr +++ b/tests/max_encoded_len_ui/crate_str.stderr @@ -5,24 +5,24 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = pa | ^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> tests/max_encoded_len_ui/crate_str.rs:5:8 - | -5 | struct Example; - | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` - | - = help: the following other types implement trait `WrapperTypeEncode`: - &T - &mut T - Arc - Box - Cow<'a, T> - Rc - String - Vec - parity_scale_codec::Ref<'a, T, U> - = note: required for `Example` to implement `Encode` + --> tests/max_encoded_len_ui/crate_str.rs:5:8 + | +5 | struct Example; + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` + | + = help: the following other types implement trait `WrapperTypeEncode`: + Box + Cow<'a, T> + parity_scale_codec::Ref<'a, T, U> + Rc + Arc + Vec + String + &T + &mut T + = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` - --> src/max_encoded_len.rs - | - | pub trait MaxEncodedLen: Encode { - | ^^^^^^ required by this bound in `MaxEncodedLen` + --> src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ^^^^^^ required by this bound in `MaxEncodedLen` diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr index b9c58104..b5ab07c7 100644 --- a/tests/max_encoded_len_ui/incomplete_attr.stderr +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -5,24 +5,24 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = pa | ^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> tests/max_encoded_len_ui/incomplete_attr.rs:5:8 - | -5 | struct Example; - | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` - | - = help: the following other types implement trait `WrapperTypeEncode`: - &T - &mut T - Arc - Box - Cow<'a, T> - Rc - String - Vec - parity_scale_codec::Ref<'a, T, U> - = note: required for `Example` to implement `Encode` + --> tests/max_encoded_len_ui/incomplete_attr.rs:5:8 + | +5 | struct Example; + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` + | + = help: the following other types implement trait `WrapperTypeEncode`: + Box + Cow<'a, T> + parity_scale_codec::Ref<'a, T, U> + Rc + Arc + Vec + String + &T + &mut T + = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` - --> src/max_encoded_len.rs - | - | pub trait MaxEncodedLen: Encode { - | ^^^^^^ required by this bound in `MaxEncodedLen` + --> src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ^^^^^^ required by this bound in `MaxEncodedLen` diff --git a/tests/max_encoded_len_ui/missing_crate_specifier.stderr b/tests/max_encoded_len_ui/missing_crate_specifier.stderr index c056aec9..68e98a6a 100644 --- a/tests/max_encoded_len_ui/missing_crate_specifier.stderr +++ b/tests/max_encoded_len_ui/missing_crate_specifier.stderr @@ -5,24 +5,24 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = pa | ^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied - --> tests/max_encoded_len_ui/missing_crate_specifier.rs:5:8 - | -5 | struct Example; - | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` - | - = help: the following other types implement trait `WrapperTypeEncode`: - &T - &mut T - Arc - Box - Cow<'a, T> - Rc - String - Vec - parity_scale_codec::Ref<'a, T, U> - = note: required for `Example` to implement `Encode` + --> tests/max_encoded_len_ui/missing_crate_specifier.rs:5:8 + | +5 | struct Example; + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` + | + = help: the following other types implement trait `WrapperTypeEncode`: + Box + Cow<'a, T> + parity_scale_codec::Ref<'a, T, U> + Rc + Arc + Vec + String + &T + &mut T + = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` - --> src/max_encoded_len.rs - | - | pub trait MaxEncodedLen: Encode { - | ^^^^^^ required by this bound in `MaxEncodedLen` + --> src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ^^^^^^ required by this bound in `MaxEncodedLen` diff --git a/tests/max_encoded_len_ui/not_encode.stderr b/tests/max_encoded_len_ui/not_encode.stderr index 3e4e57bc..b2fb1d85 100644 --- a/tests/max_encoded_len_ui/not_encode.stderr +++ b/tests/max_encoded_len_ui/not_encode.stderr @@ -1,22 +1,22 @@ error[E0277]: the trait bound `NotEncode: WrapperTypeEncode` is not satisfied - --> tests/max_encoded_len_ui/not_encode.rs:4:8 - | -4 | struct NotEncode; - | ^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `NotEncode` - | - = help: the following other types implement trait `WrapperTypeEncode`: - &T - &mut T - Arc - Box - Cow<'a, T> - Rc - String - Vec - parity_scale_codec::Ref<'a, T, U> - = note: required for `NotEncode` to implement `Encode` + --> tests/max_encoded_len_ui/not_encode.rs:4:8 + | +4 | struct NotEncode; + | ^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `NotEncode` + | + = help: the following other types implement trait `WrapperTypeEncode`: + Box + Cow<'a, T> + parity_scale_codec::Ref<'a, T, U> + Rc + Arc + Vec + String + &T + &mut T + = note: required for `NotEncode` to implement `Encode` note: required by a bound in `MaxEncodedLen` - --> src/max_encoded_len.rs - | - | pub trait MaxEncodedLen: Encode { - | ^^^^^^ required by this bound in `MaxEncodedLen` + --> src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ^^^^^^ required by this bound in `MaxEncodedLen` diff --git a/tests/max_encoded_len_ui/union.stderr b/tests/max_encoded_len_ui/union.stderr index af3dc931..fa21ec9c 100644 --- a/tests/max_encoded_len_ui/union.stderr +++ b/tests/max_encoded_len_ui/union.stderr @@ -1,5 +1,5 @@ error: Union types are not supported. - --> $DIR/union.rs:4:1 + --> tests/max_encoded_len_ui/union.rs:4:1 | 4 | union Union { | ^^^^^ diff --git a/tests/max_encoded_len_ui/unsupported_variant.stderr b/tests/max_encoded_len_ui/unsupported_variant.stderr index c4a48c60..848139a1 100644 --- a/tests/max_encoded_len_ui/unsupported_variant.stderr +++ b/tests/max_encoded_len_ui/unsupported_variant.stderr @@ -5,12 +5,12 @@ error[E0277]: the trait bound `NotMel: MaxEncodedLen` is not satisfied | ^^^^^^ the trait `MaxEncodedLen` is not implemented for `NotMel` | = help: the following other types implement trait `MaxEncodedLen`: - () - (TupleElement0, TupleElement1) - (TupleElement0, TupleElement1, TupleElement2) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) + bool + i8 + i16 + i32 + i64 + i128 + u8 + u16 and $N others From 36d4bf631ff8a45b952a7e88a2f96a9251fc9f7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:50:27 +0200 Subject: [PATCH 197/286] Bump arbitrary from 1.0.3 to 1.3.1 (#528) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Marcin S --- Cargo.lock | 10 +++++----- Cargo.toml | 2 +- fuzzer/Cargo.toml | 2 +- fuzzer/README.md | 8 +++++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73bdea07..09590eff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "arbitrary" -version = "1.0.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510c76ecefdceada737ea728f4f9a84bd2e1ef29f1ba555e560940fe279954de" +checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" dependencies = [ "derive_arbitrary", ] @@ -273,13 +273,13 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.0.2" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b24629208e87a2d8b396ff43b15c4afb0a69cea3fbbaa9ed9b92b7c02f0aed73" +checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 1.0.98", + "syn 2.0.28", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 307e252c..dcf4bf3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ bitvec = { version = "1", default-features = false, features = [ "alloc" ], opti bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } generic-array = { version = "0.14.7", optional = true } -arbitrary = { version = "1.0.1", features = ["derive"], optional = true } +arbitrary = { version = "1.3.1", features = ["derive"], optional = true } impl-trait-for-tuples = "0.2.2" [dev-dependencies] diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 69f8a48e..a2faa628 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -9,5 +9,5 @@ publish = false [dependencies] parity-scale-codec = { path = "..", features = ["derive", "bit-vec", "fuzz"] } honggfuzz = "0.5.55" -arbitrary = { version = "1.0.1", features = ["derive"] } +arbitrary = { version = "1.3.1", features = ["derive"] } bitvec = { version = "1", features = ["alloc"] } diff --git a/fuzzer/README.md b/fuzzer/README.md index e744289a..56579a43 100644 --- a/fuzzer/README.md +++ b/fuzzer/README.md @@ -1,6 +1,11 @@ # Parity SCALE Codec fuzzer ## Requirements: + +Make sure you have the requirements installed: + +https://github.com/rust-fuzz/honggfuzz-rs#dependencies + Install [honggfuzz-rs](https://github.com/rust-fuzz/honggfuzz-rs): ``` cargo install honggfuzz @@ -10,6 +15,3 @@ Run the fuzzer: ``` cargo hfuzz run codec-fuzzer ``` - - - From 60ab5fb180527936479b450588d3d1747358e03b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Oct 2023 01:13:27 +0200 Subject: [PATCH 198/286] Bump serde from 1.0.188 to 1.0.189 (#531) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.188 to 1.0.189. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.188...v1.0.189) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09590eff..13d05888 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,18 +869,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index dcf4bf3c..21448005 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.188", default-features = false, optional = true } +serde = { version = "1.0.189", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 9b9037fa8db666ef3d7f54dc434de3f9a94be3b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Oct 2023 10:25:14 +0200 Subject: [PATCH 199/286] Bump proc-macro2 from 1.0.68 to 1.0.69 (#527) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.68 to 1.0.69. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.68...1.0.69) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13d05888..633ee6ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,9 +650,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1106fec09662ec6dd98ccac0f81cef56984d0b49f75c92d8cbad76e20c005c" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index fff4855f..47510ee6 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.33" -proc-macro2 = "1.0.68" +proc-macro2 = "1.0.69" proc-macro-crate = "1.1.3" [dev-dependencies] From 984c98154cc897d3a84ea9d7f5bdd651cb581a7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:08:03 +0200 Subject: [PATCH 200/286] Bump rustix from 0.37.18 to 0.37.25 (#533) Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.37.18 to 0.37.25. - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Commits](https://github.com/bytecodealliance/rustix/compare/v0.37.18...v0.37.25) --- updated-dependencies: - dependency-name: rustix dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 633ee6ac..5bcfc53e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,9 +479,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.142" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libm" @@ -816,9 +816,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.18" +version = "0.37.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433" +checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" dependencies = [ "bitflags 1.3.2", "errno", From 802af25361c765268059d0a47dde2bdac9a0d83c Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:43:08 +0200 Subject: [PATCH 201/286] [ci] Add job to publish crates (#517) * [ci] Add job to publish crates * add dag * add publish job --- .gitlab-ci.yml | 136 +++++++++++++++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 56 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5c2ff28b..1776e7d1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,23 +4,23 @@ include: - project: parity/infrastructure/ci_cd/shared ref: main - file: /common/ci-unified.yml - + file: /common/ci-unified.yml stages: - check - test - build + - publish variables: - GIT_STRATEGY: fetch - GIT_DEPTH: "100" - CARGO_INCREMENTAL: 0 - CI_IMAGE: !reference [.ci-unified, variables, CI_IMAGE] + GIT_STRATEGY: fetch + GIT_DEPTH: "100" + CARGO_INCREMENTAL: 0 + CI_IMAGE: !reference [.ci-unified, variables, CI_IMAGE] default: - cache: {} - interruptible: true + cache: {} + interruptible: true retry: max: 2 when: @@ -28,8 +28,13 @@ default: - unknown_failure - api_failure -.docker-env: &docker-env - image: $CI_IMAGE +.kubernetes-env: + image: $CI_IMAGE + tags: + - kubernetes-parity-build + +.docker-env: + image: $CI_IMAGE before_script: - cargo -vV - rustc -vV @@ -41,16 +46,16 @@ default: - if: $CI_PIPELINE_SOURCE == "schedule" - if: $CI_COMMIT_REF_NAME == "master" - if: $CI_COMMIT_REF_NAME == "tags" - - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs - - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 tags: - - linux-docker-vm-c2 + - linux-docker #### stage: check check-clippy: - stage: check - <<: *docker-env + stage: check + extends: .docker-env script: - rustup component add clippy --toolchain stable-x86_64-unknown-linux-gnu - time cargo +stable clippy --locked -- -Dwarnings @@ -58,106 +63,103 @@ check-clippy: - time cargo +stable clippy --locked --test clippy -- -Dwarnings check-rust-stable-no_derive_no_std: - stage: check - <<: *docker-env + stage: check + extends: .docker-env variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array - check-rust-stable-no_std-chain-error: - stage: check - <<: *docker-env + stage: check + extends: .docker-env variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --no-default-features --features chain-error - check-rust-stable-no_derive: - stage: check - <<: *docker-env + stage: check + extends: .docker-env variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --features bit-vec,bytes,generic-array check-rust-stable-only_mel: - stage: check - <<: *docker-env + stage: check + extends: .docker-env variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable check --verbose --features max-encoded-len #### stage: test test-rust-stable: - stage: test - <<: *docker-env + stage: test + extends: .docker-env variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable test --verbose --all --features bit-vec,bytes,generic-array,derive,max-encoded-len - test-rust-stable-no_derive: - stage: test - <<: *docker-env + stage: test + extends: .docker-env variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable test --verbose --features bit-vec,bytes,generic-array test-rust-stable-only_mel: - stage: test - <<: *docker-env + stage: test + extends: .docker-env variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable test --verbose --features max-encoded-len test-rust-stable-only_mel-no_default_std: - stage: test - <<: *docker-env + stage: test + extends: .docker-env variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - time cargo +stable test --verbose --features max-encoded-len,std --no-default-features bench-rust-nightly: - stage: test - <<: *docker-env + stage: test + extends: .docker-env script: - time cargo +nightly bench --features bit-vec,bytes,generic-array,derive miri: - stage: test - <<: *docker-env + stage: test + extends: .docker-env variables: - RUST_BACKTRACE: 1 - MIRIFLAGS: "-Zmiri-disable-isolation" + RUST_BACKTRACE: 1 + MIRIFLAGS: "-Zmiri-disable-isolation" script: - time cargo +nightly miri test --features bit-vec,bytes,generic-array,arbitrary --release # check that build is no_std compatible # more info: https://github.com/paritytech/parity-scale-codec/pull/389 build-no-std: - stage: test - <<: *docker-env + stage: test + extends: .docker-env variables: - RUST_BACKTRACE: 1 + RUST_BACKTRACE: 1 script: # this target doesn't support std envs; it should flag any unexpected uses of std - rustup target add thumbv6m-none-eabi - time cargo build --target thumbv6m-none-eabi --no-default-features build-no-atomic-ptrs: - stage: test - <<: *docker-env + stage: test + extends: .docker-env variables: - RUST_BACKTRACE: 1 + RUST_BACKTRACE: 1 script: # this target doesn't have atomic ptrs. Some parts of alloc are not available there # we want to make sure that this crate still works on those targets @@ -166,8 +168,8 @@ build-no-atomic-ptrs: #### stage: build build-linux-ubuntu-amd64: - stage: build - <<: *docker-env + stage: build + extends: .docker-env rules: - if: $CI_PIPELINE_SOURCE == "web" - if: $CI_PIPELINE_SOURCE == "schedule" @@ -175,3 +177,25 @@ build-linux-ubuntu-amd64: - if: $CI_COMMIT_REF_NAME == "tags" script: - cargo build --verbose --release --features bit-vec,bytes,generic-array,derive + +#### stage: publish + +publish-dry-run: + stage: publish + extends: .kubernetes-env + # artificial dependency in order not to wait miri job + needs: + - job: check-clippy + artifacts: false + rules: + - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs + script: + - cargo publish -p parity-scale-codec --dry-run + +publish-crate: + stage: publish + extends: .kubernetes-env + rules: + - if: $CI_COMMIT_REF_NAME =~ /^v.[0-9]+\.[0-9]+.*$/ # i.e. v.1.0, v.2.1rc1 + script: + - cargo publish -p parity-scale-codec From 8dff7a148d8d70448b535ba8b8131a1d10bc8940 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 21:54:16 +0200 Subject: [PATCH 202/286] Bump serde from 1.0.189 to 1.0.190 (#534) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.189 to 1.0.190. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.189...v1.0.190) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5bcfc53e..64a12401 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,18 +869,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.189" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 21448005..6e99169b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.189", default-features = false, optional = true } +serde = { version = "1.0.190", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 017f72ed7bcc75e275f561cf91712f2ef6edb082 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 27 Oct 2023 19:50:49 +0100 Subject: [PATCH 203/286] Bump `proc-macro-crate` to `2.0.0` (#535) --- Cargo.lock | 82 +++++++++++++++++++++++++++++------------------ derive/Cargo.toml | 2 +- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64a12401..947fed21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,7 +168,7 @@ checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "bitflags 1.3.2", "clap_lex", - "indexmap", + "indexmap 1.9.3", "textwrap", ] @@ -298,6 +298,12 @@ dependencies = [ "regex", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.1" @@ -379,6 +385,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -424,7 +436,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", ] [[package]] @@ -506,9 +528,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.1" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" @@ -640,12 +662,11 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "1.1.3" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "thiserror", - "toml", + "toml_edit", ] [[package]] @@ -954,26 +975,6 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" -[[package]] -name = "thiserror" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.98", -] - [[package]] name = "tinytemplate" version = "1.2.1" @@ -985,12 +986,20 @@ dependencies = [ ] [[package]] -name = "toml" -version = "0.5.8" +name = "toml_datetime" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.20.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "782bf6c2ddf761c1e7855405e8975472acf76f7f36d0d4328bd3b7a2fae12a85" dependencies = [ - "serde", + "indexmap 2.0.2", + "toml_datetime", + "winnow", ] [[package]] @@ -1285,6 +1294,15 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winnow" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" +dependencies = [ + "memchr", +] + [[package]] name = "wyz" version = "0.5.0" diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 47510ee6..82748aa9 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.33" proc-macro2 = "1.0.69" -proc-macro-crate = "1.1.3" +proc-macro-crate = "2.0.0" [dev-dependencies] parity-scale-codec = { path = "..", features = ["derive", "max-encoded-len"] } From 577b112ec889e9ba1d3b3a299fed3ef995e2a7d5 Mon Sep 17 00:00:00 2001 From: Yuri Volkov <0@mcornholio.ru> Date: Mon, 30 Oct 2023 11:50:09 +0100 Subject: [PATCH 204/286] Adding gitspiegel-trigger workflow (#537) Using a workflow to trigger mirroring instead of a webhook allows us to reuse "Approving workflow runs from public forks" GitHub feature to somewhat protect us from malicious PRs --- .github/workflows/gitspiegel-trigger.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/gitspiegel-trigger.yml diff --git a/.github/workflows/gitspiegel-trigger.yml b/.github/workflows/gitspiegel-trigger.yml new file mode 100644 index 00000000..86980756 --- /dev/null +++ b/.github/workflows/gitspiegel-trigger.yml @@ -0,0 +1,20 @@ +name: gitspiegel sync + +on: + pull_request: + types: + - opened + - synchronize + - unlocked + - ready_for_review + - reopened + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Trigger sync via API + run: | + curl --fail-with-body -XPOST "https://gitspiegel.parity-prod.parity.io/api/v1/mirror/${{ github.repository }}/pull/${{ github.event.number }}" \ + -H "Content-Type: application/json" \ + -H "x-auth: ${{ secrets.GITSPIEGEL_TOKEN }}" From 28c066dc9a209eaeca8a33d8a4c5a08182694083 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 10:13:22 +0100 Subject: [PATCH 205/286] Bump arbitrary from 1.3.1 to 1.3.2 (#538) Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.3.1 to 1.3.2. - [Changelog](https://github.com/rust-fuzz/arbitrary/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-fuzz/arbitrary/compare/derive_arbitrary@1.3.1...v1.3.2) --- updated-dependencies: - dependency-name: arbitrary dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- fuzzer/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 947fed21..9eea17f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "arbitrary" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" dependencies = [ "derive_arbitrary", ] @@ -273,9 +273,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 6e99169b..c1c98a0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ bitvec = { version = "1", default-features = false, features = [ "alloc" ], opti bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } generic-array = { version = "0.14.7", optional = true } -arbitrary = { version = "1.3.1", features = ["derive"], optional = true } +arbitrary = { version = "1.3.2", features = ["derive"], optional = true } impl-trait-for-tuples = "0.2.2" [dev-dependencies] diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index a2faa628..9ace1624 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -9,5 +9,5 @@ publish = false [dependencies] parity-scale-codec = { path = "..", features = ["derive", "bit-vec", "fuzz"] } honggfuzz = "0.5.55" -arbitrary = { version = "1.3.1", features = ["derive"] } +arbitrary = { version = "1.3.2", features = ["derive"] } bitvec = { version = "1", features = ["alloc"] } From fb12c0707500be6ac4c91c450a9f5dea0ae75719 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 20:46:27 +0100 Subject: [PATCH 206/286] Bump serde from 1.0.190 to 1.0.192 (#540) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.190 to 1.0.192. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.190...v1.0.192) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9eea17f7..ecc6c486 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -890,18 +890,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.190" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index c1c98a0c..04b3975d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.190", default-features = false, optional = true } +serde = { version = "1.0.192", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From c781ce04706f64c9b1fffa7ed5dd5bd14ede76db Mon Sep 17 00:00:00 2001 From: Yuri Volkov <0@mcornholio.ru> Date: Mon, 13 Nov 2023 10:43:36 +0100 Subject: [PATCH 207/286] Fixing gitspiegel trigger workflow (#541) --- .github/workflows/gitspiegel-trigger.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/gitspiegel-trigger.yml b/.github/workflows/gitspiegel-trigger.yml index 86980756..dce3aaf2 100644 --- a/.github/workflows/gitspiegel-trigger.yml +++ b/.github/workflows/gitspiegel-trigger.yml @@ -1,5 +1,10 @@ name: gitspiegel sync +# This workflow doesn't do anything, it's only use is to trigger "workflow_run" +# webhook, that'll be consumed by gitspiegel +# This way, gitspiegel won't do mirroring, unless this workflow runs, +# and running the workflow is protected by GitHub + on: pull_request: types: @@ -13,8 +18,5 @@ jobs: sync: runs-on: ubuntu-latest steps: - - name: Trigger sync via API - run: | - curl --fail-with-body -XPOST "https://gitspiegel.parity-prod.parity.io/api/v1/mirror/${{ github.repository }}/pull/${{ github.event.number }}" \ - -H "Content-Type: application/json" \ - -H "x-auth: ${{ secrets.GITSPIEGEL_TOKEN }}" + - name: Do nothing + run: echo "let's go" From 060be3556fe3f6e25c97a8e6c72f4d424498e103 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:41:52 +0100 Subject: [PATCH 208/286] Bump serde from 1.0.192 to 1.0.193 (#543) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.192 to 1.0.193. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.192...v1.0.193) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecc6c486..41194f1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -890,18 +890,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 04b3975d..4be178ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.192", default-features = false, optional = true } +serde = { version = "1.0.193", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From e9e396c6a5e4c2c10e4c27473b50af7a198ac44d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 23:31:06 +0100 Subject: [PATCH 209/286] Bump proc-macro2 from 1.0.69 to 1.0.70 (#544) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.69 to 1.0.70. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.69...1.0.70) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 41194f1f..8cb0cf70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -671,9 +671,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 82748aa9..03be7804 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.33" -proc-macro2 = "1.0.69" +proc-macro2 = "1.0.70" proc-macro-crate = "2.0.0" [dev-dependencies] From d0f04b4e1a4415410e7f979d58b01107699527b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:38:09 +0100 Subject: [PATCH 210/286] Bump proc-macro-crate from 2.0.0 to 2.0.1 (#547) Bumps [proc-macro-crate](https://github.com/bkchr/proc-macro-crate) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/bkchr/proc-macro-crate/releases) - [Commits](https://github.com/bkchr/proc-macro-crate/compare/v2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: proc-macro-crate dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 13 +++++++------ derive/Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8cb0cf70..1cc056f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -662,10 +662,11 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" dependencies = [ + "toml_datetime", "toml_edit", ] @@ -987,15 +988,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.20.5" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "782bf6c2ddf761c1e7855405e8975472acf76f7f36d0d4328bd3b7a2fae12a85" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ "indexmap 2.0.2", "toml_datetime", diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 03be7804..12d2cd6a 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.33" proc-macro2 = "1.0.70" -proc-macro-crate = "2.0.0" +proc-macro-crate = "2.0.1" [dev-dependencies] parity-scale-codec = { path = "..", features = ["derive", "max-encoded-len"] } From 5fc75b9d5dcf4e00ab5abab30ce2f4774a7ecbc1 Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Fri, 8 Dec 2023 22:36:50 +0100 Subject: [PATCH 211/286] [ci] fix publish job (#548) --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1776e7d1..cc6b587f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -196,6 +196,6 @@ publish-crate: stage: publish extends: .kubernetes-env rules: - - if: $CI_COMMIT_REF_NAME =~ /^v.[0-9]+\.[0-9]+.*$/ # i.e. v.1.0, v.2.1rc1 + - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 script: - cargo publish -p parity-scale-codec From c1914969e12fef07959b9f45fc36b94d0ae1e270 Mon Sep 17 00:00:00 2001 From: Sergejs Kostjucenko <85877331+sergejparity@users.noreply.github.com> Date: Wed, 13 Dec 2023 13:46:27 +0200 Subject: [PATCH 212/286] Switch CI from GitLab to GitHub Actions (#546) Switch CI from GitLab to GitHub Actions Co-authored-by: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> --- .github/workflows/ci.yml | 206 +++++++++++++++++++++++ .github/workflows/gitspiegel-trigger.yml | 22 --- .github/workflows/publish.yml | 23 +++ .gitlab-ci.yml | 201 ---------------------- 4 files changed, 229 insertions(+), 223 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/gitspiegel-trigger.yml create mode 100644 .github/workflows/publish.yml delete mode 100644 .gitlab-ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..573ce99f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,206 @@ +name: Rust CI/CD + +on: + push: + branches: + - master + pull_request: + +env: + IMAGE: paritytech/ci-unified:bullseye-1.73.0 +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +jobs: + set-image: + # GitHub Actions does not allow using 'env' in a container context. + # This workaround sets the container image for each job using 'set-image' job output. + runs-on: ubuntu-latest + outputs: + IMAGE: ${{ steps.set_image.outputs.IMAGE }} + steps: + - id: set_image + run: echo "IMAGE=${{ env.IMAGE }}" >> $GITHUB_OUTPUT + +# Checks + clippy: + runs-on: ubuntu-latest + needs: [set-image] + container: ${{ needs.set-image.outputs.IMAGE }} + steps: + - name: Checkout code/. + uses: actions/checkout@v4 + + - name: Show Rust version + run: | + cargo -vV + rustc -vV + rustup show + + - name: Cache Rust dependencies + uses: swatinem/rust-cache@v2 + with: + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + + - name: Run Clippy + run: | + cargo +stable clippy --locked -- -Dwarnings + cargo +stable clippy --locked -p parity-scale-codec-derive -- -Dwarnings + cargo +stable clippy --locked --test clippy -- -Dwarnings + + checks: + runs-on: ubuntu-latest + needs: [set-image] + container: ${{ needs.set-image.outputs.IMAGE }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Show Rust version + run: | + cargo -vV + rustc -vV + rustup show + + - name: Cache Rust dependencies + uses: swatinem/rust-cache@v2 + with: + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + + - name: Check Rust Stable (no_derive_no_std) + run: time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array + + - name: Check Rust Stable (no_std-chain-error) + run: | + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + time cargo +stable check --verbose --no-default-features --features chain-error + + - name: check-rust-stable-no_derive + run: | + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + time cargo +stable check --verbose --features bit-vec,bytes,generic-array + + - name: check-rust-stable-only_mel + run: | + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + time cargo +stable check --verbose --features max-encoded-len + +# Tests + tests: + runs-on: ubuntu-latest + needs: [set-image] + container: ${{ needs.set-image.outputs.IMAGE }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Show Rust version + run: | + cargo -vV + rustc -vV + rustup show + + - name: Cache Rust dependencies + uses: swatinem/rust-cache@v2 + with: + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + + - name: Test Rust Stable + run: | + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + time cargo +stable test --verbose --all --features bit-vec,bytes,generic-array,derive,max-encoded-len + + - name: Test Rust Stable (no_derive) + run: | + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + time cargo +stable test --verbose --features bit-vec,bytes,generic-array + + - name: Test Rust Stable (only_mel) + run: | + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + time cargo +stable test --verbose --features max-encoded-len + + - name: Test Rust Stable (only_mel-no_default_std) + run: | + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + time cargo +stable test --verbose --features max-encoded-len,std --no-default-features + +# Benches + bench-rust-nightly: + runs-on: ubuntu-latest + needs: [set-image] + strategy: + matrix: + feature: [bit-vec,bytes,generic-array,derive,max-encoded-len] + container: ${{ needs.set-image.outputs.IMAGE }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache Rust dependencies + uses: swatinem/rust-cache@v2 + with: + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + + - name: Bench Rust Nightly + run: | + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + time cargo +nightly bench --features ${{ matrix.feature }} + + miri: + runs-on: ubuntu-latest + needs: [set-image] + strategy: + matrix: + feature: [bit-vec,bytes,generic-array,arbitrary] + container: ${{ needs.set-image.outputs.IMAGE }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache Rust dependencies + uses: swatinem/rust-cache@v2 + with: + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + + - name: Run Miri + run: | + export RUST_BACKTRACE=1 + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + export MIRIFLAGS='-Zmiri-disable-isolation' + time cargo +nightly miri test --features ${{ matrix.feature }} --release + +# Build + + build-linux-ubuntu-amd64: + runs-on: ubuntu-latest + needs: [set-image, clippy, checks, tests] + container: ${{ needs.set-image.outputs.IMAGE }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache Rust dependencies + uses: swatinem/rust-cache@v2 + with: + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + + - name: Build for Linux (Ubuntu, AMD64) + run: cargo build --verbose --release --features bit-vec,bytes,generic-array,derive + + publish-dry-run: + runs-on: ubuntu-latest + needs: [set-image, build-linux-ubuntu-amd64] + container: ${{ needs.set-image.outputs.IMAGE }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache Rust dependencies + uses: swatinem/rust-cache@v2 + with: + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + + - name: Dry Run Publish + if: github.event_name == 'pull_request' + run: cargo publish -p parity-scale-codec --dry-run diff --git a/.github/workflows/gitspiegel-trigger.yml b/.github/workflows/gitspiegel-trigger.yml deleted file mode 100644 index dce3aaf2..00000000 --- a/.github/workflows/gitspiegel-trigger.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: gitspiegel sync - -# This workflow doesn't do anything, it's only use is to trigger "workflow_run" -# webhook, that'll be consumed by gitspiegel -# This way, gitspiegel won't do mirroring, unless this workflow runs, -# and running the workflow is protected by GitHub - -on: - pull_request: - types: - - opened - - synchronize - - unlocked - - ready_for_review - - reopened - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - name: Do nothing - run: echo "let's go" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..2e9f3322 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,23 @@ +name: Publish release to crates.io + +on: + release: + types: + - published + +jobs: + publish-crate: + runs-on: ubuntu-latest + environment: release + container: paritytech/ci-unified:bullseye-1.73.0 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache Rust dependencies + uses: swatinem/rust-cache@v2 + with: + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + + - name: Publish Crate + run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} -p parity-scale-codec diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index cc6b587f..00000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,201 +0,0 @@ -# .gitlab-ci.yml -# - -include: - - project: parity/infrastructure/ci_cd/shared - ref: main - file: /common/ci-unified.yml - -stages: - - check - - test - - build - - publish - -variables: - GIT_STRATEGY: fetch - GIT_DEPTH: "100" - CARGO_INCREMENTAL: 0 - CI_IMAGE: !reference [.ci-unified, variables, CI_IMAGE] - -default: - cache: {} - interruptible: true - retry: - max: 2 - when: - - runner_system_failure - - unknown_failure - - api_failure - -.kubernetes-env: - image: $CI_IMAGE - tags: - - kubernetes-parity-build - -.docker-env: - image: $CI_IMAGE - before_script: - - cargo -vV - - rustc -vV - - rustup show - - bash --version - rules: - - if: $CI_PIPELINE_SOURCE == "trigger" - - if: $CI_PIPELINE_SOURCE == "web" - - if: $CI_PIPELINE_SOURCE == "schedule" - - if: $CI_COMMIT_REF_NAME == "master" - - if: $CI_COMMIT_REF_NAME == "tags" - - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs - - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - tags: - - linux-docker - -#### stage: check - -check-clippy: - stage: check - extends: .docker-env - script: - - rustup component add clippy --toolchain stable-x86_64-unknown-linux-gnu - - time cargo +stable clippy --locked -- -Dwarnings - - time cargo +stable clippy --locked -p parity-scale-codec-derive -- -Dwarnings - - time cargo +stable clippy --locked --test clippy -- -Dwarnings - -check-rust-stable-no_derive_no_std: - stage: check - extends: .docker-env - variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - - time cargo +stable check --verbose --no-default-features --features bit-vec,bytes,generic-array - -check-rust-stable-no_std-chain-error: - stage: check - extends: .docker-env - variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - - time cargo +stable check --verbose --no-default-features --features chain-error - -check-rust-stable-no_derive: - stage: check - extends: .docker-env - variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - - time cargo +stable check --verbose --features bit-vec,bytes,generic-array - -check-rust-stable-only_mel: - stage: check - extends: .docker-env - variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - - time cargo +stable check --verbose --features max-encoded-len - -#### stage: test - -test-rust-stable: - stage: test - extends: .docker-env - variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - - time cargo +stable test --verbose --all --features bit-vec,bytes,generic-array,derive,max-encoded-len - -test-rust-stable-no_derive: - stage: test - extends: .docker-env - variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - - time cargo +stable test --verbose --features bit-vec,bytes,generic-array - -test-rust-stable-only_mel: - stage: test - extends: .docker-env - variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - - time cargo +stable test --verbose --features max-encoded-len - -test-rust-stable-only_mel-no_default_std: - stage: test - extends: .docker-env - variables: - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - - time cargo +stable test --verbose --features max-encoded-len,std --no-default-features - -bench-rust-nightly: - stage: test - extends: .docker-env - script: - - time cargo +nightly bench --features bit-vec,bytes,generic-array,derive - -miri: - stage: test - extends: .docker-env - variables: - RUST_BACKTRACE: 1 - MIRIFLAGS: "-Zmiri-disable-isolation" - script: - - time cargo +nightly miri test --features bit-vec,bytes,generic-array,arbitrary --release - -# check that build is no_std compatible -# more info: https://github.com/paritytech/parity-scale-codec/pull/389 -build-no-std: - stage: test - extends: .docker-env - variables: - RUST_BACKTRACE: 1 - script: - # this target doesn't support std envs; it should flag any unexpected uses of std - - rustup target add thumbv6m-none-eabi - - time cargo build --target thumbv6m-none-eabi --no-default-features - -build-no-atomic-ptrs: - stage: test - extends: .docker-env - variables: - RUST_BACKTRACE: 1 - script: - # this target doesn't have atomic ptrs. Some parts of alloc are not available there - # we want to make sure that this crate still works on those targets - - cargo +nightly check --target bpfel-unknown-none -Zbuild-std="core,alloc" --no-default-features --features generic-array,derive,max-encoded-len,chain-error - -#### stage: build - -build-linux-ubuntu-amd64: - stage: build - extends: .docker-env - rules: - - if: $CI_PIPELINE_SOURCE == "web" - - if: $CI_PIPELINE_SOURCE == "schedule" - - if: $CI_COMMIT_REF_NAME == "master" - - if: $CI_COMMIT_REF_NAME == "tags" - script: - - cargo build --verbose --release --features bit-vec,bytes,generic-array,derive - -#### stage: publish - -publish-dry-run: - stage: publish - extends: .kubernetes-env - # artificial dependency in order not to wait miri job - needs: - - job: check-clippy - artifacts: false - rules: - - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs - script: - - cargo publish -p parity-scale-codec --dry-run - -publish-crate: - stage: publish - extends: .kubernetes-env - rules: - - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - script: - - cargo publish -p parity-scale-codec From d36867087537e25040350155490deb720780fb03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 00:04:53 +0100 Subject: [PATCH 213/286] Bump trybuild from 1.0.85 to 1.0.86 (#549) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.85 to 1.0.86. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.85...1.0.86) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1cc056f2..659cf4e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1005,9 +1005,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196a58260a906cedb9bf6d8034b6379d0c11f552416960452f267402ceeddff1" +checksum = "8419ecd263363827c5730386f418715766f584e2f874d32c23c5b00bd9727e7e" dependencies = [ "basic-toml", "glob", diff --git a/Cargo.toml b/Cargo.toml index 4be178ad..3d983902 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.3.1" -trybuild = "1.0.85" +trybuild = "1.0.86" paste = "1" [[bench]] From cb5c4fce07822b46943dffb2aba5b4def480d713 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 23:40:54 +0100 Subject: [PATCH 214/286] Bump proc-macro2 from 1.0.70 to 1.0.73 (#553) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.70 to 1.0.73. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.70...1.0.73) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 659cf4e3..dee0ad96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -672,9 +672,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "2dd5e8a1f1029c43224ad5898e50140c2aebb1705f19e67c918ebf5b9e797fe1" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 12d2cd6a..ad89a245 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.33" -proc-macro2 = "1.0.70" +proc-macro2 = "1.0.73" proc-macro-crate = "2.0.1" [dev-dependencies] From d404bcf7cb170fa3f870deecc9d0d4f692ce7017 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 23:41:56 +0100 Subject: [PATCH 215/286] Bump quote from 1.0.33 to 1.0.34 (#552) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.33 to 1.0.34. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.33...1.0.34) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dee0ad96..cade6c1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -718,9 +718,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "22a37c9326af5ed140c86a46655b5278de879853be5573c01df185b6f49a580a" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index ad89a245..00437a55 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.33" +quote = "1.0.34" proc-macro2 = "1.0.73" proc-macro-crate = "2.0.1" From d7e35534de4fa369daf315cd3e190f4ddb016fc0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 22:26:42 +0100 Subject: [PATCH 216/286] Bump proc-macro2 from 1.0.73 to 1.0.74 (#554) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.73 to 1.0.74. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.73...1.0.74) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cade6c1e..68bbee48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -672,9 +672,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd5e8a1f1029c43224ad5898e50140c2aebb1705f19e67c918ebf5b9e797fe1" +checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 00437a55..673e52b0 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.34" -proc-macro2 = "1.0.73" +proc-macro2 = "1.0.74" proc-macro-crate = "2.0.1" [dev-dependencies] From ae31325ed390a18c4110aff8631ae1704ac6e9a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 00:22:14 +0100 Subject: [PATCH 217/286] Bump quote from 1.0.34 to 1.0.35 (#556) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.34 to 1.0.35. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.34...1.0.35) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68bbee48..ac72f569 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -718,9 +718,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a37c9326af5ed140c86a46655b5278de879853be5573c01df185b6f49a580a" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 673e52b0..26688a29 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.34" +quote = "1.0.35" proc-macro2 = "1.0.74" proc-macro-crate = "2.0.1" From 42e3a75e79b37fcd2a2626c5f4c012071a598795 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 19:57:39 +0100 Subject: [PATCH 218/286] Bump proc-macro-crate from 2.0.1 to 3.0.0 (#558) Bumps [proc-macro-crate](https://github.com/bkchr/proc-macro-crate) from 2.0.1 to 3.0.0. - [Release notes](https://github.com/bkchr/proc-macro-crate/releases) - [Commits](https://github.com/bkchr/proc-macro-crate/commits) --- updated-dependencies: - dependency-name: proc-macro-crate dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 13 ++++++------- derive/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac72f569..5e980fad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -662,11 +662,10 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" dependencies = [ - "toml_datetime", "toml_edit", ] @@ -988,15 +987,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap 2.0.2", "toml_datetime", diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 26688a29..61941a44 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.35" proc-macro2 = "1.0.74" -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" [dev-dependencies] parity-scale-codec = { path = "..", features = ["derive", "max-encoded-len"] } From 2ca4d1ced40c4dadcdeba467f17ab9b754072a23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 21:30:50 +0100 Subject: [PATCH 219/286] Bump proc-macro2 from 1.0.74 to 1.0.75 (#557) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.74 to 1.0.75. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.74...1.0.75) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e980fad..b9d8bc14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -671,9 +671,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.74" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" +checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 61941a44..561a4ab5 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.35" -proc-macro2 = "1.0.74" +proc-macro2 = "1.0.75" proc-macro-crate = "3.0.0" [dev-dependencies] From da3e93236ebd78617880d8e5015c531a84c98847 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 19:49:59 +0100 Subject: [PATCH 220/286] Bump serde from 1.0.193 to 1.0.194 (#559) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.193 to 1.0.194. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.193...v1.0.194) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 16 ++++++++-------- Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9d8bc14..2ed4189e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,7 +279,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.48", ] [[package]] @@ -890,22 +890,22 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.48", ] [[package]] @@ -932,9 +932,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 3d983902..7cafc3f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.193", default-features = false, optional = true } +serde = { version = "1.0.194", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 9c73bc52e4dd7fc8b3ef42a2a19f221ed946514f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 15:55:20 +0000 Subject: [PATCH 221/286] Bump serde from 1.0.194 to 1.0.195 (#561) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.194 to 1.0.195. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.194...v1.0.195) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ed4189e..93f1529a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -890,18 +890,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 7cafc3f7..76c7b274 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.194", default-features = false, optional = true } +serde = { version = "1.0.195", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From ca25960e9f290a7f946ab3e3ad909fa2e1eeb985 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 17:15:08 +0000 Subject: [PATCH 222/286] Bump proc-macro2 from 1.0.75 to 1.0.76 (#560) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.75 to 1.0.76. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.75...1.0.76) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93f1529a..1ee4e912 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -671,9 +671,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 561a4ab5..69933954 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.35" -proc-macro2 = "1.0.75" +proc-macro2 = "1.0.76" proc-macro-crate = "3.0.0" [dev-dependencies] From 805816af94e896cfbe863f6b61f421c4aae9be78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:19:03 +0000 Subject: [PATCH 223/286] Bump trybuild from 1.0.86 to 1.0.88 (#563) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.86 to 1.0.88. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.86...1.0.88) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ee4e912..0e86c2ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,9 +51,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "basic-toml" -version = "0.1.2" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" +checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" dependencies = [ "serde", ] @@ -910,9 +910,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.100" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -1004,9 +1004,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419ecd263363827c5730386f418715766f584e2f874d32c23c5b00bd9727e7e" +checksum = "76de4f783e610194f6c98bfd53f9fc52bb2e0d02c947621e8a0f4ecc799b2880" dependencies = [ "basic-toml", "glob", diff --git a/Cargo.toml b/Cargo.toml index 76c7b274..e2ae4857 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.3.1" -trybuild = "1.0.86" +trybuild = "1.0.88" paste = "1" [[bench]] From f85a1aa4d68f78a8c33cc7cab8b9e693b7a7b56c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 20:03:38 +0100 Subject: [PATCH 224/286] Bump trybuild from 1.0.88 to 1.0.89 (#566) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.88 to 1.0.89. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.88...1.0.89) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e86c2ee..8260e7f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1004,9 +1004,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76de4f783e610194f6c98bfd53f9fc52bb2e0d02c947621e8a0f4ecc799b2880" +checksum = "9a9d3ba662913483d6722303f619e75ea10b7855b0f8e0d72799cf8621bb488f" dependencies = [ "basic-toml", "glob", diff --git a/Cargo.toml b/Cargo.toml index e2ae4857..90d2dab9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.3.1" -trybuild = "1.0.88" +trybuild = "1.0.89" paste = "1" [[bench]] From 6d735960638cff48d8a9941f8c16bd9bdc13b671 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:14:16 +0100 Subject: [PATCH 225/286] Bump proc-macro-crate from 3.0.0 to 3.1.0 (#567) Bumps [proc-macro-crate](https://github.com/bkchr/proc-macro-crate) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/bkchr/proc-macro-crate/releases) - [Commits](https://github.com/bkchr/proc-macro-crate/commits) --- updated-dependencies: - dependency-name: proc-macro-crate dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8260e7f6..4a922c52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -662,9 +662,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ "toml_edit", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 69933954..c6c635ae 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.35" proc-macro2 = "1.0.76" -proc-macro-crate = "3.0.0" +proc-macro-crate = "3.1.0" [dev-dependencies] parity-scale-codec = { path = "..", features = ["derive", "max-encoded-len"] } From b8ce1f57e07f980f0ed126cf8e64d65c82cab06a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:45:26 +0100 Subject: [PATCH 226/286] Bump proc-macro2 from 1.0.76 to 1.0.78 (#568) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.76 to 1.0.78. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.76...1.0.78) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a922c52..e20c9ddb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -671,9 +671,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index c6c635ae..d90a4ed2 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.35" -proc-macro2 = "1.0.76" +proc-macro2 = "1.0.78" proc-macro-crate = "3.1.0" [dev-dependencies] From 8c3cc7f2311c8ea7522f4edc21d9cf1f7b661519 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 20:12:04 +0100 Subject: [PATCH 227/286] Bump serde from 1.0.195 to 1.0.196 (#570) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.195 to 1.0.196. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.195...v1.0.196) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e20c9ddb..ff4bf282 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -890,18 +890,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 90d2dab9..bba01533 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.195", default-features = false, optional = true } +serde = { version = "1.0.196", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From a1c9b026a6d6a5ed7f1eebbf7aeb97177420abc6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:21:38 +0100 Subject: [PATCH 228/286] Bump serde from 1.0.196 to 1.0.197 (#571) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.196 to 1.0.197. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.196...v1.0.197) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff4bf282..93be738a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -890,18 +890,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index bba01533..91aead1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.196", default-features = false, optional = true } +serde = { version = "1.0.197", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From c77ea40deba68f134bacaa093985abd7bf9aab54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 14:32:51 +0100 Subject: [PATCH 229/286] Bump proc-macro2 from 1.0.78 to 1.0.79 (#572) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.78 to 1.0.79. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.78...1.0.79) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93be738a..d1e1efbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -671,9 +671,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index d90a4ed2..4f8a8760 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.35" -proc-macro2 = "1.0.78" +proc-macro2 = "1.0.79" proc-macro-crate = "3.1.0" [dev-dependencies] From ca68d2edbe3c3b1bfcb2272202c62eb80d146195 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:43:16 +0100 Subject: [PATCH 230/286] Bump trybuild from 1.0.89 to 1.0.90 (#573) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.89 to 1.0.90. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.89...1.0.90) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 65 ++++++++++++++++++++++++++++++++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1e1efbb..d4b15121 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,15 +49,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "basic-toml" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" -dependencies = [ - "serde", -] - [[package]] name = "bit-set" version = "0.5.3" @@ -666,7 +657,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit", + "toml_edit 0.21.0", ] [[package]] @@ -919,6 +910,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "syn" version = "1.0.98" @@ -985,11 +985,26 @@ dependencies = [ "serde_json", ] +[[package]] +name = "toml" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af06656561d28735e9c1cd63dfd57132c8155426aa6af24f36a00a351f88c48e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.7", +] + [[package]] name = "toml_datetime" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -999,22 +1014,35 @@ checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap 2.0.2", "toml_datetime", - "winnow", + "winnow 0.5.17", +] + +[[package]] +name = "toml_edit" +version = "0.22.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992" +dependencies = [ + "indexmap 2.0.2", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.5", ] [[package]] name = "trybuild" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9d3ba662913483d6722303f619e75ea10b7855b0f8e0d72799cf8621bb488f" +checksum = "2aa6f84ec205ebf87fb7a0abdbcd1467fa5af0e86878eb6d888b78ecbb10b6d5" dependencies = [ - "basic-toml", "glob", "once_cell", "serde", "serde_derive", "serde_json", "termcolor", + "toml", ] [[package]] @@ -1303,6 +1331,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + [[package]] name = "wyz" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 91aead1e..b62c684f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.3.1" -trybuild = "1.0.89" +trybuild = "1.0.90" paste = "1" [[bench]] From 0eb6d82f619c0a296b3a2fe37a39dbd74ba7df99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 17:25:54 +0000 Subject: [PATCH 231/286] Bump bytes from 1.5.0 to 1.6.0 (#574) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.5.0 to 1.6.0. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.5.0...v1.6.0) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4b15121..0ef0ac97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,9 +102,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cast" From 42db790aba1f5fba57ac47153353967c94a8d240 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 00:07:34 +0200 Subject: [PATCH 232/286] Bump trybuild from 1.0.90 to 1.0.91 (#577) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.90 to 1.0.91. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.90...1.0.91) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ef0ac97..0a001f46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1032,9 +1032,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aa6f84ec205ebf87fb7a0abdbcd1467fa5af0e86878eb6d888b78ecbb10b6d5" +checksum = "8ad7eb6319ebadebca3dacf1f85a93bc54b73dd81b9036795f73de7ddfe27d5a" dependencies = [ "glob", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index b62c684f..50631cb1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.3.1" -trybuild = "1.0.90" +trybuild = "1.0.91" paste = "1" [[bench]] From f70e66b42db6232b80f20ee254331f712d7ccc75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 23:54:28 +0200 Subject: [PATCH 233/286] Bump quote from 1.0.35 to 1.0.36 (#578) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.35 to 1.0.36. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.35...1.0.36) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a001f46..823f9357 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -708,9 +708,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 4f8a8760..419450ec 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.35" +quote = "1.0.36" proc-macro2 = "1.0.79" proc-macro-crate = "3.1.0" From 9c11cfceb29fbd6bd4d6cb057ba443c64dccaa92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 00:23:45 +0200 Subject: [PATCH 234/286] Bump serde from 1.0.197 to 1.0.198 (#580) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.197 to 1.0.198. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.197...v1.0.198) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 823f9357..208fb750 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -881,18 +881,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 50631cb1..8cffd487 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.197", default-features = false, optional = true } +serde = { version = "1.0.198", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 5f4fb36df6b146dfa5417018ae831f92bab17400 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 00:24:14 +0200 Subject: [PATCH 235/286] Bump proc-macro2 from 1.0.79 to 1.0.81 (#581) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.79 to 1.0.81. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.79...1.0.81) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 208fb750..aaae82f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -662,9 +662,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 419450ec..f0c8bb59 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.36" -proc-macro2 = "1.0.79" +proc-macro2 = "1.0.81" proc-macro-crate = "3.1.0" [dev-dependencies] From 94cfe52b378a15e2cd10764572c09e9c8b2fdbbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 23:03:05 +0200 Subject: [PATCH 236/286] Bump serde from 1.0.198 to 1.0.199 (#584) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.198 to 1.0.199. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.198...v1.0.199) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aaae82f6..99b8867d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -881,18 +881,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.198" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.198" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 8cffd487..22317957 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.198", default-features = false, optional = true } +serde = { version = "1.0.199", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From faac8ccd595f2c05eb29c79995dc02beeb19422d Mon Sep 17 00:00:00 2001 From: Alexander Kalankhodzhaev Date: Tue, 30 Apr 2024 20:07:56 +0700 Subject: [PATCH 237/286] Source code formatting (#583) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * style: apply formatting * ci: add cargo fmt check * Update derive/src/decode.rs --------- Co-authored-by: Bastian Köcher --- .github/workflows/ci.yml | 14 ++ benches/benches.rs | 160 +++++++------ derive/src/decode.rs | 77 +++--- derive/src/encode.rs | 10 +- derive/src/lib.rs | 20 +- derive/src/max_encoded_len.rs | 2 +- derive/src/trait_bounds.rs | 6 +- derive/src/utils.rs | 16 +- fuzzer/src/main.rs | 55 +++-- src/bit_vec.rs | 29 ++- src/codec.rs | 328 ++++++++++++++------------ src/compact.rs | 241 +++++++++++++------ src/const_encoded_len.rs | 24 +- src/decode_all.rs | 4 +- src/encode_append.rs | 56 +++-- src/encode_like.rs | 15 +- src/generic_array.rs | 6 +- src/joiner.rs | 5 +- src/keyedvec.rs | 3 +- src/lib.rs | 64 +++-- src/max_encoded_len.rs | 46 +++- tests/chain-error.rs | 21 +- tests/max_encoded_len.rs | 6 +- tests/mod.rs | 10 +- tests/single_field_struct_encoding.rs | 10 +- tests/skip.rs | 24 +- tests/type_inference.rs | 7 +- tests/variant_number.rs | 2 +- 28 files changed, 709 insertions(+), 552 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 573ce99f..da548f02 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,20 @@ jobs: run: echo "IMAGE=${{ env.IMAGE }}" >> $GITHUB_OUTPUT # Checks + fmt: + runs-on: ubuntu-latest + needs: [set-image] + container: ${{ needs.set-image.outputs.IMAGE }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Show Cargo version + run: cargo +nightly -vV + + - name: Cargo fmt + run: cargo +nightly fmt --all -- --check + clippy: runs-on: ubuntu-latest needs: [set-image] diff --git a/benches/benches.rs b/benches/benches.rs index 902be9e0..16d225fa 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -12,21 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{time::Duration, any::type_name, convert::{TryFrom, TryInto}}; +use std::{ + any::type_name, + convert::{TryFrom, TryInto}, + time::Duration, +}; #[cfg(feature = "bit-vec")] -use bitvec::{vec::BitVec, order::Lsb0}; -use criterion::{Criterion, black_box, Bencher, criterion_group, criterion_main}; +use bitvec::{order::Lsb0, vec::BitVec}; +use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion}; use parity_scale_codec::*; -use parity_scale_codec_derive::{Encode, Decode}; +use parity_scale_codec_derive::{Decode, Encode}; fn array_vec_write_u128(b: &mut Bencher) { b.iter(|| { for b in 0..black_box(1_000_000) { let a = 0xffff_ffff_ffff_ffff_ffff_u128; - Compact(a ^ b).using_encoded(|x| { - black_box(x).len() - }); + Compact(a ^ b).using_encoded(|x| black_box(x).len()); } }); } @@ -84,8 +86,7 @@ fn vec_append_with_decode_and_encode(b: &mut Bencher) { b.iter(|| { let mut encoded_events_vec = Vec::new(); for _ in 0..1000 { - let mut events = Vec::::decode(&mut &encoded_events_vec[..]) - .unwrap_or_default(); + let mut events = Vec::::decode(&mut &encoded_events_vec[..]).unwrap_or_default(); events.push(Event::ComplexEvent(data.to_vec(), 4, 5, 6, 9)); @@ -107,62 +108,69 @@ fn vec_append_with_encode_append(b: &mut Bencher) { encoded_events_vec = as EncodeAppend>::append_or_new( encoded_events_vec, &[Event::ComplexEvent(data.to_vec(), 4, 5, 6, 9)], - ).unwrap(); + ) + .unwrap(); } }); } -fn encode_decode_vec + Codec>(c: &mut Criterion) where T::Error: std::fmt::Debug { +fn encode_decode_vec + Codec>(c: &mut Criterion) +where + T::Error: std::fmt::Debug, +{ let mut g = c.benchmark_group("vec_encode"); for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { - g.bench_with_input(&format!("{}/{}", type_name::(), vec_size), &vec_size, |b, &vec_size| { - let vec: Vec = (0..=127u8) - .cycle() - .take(vec_size) - .map(|v| v.try_into().unwrap()) - .collect(); - - let vec = black_box(vec); - b.iter(|| vec.encode()) - }); + g.bench_with_input( + &format!("{}/{}", type_name::(), vec_size), + &vec_size, + |b, &vec_size| { + let vec: Vec = + (0..=127u8).cycle().take(vec_size).map(|v| v.try_into().unwrap()).collect(); + + let vec = black_box(vec); + b.iter(|| vec.encode()) + }, + ); } drop(g); let mut g = c.benchmark_group("vec_decode"); for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { - g.bench_with_input(&format!("{}/{}", type_name::(), vec_size), &vec_size, |b, &vec_size| { - let vec: Vec = (0..=127u8) - .cycle() - .take(vec_size) - .map(|v| v.try_into().unwrap()) - .collect(); - - let vec = vec.encode(); - - let vec = black_box(vec); - b.iter(|| { - let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); - }) - }); + g.bench_with_input( + &format!("{}/{}", type_name::(), vec_size), + &vec_size, + |b, &vec_size| { + let vec: Vec = + (0..=127u8).cycle().take(vec_size).map(|v| v.try_into().unwrap()).collect(); + + let vec = vec.encode(); + + let vec = black_box(vec); + b.iter(|| { + let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); + }) + }, + ); } drop(g); let mut g = c.benchmark_group("vec_decode_no_limit"); for vec_size in [16384, 131072] { - g.bench_with_input(&format!("vec_decode_no_limit_{}/{}", type_name::(), vec_size), &vec_size, |b, &vec_size| { - let vec: Vec = (0..=127u8) - .cycle() - .take(vec_size) - .map(|v| v.try_into().unwrap()) - .collect(); - - let vec = vec.encode(); - - let vec = black_box(vec); - b.iter(|| { - let _: Vec = Decode::decode(&mut NoLimitInput(&vec[..])).unwrap(); - }) - }); + g.bench_with_input( + &format!("vec_decode_no_limit_{}/{}", type_name::(), vec_size), + &vec_size, + |b, &vec_size| { + let vec: Vec = + (0..=127u8).cycle().take(vec_size).map(|v| v.try_into().unwrap()).collect(); + + let vec = vec.encode(); + + let vec = black_box(vec); + b.iter(|| { + let _: Vec = Decode::decode(&mut NoLimitInput(&vec[..])).unwrap(); + }) + }, + ); } } @@ -183,28 +191,38 @@ fn encode_decode_complex_type(c: &mut Criterion) { let mut g = c.benchmark_group("vec_encode_complex_type"); for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { let complex_types = complex_types.clone(); - g.bench_with_input(format!("vec_encode_complex_type/{}", vec_size), &vec_size, move |b, &vec_size| { - let vec: Vec = complex_types.clone().into_iter().cycle().take(vec_size).collect(); + g.bench_with_input( + format!("vec_encode_complex_type/{}", vec_size), + &vec_size, + move |b, &vec_size| { + let vec: Vec = + complex_types.clone().into_iter().cycle().take(vec_size).collect(); - let vec = black_box(vec); - b.iter(|| vec.encode()) - }); + let vec = black_box(vec); + b.iter(|| vec.encode()) + }, + ); } drop(g); let mut g = c.benchmark_group("vec_decode_complex_type"); for vec_size in [1, 2, 5, 32, 1024, 2048, 16384] { let complex_types = complex_types.clone(); - g.bench_with_input(format!("vec_decode_complex_type/{}", vec_size), &vec_size, move |b, &vec_size| { - let vec: Vec = complex_types.clone().into_iter().cycle().take(vec_size).collect(); + g.bench_with_input( + format!("vec_decode_complex_type/{}", vec_size), + &vec_size, + move |b, &vec_size| { + let vec: Vec = + complex_types.clone().into_iter().cycle().take(vec_size).collect(); - let vec = vec.encode(); + let vec = vec.encode(); - let vec = black_box(vec); - b.iter(|| { - let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); - }) - }); + let vec = black_box(vec); + b.iter(|| { + let _: Vec = Decode::decode(&mut &vec[..]).unwrap(); + }) + }, + ); } } @@ -225,12 +243,8 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { let mut g = c.benchmark_group("bitvec_u8_encode"); for size in [1, 2, 5, 32, 1024] { g.bench_with_input(size.to_string(), &size, |b, &size| { - let vec: BitVec = [true, false] - .iter() - .cloned() - .cycle() - .take(size) - .collect(); + let vec: BitVec = + [true, false].iter().cloned().cycle().take(size).collect(); let vec = black_box(vec); b.iter(|| vec.encode()) @@ -243,12 +257,8 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { let mut g = c.benchmark_group("bitvec_u8_decode"); for size in [1, 2, 5, 32, 1024] { g.bench_with_input(size.to_string(), &size, |b, &size| { - let vec: BitVec = [true, false] - .iter() - .cloned() - .cycle() - .take(size) - .collect(); + let vec: BitVec = + [true, false].iter().cloned().cycle().take(size).collect(); let vec = vec.encode(); @@ -261,7 +271,7 @@ fn encode_decode_bitvec_u8(c: &mut Criterion) { } } -criterion_group!{ +criterion_group! { name = benches; config = Criterion::default().warm_up_time(Duration::from_millis(500)).without_plots(); targets = encode_decode_vec::, encode_decode_vec::, encode_decode_vec::, encode_decode_vec::, diff --git a/derive/src/decode.rs b/derive/src/decode.rs index 38d5565a..7f2d08b2 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -12,11 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use proc_macro2::{Span, TokenStream, Ident}; -use syn::{ - spanned::Spanned, - Data, Fields, Field, Error, -}; +use proc_macro2::{Ident, Span, TokenStream}; +use syn::{spanned::Spanned, Data, Error, Field, Fields}; use crate::utils; @@ -49,13 +46,15 @@ pub fn quote( }, }, Data::Enum(ref data) => { - let data_variants = || data.variants.iter().filter(|variant| !utils::should_skip(&variant.attrs)); + let data_variants = + || data.variants.iter().filter(|variant| !utils::should_skip(&variant.attrs)); if data_variants().count() > 256 { return Error::new( data.variants.span(), - "Currently only enums with at most 256 variants are encodable." - ).to_compile_error(); + "Currently only enums with at most 256 variants are encodable.", + ) + .to_compile_error(); } let recurse = data_variants().enumerate().map(|(i, v)| { @@ -84,14 +83,10 @@ pub fn quote( } }); - let read_byte_err_msg = format!( - "Could not decode `{}`, failed to read variant byte", - type_name, - ); - let invalid_variant_err_msg = format!( - "Could not decode `{}`, variant doesn't exist", - type_name, - ); + let read_byte_err_msg = + format!("Could not decode `{type_name}`, failed to read variant byte"); + let invalid_variant_err_msg = + format!("Could not decode `{type_name}`, variant doesn't exist"); quote! { match #input.read_byte() .map_err(|e| e.chain(#read_byte_err_msg))? @@ -107,9 +102,9 @@ pub fn quote( }, } } - }, - Data::Union(_) => Error::new(Span::call_site(), "Union types are not supported.").to_compile_error(), + Data::Union(_) => + Error::new(Span::call_site(), "Union types are not supported.").to_compile_error(), } } @@ -117,7 +112,7 @@ pub fn quote_decode_into( data: &Data, crate_path: &syn::Path, input: &TokenStream, - attrs: &[syn::Attribute] + attrs: &[syn::Attribute], ) -> Option { // Make sure the type is `#[repr(transparent)]`, as this guarantees that // there can be only one field that is not zero-sized. @@ -126,16 +121,13 @@ pub fn quote_decode_into( } let fields = match data { - Data::Struct( - syn::DataStruct { - fields: Fields::Named(syn::FieldsNamed { named: fields, .. }) | - Fields::Unnamed(syn::FieldsUnnamed { unnamed: fields, .. }), - .. - } - ) => { - fields - }, - _ => return None + Data::Struct(syn::DataStruct { + fields: + Fields::Named(syn::FieldsNamed { named: fields, .. }) | + Fields::Unnamed(syn::FieldsUnnamed { unnamed: fields, .. }), + .. + }) => fields, + _ => return None, }; if fields.is_empty() { @@ -143,11 +135,11 @@ pub fn quote_decode_into( } // Bail if there are any extra attributes which could influence how the type is decoded. - if fields.iter().any(|field| + if fields.iter().any(|field| { utils::get_encoded_as_type(field).is_some() || - utils::is_compact(field) || - utils::should_skip(&field.attrs) - ) { + utils::is_compact(field) || + utils::should_skip(&field.attrs) + }) { return None; } @@ -183,10 +175,11 @@ pub fn quote_decode_into( if !non_zst_field_count.is_empty() { non_zst_field_count.push(quote! { + }); } - non_zst_field_count.push(quote! { if ::core::mem::size_of::<#field_type>() > 0 { 1 } else { 0 } }); + non_zst_field_count + .push(quote! { if ::core::mem::size_of::<#field_type>() > 0 { 1 } else { 0 } }); } - Some(quote!{ + Some(quote! { // Just a sanity check. These should always be true and will be optimized-out. ::core::assert_eq!(#(#sizes)*, ::core::mem::size_of::()); ::core::assert!(#(#non_zst_field_count)* <= 1); @@ -198,7 +191,12 @@ pub fn quote_decode_into( }) } -fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_path: &syn::Path) -> TokenStream { +fn create_decode_expr( + field: &Field, + name: &str, + input: &TokenStream, + crate_path: &syn::Path, +) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); let compact = utils::is_compact(field); let skip = utils::should_skip(&field.attrs); @@ -208,8 +206,9 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_path if encoded_as.is_some() as u8 + compact as u8 + skip as u8 > 1 { return Error::new( field.span(), - "`encoded_as`, `compact` and `skip` can only be used one at a time!" - ).to_compile_error(); + "`encoded_as`, `compact` and `skip` can only be used one at a time!", + ) + .to_compile_error(); } let err_msg = format!("Could not decode `{}`", name); @@ -282,7 +281,7 @@ fn create_instance( } }, Fields::Unnamed(ref fields) => { - let recurse = fields.unnamed.iter().enumerate().map(|(i, f) | { + let recurse = fields.unnamed.iter().enumerate().map(|(i, f)| { let field_name = format!("{}.{}", name_str, i); create_decode_expr(f, &field_name, input, crate_path) diff --git a/derive/src/encode.rs b/derive/src/encode.rs index e1ec680c..a29eec78 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -35,7 +35,7 @@ fn encode_single_field( Span::call_site(), "Internal error: cannot encode single field optimisation if skipped", ) - .to_compile_error() + .to_compile_error(); } if encoded_as.is_some() && compact { @@ -43,7 +43,7 @@ fn encode_single_field( Span::call_site(), "`encoded_as` and `compact` can not be used at the same time!", ) - .to_compile_error() + .to_compile_error(); } let final_field_variable = if compact { @@ -128,7 +128,7 @@ where f.span(), "`encoded_as`, `compact` and `skip` can only be used one at a time!", ) - .to_compile_error() + .to_compile_error(); } // Based on the seen attribute, we call a handler that generates code for a specific @@ -306,12 +306,12 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenS data.variants.span(), "Currently only enums with at most 256 variants are encodable.", ) - .to_compile_error() + .to_compile_error(); } // If the enum has no variants, we don't need to encode anything. if data_variants().count() == 0 { - return quote!() + return quote!(); } let recurse = data_variants().enumerate().map(|(i, f)| { diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 3c868e27..47c26dc4 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -129,7 +129,7 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream }; if let Err(e) = utils::check_attributes(&input) { - return e.to_compile_error().into() + return e.to_compile_error().into(); } let crate_path = match codec_crate_path(&input.attrs) { @@ -147,7 +147,7 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream utils::has_dumb_trait_bound(&input.attrs), &crate_path, ) { - return e.to_compile_error().into() + return e.to_compile_error().into(); } let name = &input.ident; @@ -179,7 +179,7 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream }; if let Err(e) = utils::check_attributes(&input) { - return e.to_compile_error().into() + return e.to_compile_error().into(); } let crate_path = match codec_crate_path(&input.attrs) { @@ -197,7 +197,7 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream utils::has_dumb_trait_bound(&input.attrs), &crate_path, ) { - return e.to_compile_error().into() + return e.to_compile_error().into(); } let name = &input.ident; @@ -208,12 +208,8 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream let decoding = decode::quote(&input.data, name, "e!(#ty_gen_turbofish), &input_, &crate_path); - let decode_into_body = decode::quote_decode_into( - &input.data, - &crate_path, - &input_, - &input.attrs - ); + let decode_into_body = + decode::quote_decode_into(&input.data, &crate_path, &input_, &input.attrs); let impl_decode_into = if let Some(body) = decode_into_body { quote! { @@ -266,7 +262,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr }; if let Err(e) = utils::check_attributes(&input) { - return e.to_compile_error().into() + return e.to_compile_error().into(); } let crate_path = match codec_crate_path(&input.attrs) { @@ -284,7 +280,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr utils::has_dumb_trait_bound(&input.attrs), &crate_path, ) { - return e.to_compile_error().into() + return e.to_compile_error().into(); } let name = &input.ident; diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index 763e8ceb..008ffd28 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -45,7 +45,7 @@ pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::Tok has_dumb_trait_bound(&input.attrs), &crate_path, ) { - return e.to_compile_error().into() + return e.to_compile_error().into(); } let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index f803990d..209e1bf6 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -55,7 +55,7 @@ impl<'a, 'ast> Visit<'ast> for TypePathStartsWithIdent<'a> { if let Some(segment) = i.path.segments.first() { if &segment.ident == self.ident { self.result = true; - return + return; } } @@ -119,7 +119,7 @@ pub fn add( let skip_type_params = match custom_trait_bound { Some(CustomTraitBound::SpecifiedBounds { bounds, .. }) => { generics.make_where_clause().predicates.extend(bounds); - return Ok(()) + return Ok(()); }, Some(CustomTraitBound::SkipTypeParams { type_names, .. }) => type_names.into_iter().collect::>(), @@ -132,7 +132,7 @@ pub fn add( .map(|tp| tp.ident.clone()) .collect::>(); if ty_params.is_empty() { - return Ok(()) + return Ok(()); } let codec_types = diff --git a/derive/src/utils.rs b/derive/src/utils.rs index 5a2fa45d..091a45ee 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -20,7 +20,7 @@ use std::str::FromStr; use proc_macro2::TokenStream; -use quote::{ToTokens, quote}; +use quote::{quote, ToTokens}; use syn::{ parse::Parse, punctuated::Punctuated, spanned::Spanned, token, Attribute, Data, DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, MetaNameValue, NestedMeta, Path, Variant, @@ -48,7 +48,7 @@ pub fn variant_index(v: &Variant, i: usize) -> TokenStream { let byte = v .base10_parse::() .expect("Internal error, index attribute must have been checked"); - return Some(byte) + return Some(byte); } } } @@ -75,7 +75,7 @@ pub fn get_encoded_as_type(field: &Field) -> Option { return Some( TokenStream::from_str(&s.value()) .expect("Internal error, encoded_as attribute must have been checked"), - ) + ); } } } @@ -89,7 +89,7 @@ pub fn is_compact(field: &Field) -> bool { find_meta_item(field.attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("compact") { - return Some(()) + return Some(()); } } @@ -103,7 +103,7 @@ pub fn should_skip(attrs: &[Attribute]) -> bool { find_meta_item(attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("skip") { - return Some(path.span()) + return Some(path.span()); } } @@ -117,7 +117,7 @@ pub fn has_dumb_trait_bound(attrs: &[Attribute]) -> bool { find_meta_item(attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("dumb_trait_bound") { - return Some(()) + return Some(()); } } @@ -262,9 +262,7 @@ pub fn filter_skip_named(fields: &syn::FieldsNamed) -> impl Iterator impl Iterator { +pub fn filter_skip_unnamed(fields: &syn::FieldsUnnamed) -> impl Iterator { fields.unnamed.iter().enumerate().filter(|(_, f)| !should_skip(&f.attrs)) } diff --git a/fuzzer/src/main.rs b/fuzzer/src/main.rs index 8463d74e..fba804c9 100644 --- a/fuzzer/src/main.rs +++ b/fuzzer/src/main.rs @@ -1,28 +1,37 @@ -use std::collections::{BTreeMap, BTreeSet, VecDeque, LinkedList, BinaryHeap}; -use std::time::Duration; +use std::{ + collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque}, + time::Duration, +}; -use bitvec::{vec::BitVec, order::Msb0, order::BitOrder, store::BitStore}; -use honggfuzz::fuzz; -use parity_scale_codec::{Encode, Decode, Compact}; -use honggfuzz::arbitrary::{Arbitrary, Unstructured, Result as ArbResult}; +use bitvec::{ + order::{BitOrder, Msb0}, + store::BitStore, + vec::BitVec, +}; +use honggfuzz::{ + arbitrary::{Arbitrary, Result as ArbResult, Unstructured}, + fuzz, +}; +use parity_scale_codec::{Compact, Decode, Encode}; #[derive(Encode, Decode, Clone, PartialEq, Debug, Arbitrary)] -pub struct MockStruct{ - vec_u: Vec +pub struct MockStruct { + vec_u: Vec, } /// Used for implementing the Arbitrary trait for a BitVec. #[derive(Encode, Decode, Clone, PartialEq, Debug)] pub struct BitVecWrapper(BitVec); -impl<'a, O: 'static + BitOrder, T: 'static + BitStore + Arbitrary<'a>> Arbitrary<'a> for BitVecWrapper { +impl<'a, O: 'static + BitOrder, T: 'static + BitStore + Arbitrary<'a>> Arbitrary<'a> + for BitVecWrapper +{ fn arbitrary(u: &mut Unstructured<'a>) -> ArbResult { let v = Vec::::arbitrary(u)?; Ok(BitVecWrapper(BitVec::::from_vec(v))) } } - /// Used for implementing the PartialEq trait for a BinaryHeap. #[derive(Encode, Decode, Debug, Clone, Arbitrary)] struct BinaryHeapWrapper(BinaryHeap); @@ -38,19 +47,16 @@ pub enum MockEnum { Empty, Unit(u32), UnitVec(Vec), - Complex { - data: Vec, - bitvec: BitVecWrapper, - string: String, - }, + Complex { data: Vec, bitvec: BitVecWrapper, string: String }, Mock(MockStruct), NestedVec(Vec>>>>>>>>), } /// `fuzz_flow` parameter can either be `round_trip` or `only_decode`. -/// `round_trip` will decode -> encode and compare the obtained encoded bytes with the original data. -/// `only_decode` will only decode, without trying to encode the decoded object. -/// `round_trip_sort` will decode -> encode and compare the obtained encoded SORTED bytes with the original SORTED data. +/// `round_trip` will decode -> encode and compare the obtained encoded bytes with the original +/// data. `only_decode` will only decode, without trying to encode the decoded object. +/// `round_trip_sort` will decode -> encode and compare the obtained encoded SORTED bytes with the +/// original SORTED data. macro_rules! fuzz_decoder { ( $fuzz_flow:ident; @@ -253,23 +259,22 @@ macro_rules! fuzz_encoder { }; } -fn fuzz_encode (data: T) { +fn fuzz_encode(data: T) { let original = data.clone(); let mut obj: &[u8] = &data.encode(); let decoded = ::decode(&mut obj); match decoded { - Ok(object) => { + Ok(object) => if object != original { println!("original object: {:?}", original); println!("decoded object: {:?}", object); panic!("Original object differs from decoded object") - } - } + }, Err(e) => { println!("original object: {:?}", original); println!("decoding error: {:?}", e); panic!("Failed to decode the encoded object"); - } + }, } } @@ -308,7 +313,9 @@ macro_rules! fuzz_encoding { fn main() { loop { - fuzz!(|data: &[u8]| { fuzz_decode(data); }); + fuzz!(|data: &[u8]| { + fuzz_decode(data); + }); fuzz_encoding!(); } } diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 4f0f84b5..c4a00669 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -14,11 +14,11 @@ //! `BitVec` specific serialization. -use bitvec::{ - vec::BitVec, store::BitStore, order::BitOrder, slice::BitSlice, boxed::BitBox, view::BitView, -}; use crate::{ - EncodeLike, Encode, Decode, Input, Output, Error, Compact, codec::decode_vec_with_len, + codec::decode_vec_with_len, Compact, Decode, Encode, EncodeLike, Error, Input, Output, +}; +use bitvec::{ + boxed::BitBox, order::BitOrder, slice::BitSlice, store::BitStore, vec::BitVec, view::BitView, }; impl Encode for BitSlice { @@ -59,12 +59,13 @@ impl Decode for BitVec { } let vec = decode_vec_with_len(input, bitvec::mem::elts::(bits as usize))?; - let mut result = Self::try_from_vec(vec) - .map_err(|_| { - Error::from("UNEXPECTED ERROR: `bits` is less or equal to + let mut result = Self::try_from_vec(vec).map_err(|_| { + Error::from( + "UNEXPECTED ERROR: `bits` is less or equal to `ARCH32BIT_BITSLICE_MAX_BITS`; So BitVec must be able to handle the number of - segment needed for `bits` to be represented; qed") - })?; + segment needed for `bits` to be represented; qed", + ) + })?; assert!(bits as usize <= result.len()); result.truncate(bits as usize); @@ -90,8 +91,11 @@ impl Decode for BitBox { #[cfg(test)] mod tests { use super::*; - use bitvec::{bitvec, order::{Msb0, Lsb0}}; use crate::{codec::MAX_PREALLOCATION, CompactLen}; + use bitvec::{ + bitvec, + order::{Lsb0, Msb0}, + }; macro_rules! test_data { ($inner_type:ident) => ( @@ -202,7 +206,10 @@ mod tests { (bitvec![u8, Lsb0; 1, 1, 1, 1].encode(), (Compact(4u32), 0b00001111u8).encode()), (bitvec![u8, Lsb0; 1, 1, 1, 1, 1].encode(), (Compact(5u32), 0b00011111u8).encode()), (bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 0].encode(), (Compact(6u32), 0b00011111u8).encode()), - (bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1].encode(), (Compact(12u32), 0b00011111u8, 0b00001011u8).encode()), + ( + bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1].encode(), + (Compact(12u32), 0b00011111u8, 0b00001011u8).encode(), + ), ]; for (idx, (actual, expected)) in cases.into_iter().enumerate() { diff --git a/src/codec.rs b/src/codec.rs index 08f4640b..6beebad2 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -14,49 +14,38 @@ //! Serialization. -use core::fmt; use core::{ convert::TryFrom, + fmt, iter::FromIterator, marker::PhantomData, mem, - mem::{ - MaybeUninit, + mem::MaybeUninit, + num::{ + NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16, + NonZeroU32, NonZeroU64, NonZeroU8, }, ops::{Deref, Range, RangeInclusive}, time::Duration, }; -use core::num::{ - NonZeroI8, - NonZeroI16, - NonZeroI32, - NonZeroI64, - NonZeroI128, - NonZeroU8, - NonZeroU16, - NonZeroU32, - NonZeroU64, - NonZeroU128, -}; use byte_slice_cast::{AsByteSlice, AsMutByteSlice, ToMutByteSlice}; #[cfg(target_has_atomic = "ptr")] use crate::alloc::sync::Arc; -use crate::alloc::{ - boxed::Box, - borrow::{Cow, ToOwned}, - collections::{ - BTreeMap, BTreeSet, VecDeque, LinkedList, BinaryHeap +use crate::{ + alloc::{ + borrow::{Cow, ToOwned}, + boxed::Box, + collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque}, + rc::Rc, + string::String, + vec::Vec, }, - rc::Rc, - string::String, - vec::Vec, + compact::Compact, + encode_like::EncodeLike, + DecodeFinished, Error, }; -use crate::compact::Compact; -use crate::DecodeFinished; -use crate::encode_like::EncodeLike; -use crate::Error; pub(crate) const MAX_PREALLOCATION: usize = 4 * 1024; const A_BILLION: u32 = 1_000_000_000; @@ -101,7 +90,10 @@ pub trait Input { /// Decodes a `bytes::Bytes`. #[cfg(feature = "bytes")] #[doc(hidden)] - fn scale_internal_decode_bytes(&mut self) -> Result where Self: Sized { + fn scale_internal_decode_bytes(&mut self) -> Result + where + Self: Sized, + { Vec::::decode(self).map(bytes::Bytes::from) } } @@ -186,18 +178,20 @@ impl Output for Vec { #[cfg(feature = "std")] impl Output for W { fn write(&mut self, bytes: &[u8]) { - (self as &mut dyn std::io::Write).write_all(bytes).expect("Codec outputs are infallible"); + (self as &mut dyn std::io::Write) + .write_all(bytes) + .expect("Codec outputs are infallible"); } } - /// !INTERNAL USE ONLY! /// /// This enum provides type information to optimize encoding/decoding by doing fake specialization. #[doc(hidden)] #[non_exhaustive] pub enum TypeInfo { - /// Default value of [`Encode::TYPE_INFO`] to not require implementors to set this value in the trait. + /// Default value of [`Encode::TYPE_INFO`] to not require implementors to set this value in the + /// trait. Unknown, U8, I8, @@ -215,8 +209,8 @@ pub enum TypeInfo { /// Trait that allows zero-copy write of value-references to slices in LE format. /// -/// Implementations should override `using_encoded` for value types and `encode_to` and `size_hint` for allocating types. -/// Wrapper types should override all methods. +/// Implementations should override `using_encoded` for value types and `encode_to` and `size_hint` +/// for allocating types. Wrapper types should override all methods. pub trait Encode { // !INTERNAL USE ONLY! // This const helps SCALE to optimize the encoding/decoding by doing fake specialization. @@ -254,8 +248,9 @@ pub trait Encode { /// /// # Note /// - /// This works by using a special [`Output`] that only tracks the size. So, there are no allocations inside the - /// output. However, this can not prevent allocations that some types are doing inside their own encoding. + /// This works by using a special [`Output`] that only tracks the size. So, there are no + /// allocations inside the output. However, this can not prevent allocations that some types are + /// doing inside their own encoding. fn encoded_size(&self) -> usize { let mut size_tracker = SizeTracker { written: 0 }; self.encode_to(&mut size_tracker); @@ -304,8 +299,12 @@ pub trait Decode: Sized { /// If this function returns `Ok` then `dst` **must** be properly initialized. /// /// This is enforced by requiring the implementation to return a [`DecodeFinished`] - /// which can only be created by calling [`DecodeFinished::assert_decoding_finished`] which is `unsafe`. - fn decode_into(input: &mut I, dst: &mut MaybeUninit) -> Result { + /// which can only be created by calling [`DecodeFinished::assert_decoding_finished`] which is + /// `unsafe`. + fn decode_into( + input: &mut I, + dst: &mut MaybeUninit, + ) -> Result { let value = Self::decode(input)?; dst.write(value); @@ -388,7 +387,7 @@ impl EncodeLike<&str> for String {} impl EncodeLike for &str {} #[cfg(target_has_atomic = "ptr")] -mod atomic_ptr_targets { +mod atomic_ptr_targets { use super::*; impl WrapperTypeEncode for Arc {} impl EncodeLike for Arc {} @@ -412,7 +411,7 @@ mod feature_wrapper_bytes { #[cfg(feature = "bytes")] struct BytesCursor { bytes: bytes::Bytes, - position: usize + position: usize, } #[cfg(feature = "bytes")] @@ -423,7 +422,7 @@ impl Input for BytesCursor { fn read(&mut self, into: &mut [u8]) -> Result<(), Error> { if into.len() > self.bytes.len() - self.position { - return Err("Not enough data to fill buffer".into()) + return Err("Not enough data to fill buffer".into()); } into.copy_from_slice(&self.bytes[self.position..self.position + into.len()]); @@ -447,7 +446,10 @@ impl Input for BytesCursor { /// Decodes a given `T` from `Bytes`. #[cfg(feature = "bytes")] -pub fn decode_from_bytes(bytes: bytes::Bytes) -> Result where T: Decode { +pub fn decode_from_bytes(bytes: bytes::Bytes) -> Result +where + T: Decode, +{ // We could just use implement `Input` for `Bytes` and use `Bytes::split_to` // to move the cursor, however doing it this way allows us to prevent an // unnecessary allocation when the `T` which is being deserialized doesn't @@ -464,10 +466,7 @@ pub fn decode_from_bytes(bytes: bytes::Bytes) -> Result where T: De // However, if `T` doesn't contain any `Bytes` then this extra allocation is // technically unnecessary, and we can avoid it by tracking the position ourselves // and treating the underlying `Bytes` as a fancy `&[u8]`. - let mut input = BytesCursor { - bytes, - position: 0 - }; + let mut input = BytesCursor { bytes, position: 0 }; T::decode(&mut input) } @@ -478,7 +477,8 @@ impl Decode for bytes::Bytes { } } -impl Encode for X where +impl Encode for X +where T: Encode + ?Sized, X: WrapperTypeEncode, { @@ -510,7 +510,10 @@ pub trait WrapperTypeDecode: Sized { // This is a used to specialize `decode` for the wrapped type. #[doc(hidden)] #[inline] - fn decode_wrapped(input: &mut I) -> Result where Self::Wrapped: Decode { + fn decode_wrapped(input: &mut I) -> Result + where + Self::Wrapped: Decode, + { input.descend_ref()?; let result = Ok(Self::Wrapped::decode(input)?.into()); input.ascend_ref(); @@ -521,7 +524,10 @@ pub trait WrapperTypeDecode: Sized { impl WrapperTypeDecode for Box { type Wrapped = T; - fn decode_wrapped(input: &mut I) -> Result where Self::Wrapped: Decode { + fn decode_wrapped(input: &mut I) -> Result + where + Self::Wrapped: Decode, + { input.descend_ref()?; // Placement new is not yet stable, but we can just manually allocate a chunk of memory @@ -535,11 +541,8 @@ impl WrapperTypeDecode for Box { let ptr: *mut MaybeUninit = if layout.size() == 0 { core::ptr::NonNull::dangling().as_ptr() } else { - // SAFETY: Layout has a non-zero size so calling this is safe. - let ptr: *mut u8 = unsafe { - crate::alloc::alloc::alloc(layout) - }; + let ptr: *mut u8 = unsafe { crate::alloc::alloc::alloc(layout) }; if ptr.is_null() { crate::alloc::alloc::handle_alloc_error(layout); @@ -576,7 +579,10 @@ impl WrapperTypeDecode for Box { impl WrapperTypeDecode for Rc { type Wrapped = T; - fn decode_wrapped(input: &mut I) -> Result where Self::Wrapped: Decode { + fn decode_wrapped(input: &mut I) -> Result + where + Self::Wrapped: Decode, + { // TODO: This is inefficient; use `Rc::new_uninit` once that's stable. Box::::decode(input).map(|output| output.into()) } @@ -586,15 +592,19 @@ impl WrapperTypeDecode for Rc { impl WrapperTypeDecode for Arc { type Wrapped = T; - fn decode_wrapped(input: &mut I) -> Result where Self::Wrapped: Decode { + fn decode_wrapped(input: &mut I) -> Result + where + Self::Wrapped: Decode, + { // TODO: This is inefficient; use `Arc::new_uninit` once that's stable. Box::::decode(input).map(|output| output.into()) } } -impl Decode for X where +impl Decode for X +where T: Decode + Into, - X: WrapperTypeDecode, + X: WrapperTypeDecode, { #[inline] fn decode(input: &mut I) -> Result { @@ -604,8 +614,8 @@ impl Decode for X where /// A macro that matches on a [`TypeInfo`] and expands a given macro per variant. /// -/// The first parameter to the given macro will be the type of variant (e.g. `u8`, `u32`, etc.) and other parameters -/// given to this macro. +/// The first parameter to the given macro will be the type of variant (e.g. `u8`, `u32`, etc.) and +/// other parameters given to this macro. /// /// The last parameter is the code that should be executed for the `Unknown` type info. macro_rules! with_type_info { @@ -647,11 +657,11 @@ impl Encode for Result { Ok(ref t) => { dest.push_byte(0); t.encode_to(dest); - } + }, Err(ref e) => { dest.push_byte(1); e.encode_to(dest); - } + }, } } } @@ -662,19 +672,19 @@ where LikeT: Encode, E: EncodeLike, LikeE: Encode, -{} +{ +} impl Decode for Result { fn decode(input: &mut I) -> Result { - match input.read_byte() + match input + .read_byte() .map_err(|e| e.chain("Could not result variant byte for `Result`"))? { - 0 => Ok( - Ok(T::decode(input).map_err(|e| e.chain("Could not Decode `Result::Ok(T)`"))?) - ), - 1 => Ok( - Err(E::decode(input).map_err(|e| e.chain("Could not decode `Result::Error(E)`"))?) - ), + 0 => Ok(Ok(T::decode(input).map_err(|e| e.chain("Could not Decode `Result::Ok(T)`"))?)), + 1 => Ok(Err( + E::decode(input).map_err(|e| e.chain("Could not decode `Result::Error(E)`"))? + )), _ => Err("unexpected first byte decoding Result".into()), } } @@ -732,7 +742,7 @@ impl Encode for Option { Some(ref t) => { dest.push_byte(1); t.encode_to(dest); - } + }, None => dest.push_byte(0), } } @@ -740,13 +750,14 @@ impl Encode for Option { impl Decode for Option { fn decode(input: &mut I) -> Result { - match input.read_byte() + match input + .read_byte() .map_err(|e| e.chain("Could not decode variant byte for `Option`"))? { 0 => Ok(None), - 1 => Ok( - Some(T::decode(input).map_err(|e| e.chain("Could not decode `Option::Some(T)`"))?) - ), + 1 => Ok(Some( + T::decode(input).map_err(|e| e.chain("Could not decode `Option::Some(T)`"))?, + )), _ => Err("unexpected first byte decoding Option".into()), } } @@ -835,7 +846,8 @@ pub fn decode_vec_with_len( input: &mut I, items_len: usize, ) -> Result, Error> { - let input_capacity = input.remaining_len()? + let input_capacity = input + .remaining_len()? .unwrap_or(MAX_PREALLOCATION) .checked_div(mem::size_of::()) .unwrap_or(0); @@ -910,28 +922,26 @@ impl Decode for [T; N] { Self::decode_into(input, &mut array)?; // SAFETY: `decode_into` succeeded, so the array is initialized. - unsafe { - Ok(array.assume_init()) - } + unsafe { Ok(array.assume_init()) } } - fn decode_into(input: &mut I, dst: &mut MaybeUninit) -> Result { + fn decode_into( + input: &mut I, + dst: &mut MaybeUninit, + ) -> Result { let is_primitive = match ::TYPE_INFO { - | TypeInfo::U8 - | TypeInfo::I8 - => true, - | TypeInfo::U16 - | TypeInfo::I16 - | TypeInfo::U32 - | TypeInfo::I32 - | TypeInfo::U64 - | TypeInfo::I64 - | TypeInfo::U128 - | TypeInfo::I128 - | TypeInfo::F32 - | TypeInfo::F64 - => cfg!(target_endian = "little"), - TypeInfo::Unknown => false + | TypeInfo::U8 | TypeInfo::I8 => true, + | TypeInfo::U16 | + TypeInfo::I16 | + TypeInfo::U32 | + TypeInfo::I32 | + TypeInfo::U64 | + TypeInfo::I64 | + TypeInfo::U128 | + TypeInfo::I128 | + TypeInfo::F32 | + TypeInfo::F64 => cfg!(target_endian = "little"), + TypeInfo::Unknown => false, }; if is_primitive { @@ -952,9 +962,7 @@ impl Decode for [T; N] { } // SAFETY: We've zero-initialized everything so creating a slice here is safe. - let slice: &mut [u8] = unsafe { - core::slice::from_raw_parts_mut(ptr, bytesize) - }; + let slice: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(ptr, bytesize) }; input.read(slice)?; @@ -975,7 +983,7 @@ impl Decode for [T; N] { /// dropped in case an error occurs or the underlying `decode` implementation panics. struct State<'a, T, const N: usize> { count: usize, - slice: &'a mut [MaybeUninit; N] + slice: &'a mut [MaybeUninit; N], } impl<'a, T, const N: usize> Drop for State<'a, T, N> { @@ -1002,10 +1010,7 @@ impl Decode for [T; N] { } } - let mut state = State { - count: 0, - slice - }; + let mut state = State { count: 0, slice }; while state.count < state.slice.len() { T::decode_into(input, &mut state.slice[state.count])?; @@ -1016,9 +1021,7 @@ impl Decode for [T; N] { mem::forget(state); // SAFETY: We've initialized the whole slice so calling this is safe. - unsafe { - Ok(DecodeFinished::assert_decoding_finished()) - } + unsafe { Ok(DecodeFinished::assert_decoding_finished()) } } fn skip(input: &mut I) -> Result<(), Error> { @@ -1028,7 +1031,7 @@ impl Decode for [T; N] { T::skip(input)?; } } else { - Self::decode(input)?; + Self::decode(input)?; } Ok(()) } @@ -1059,7 +1062,8 @@ impl Encode for str { } impl<'a, T: ToOwned + ?Sized> Decode for Cow<'a, T> - where ::Owned: Decode, +where + ::Owned: Decode, { fn decode(input: &mut I) -> Result { Ok(Cow::Owned(Decode::decode(input)?)) @@ -1085,7 +1089,10 @@ impl Decode for String { } /// Writes the compact encoding of `len` do `dest`. -pub(crate) fn compact_encode_len_to(dest: &mut W, len: usize) -> Result<(), Error> { +pub(crate) fn compact_encode_len_to( + dest: &mut W, + len: usize, +) -> Result<(), Error> { if len > u32::MAX as usize { return Err("Attempted to serialize a collection with too many elements.".into()); } @@ -1117,14 +1124,15 @@ where { debug_assert!(MAX_PREALLOCATION >= mem::size_of::(), "Invalid precondition"); - let byte_len = items_len.checked_mul(mem::size_of::()) + let byte_len = items_len + .checked_mul(mem::size_of::()) .ok_or("Item is too big and cannot be allocated")?; let input_len = input.remaining_len()?; // If there is input len and it cannot be pre-allocated then return directly. if input_len.map(|l| l < byte_len).unwrap_or(false) { - return Err("Not enough data to decode vector".into()) + return Err("Not enough data to decode vector".into()); } // In both these branches we're going to be creating and resizing a Vec, @@ -1179,9 +1187,8 @@ impl, U: Encode> EncodeLike> for &[T] {} impl Decode for Vec { fn decode(input: &mut I) -> Result { - >::decode(input).and_then(move |Compact(len)| { - decode_vec_with_len(input, len as usize) - }) + >::decode(input) + .and_then(move |Compact(len)| decode_vec_with_len(input, len as usize)) } } @@ -1257,9 +1264,8 @@ impl Encode for VecDeque { ( $ty:ty, $self:ident, $dest:ident ) => {{ if cfg!(target_endian = "little") || mem::size_of::() == 1 { let slices = $self.as_slices(); - let typed = unsafe { - core::mem::transmute::<(&[T], &[T]), (&[$ty], &[$ty])>(slices) - }; + let typed = + unsafe { core::mem::transmute::<(&[T], &[T]), (&[$ty], &[$ty])>(slices) }; $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.0)); $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.1)); @@ -1292,8 +1298,7 @@ impl Decode for VecDeque { impl EncodeLike for () {} impl Encode for () { - fn encode_to(&self, _dest: &mut W) { - } + fn encode_to(&self, _dest: &mut W) {} fn using_encoded R>(&self, f: F) -> R { f(&[]) @@ -1419,8 +1424,24 @@ mod inner_tuple_impl { use super::*; tuple_impl!( - (A0, A1), (B0, B1), (C0, C1), (D0, D1), (E0, E1), (F0, F1), (G0, G1), (H0, H1), (I0, I1), - (J0, J1), (K0, K1), (L0, L1), (M0, M1), (N0, N1), (O0, O1), (P0, P1), (Q0, Q1), (R0, R1), + (A0, A1), + (B0, B1), + (C0, C1), + (D0, D1), + (E0, E1), + (F0, F1), + (G0, G1), + (H0, H1), + (I0, I1), + (J0, J1), + (K0, K1), + (L0, L1), + (M0, M1), + (N0, N1), + (O0, O1), + (P0, P1), + (Q0, Q1), + (R0, R1), ); } @@ -1505,7 +1526,7 @@ impl Decode for bool { match byte { 0 => Ok(false), 1 => Ok(true), - _ => Err("Invalid boolean representation".into()) + _ => Err("Invalid boolean representation".into()), } } @@ -1542,7 +1563,7 @@ impl EncodeLike for Duration {} impl Encode for Range where - T: Encode + T: Encode, { fn size_hint(&self) -> usize { 2 * mem::size_of::() @@ -1555,18 +1576,18 @@ where impl Decode for Range where - T: Decode + T: Decode, { fn decode(input: &mut I) -> Result { - let (start, end) = <(T, T)>::decode(input) - .map_err(|e| e.chain("Could not decode `Range`"))?; + let (start, end) = + <(T, T)>::decode(input).map_err(|e| e.chain("Could not decode `Range`"))?; Ok(Range { start, end }) } } impl Encode for RangeInclusive where - T: Encode + T: Encode, { fn size_hint(&self) -> usize { 2 * mem::size_of::() @@ -1579,16 +1600,15 @@ where impl Decode for RangeInclusive where - T: Decode + T: Decode, { fn decode(input: &mut I) -> Result { - let (start, end) = <(T, T)>::decode(input) - .map_err(|e| e.chain("Could not decode `RangeInclusive`"))?; + let (start, end) = + <(T, T)>::decode(input).map_err(|e| e.chain("Could not decode `RangeInclusive`"))?; Ok(RangeInclusive::new(start, end)) } } - #[cfg(test)] mod tests { use super::*; @@ -1597,9 +1617,7 @@ mod tests { #[test] fn vec_is_sliceable() { let v = b"Hello world".to_vec(); - v.using_encoded(|ref slice| - assert_eq!(slice, &b"\x2cHello world") - ); + v.using_encoded(|ref slice| assert_eq!(slice, &b"\x2cHello world")); } #[test] @@ -1633,7 +1651,11 @@ mod tests { } fn hexify(bytes: &[u8]) -> String { - bytes.iter().map(|ref b| format!("{:02x}", b)).collect::>().join(" ") + bytes + .iter() + .map(|ref b| format!("{:02x}", b)) + .collect::>() + .join(" ") } #[test] @@ -1684,10 +1706,7 @@ mod tests { let encoded_vec = input.to_vec().encode(); assert_eq!(encoded, encoded_vec); - assert_eq!( - &b"hello"[..], - bytes::Bytes::decode(&mut &encoded[..]).unwrap(), - ); + assert_eq!(&b"hello"[..], bytes::Bytes::decode(&mut &encoded[..]).unwrap(),); } #[cfg(feature = "bytes")] @@ -1754,13 +1773,16 @@ mod tests { "Hamlet".to_owned(), "Война и мир".to_owned(), "三国演义".to_owned(), - "أَلْف لَيْلَة وَلَيْلَة‎".to_owned() + "أَلْف لَيْلَة وَلَيْلَة‎".to_owned(), ]; let encoded = value.encode(); - assert_eq!(hexify(&encoded), "10 18 48 61 6d 6c 65 74 50 d0 92 d0 be d0 b9 d0 bd d0 b0 20 d0 \ + assert_eq!( + hexify(&encoded), + "10 18 48 61 6d 6c 65 74 50 d0 92 d0 be d0 b9 d0 bd d0 b0 20 d0 \ b8 20 d0 bc d0 b8 d1 80 30 e4 b8 89 e5 9b bd e6 bc 94 e4 b9 89 bc d8 a3 d9 8e d9 84 d9 92 \ d9 81 20 d9 84 d9 8e d9 8a d9 92 d9 84 d9 8e d8 a9 20 d9 88 d9 8e d9 84 d9 8e d9 8a d9 92 \ - d9 84 d9 8e d8 a9 e2 80 8e"); + d9 84 d9 8e d8 a9 e2 80 8e" + ); assert_eq!(>::decode(&mut &encoded[..]).unwrap(), value); } @@ -1768,12 +1790,16 @@ mod tests { struct MyWrapper(Compact); impl Deref for MyWrapper { type Target = Compact; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl WrapperTypeEncode for MyWrapper {} impl From> for MyWrapper { - fn from(c: Compact) -> Self { MyWrapper(c) } + fn from(c: Compact) -> Self { + MyWrapper(c) + } } impl WrapperTypeDecode for MyWrapper { type Wrapped = Compact; @@ -1810,18 +1836,15 @@ mod tests { let t1: BTreeSet = FromIterator::from_iter((0..10).flat_map(|i| 0..i)); let t2: LinkedList = FromIterator::from_iter((0..10).flat_map(|i| 0..i)); let t3: BinaryHeap = FromIterator::from_iter((0..10).flat_map(|i| 0..i)); - let t4: BTreeMap = FromIterator::from_iter( - (0..10) - .flat_map(|i| 0..i) - .map(|i| (i as u16, i + 10)) - ); + let t4: BTreeMap = + FromIterator::from_iter((0..10).flat_map(|i| 0..i).map(|i| (i as u16, i + 10))); let t5: BTreeSet> = FromIterator::from_iter((0..10).map(|i| Vec::from_iter(0..i))); - let t6: LinkedList> = FromIterator::from_iter((0..10).map(|i| Vec::from_iter(0..i))); - let t7: BinaryHeap> = FromIterator::from_iter((0..10).map(|i| Vec::from_iter(0..i))); + let t6: LinkedList> = + FromIterator::from_iter((0..10).map(|i| Vec::from_iter(0..i))); + let t7: BinaryHeap> = + FromIterator::from_iter((0..10).map(|i| Vec::from_iter(0..i))); let t8: BTreeMap, u32> = FromIterator::from_iter( - (0..10) - .map(|i| Vec::from_iter(0..i)) - .map(|i| (i.clone(), i.len() as u32)) + (0..10).map(|i| Vec::from_iter(0..i)).map(|i| (i.clone(), i.len() as u32)), ); assert_eq!(Decode::decode(&mut &t1.encode()[..]), Ok(t1)); @@ -2013,7 +2036,6 @@ mod tests { <[u32; 0]>::decode(&mut &encoded[..]).unwrap(); } - macro_rules! test_array_encode_and_decode { ( $( $name:ty ),* $(,)? ) => { $( diff --git a/src/compact.rs b/src/compact.rs index 91e632e5..9299db6b 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -16,12 +16,14 @@ use arrayvec::ArrayVec; -use crate::alloc::vec::Vec; -use crate::codec::{Encode, Decode, Input, Output, EncodeAsRef}; -use crate::encode_like::EncodeLike; -use crate::Error; #[cfg(feature = "max-encoded-len")] use crate::MaxEncodedLen; +use crate::{ + alloc::vec::Vec, + codec::{Decode, Encode, EncodeAsRef, Input, Output}, + encode_like::EncodeLike, + Error, +}; #[cfg(feature = "fuzz")] use arbitrary::Arbitrary; @@ -66,8 +68,8 @@ impl<'a, T: 'a + Input> Input for PrefixInput<'a, T> { Some(v) if !buffer.is_empty() => { buffer[0] = v; self.input.read(&mut buffer[1..]) - } - _ => self.input.read(buffer) + }, + _ => self.input.read(buffer), } } } @@ -84,11 +86,15 @@ pub trait CompactLen { pub struct Compact(pub T); impl From for Compact { - fn from(x: T) -> Compact { Compact(x) } + fn from(x: T) -> Compact { + Compact(x) + } } impl<'a, T: Copy> From<&'a T> for Compact { - fn from(x: &'a T) -> Compact { Compact(*x) } + fn from(x: &'a T) -> Compact { + Compact(*x) + } } /// Allow foreign structs to be wrap in Compact @@ -103,10 +109,7 @@ pub trait CompactAs: From> { fn decode_from(_: Self::As) -> Result; } -impl EncodeLike for Compact -where - for<'a> CompactRef<'a, T>: Encode, -{} +impl EncodeLike for Compact where for<'a> CompactRef<'a, T>: Encode {} impl Encode for Compact where @@ -133,7 +136,8 @@ impl<'a, T> EncodeLike for CompactRef<'a, T> where T: CompactAs, for<'b> CompactRef<'b, T::As>: Encode, -{} +{ +} impl<'a, T> Encode for CompactRef<'a, T> where @@ -185,25 +189,42 @@ impl_from_compact! { (), u8, u16, u32, u64, u128 } pub struct CompactRef<'a, T>(pub &'a T); impl<'a, T> From<&'a T> for CompactRef<'a, T> { - fn from(x: &'a T) -> Self { CompactRef(x) } + fn from(x: &'a T) -> Self { + CompactRef(x) + } } -impl core::fmt::Debug for Compact where T: core::fmt::Debug { +impl core::fmt::Debug for Compact +where + T: core::fmt::Debug, +{ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.0.fmt(f) } } #[cfg(feature = "serde")] -impl serde::Serialize for Compact where T: serde::Serialize { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { +impl serde::Serialize for Compact +where + T: serde::Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { T::serialize(&self.0, serializer) } } #[cfg(feature = "serde")] -impl<'de, T> serde::Deserialize<'de> for Compact where T: serde::Deserialize<'de> { - fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { +impl<'de, T> serde::Deserialize<'de> for Compact +where + T: serde::Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { T::deserialize(deserializer).map(Compact) } } @@ -228,26 +249,34 @@ pub trait HasCompact: Sized { type Type: for<'a> EncodeAsRef<'a, Self> + Decode + From + Into + MaybeMaxEncodedLen; } -impl<'a, T: 'a> EncodeAsRef<'a, T> for Compact where CompactRef<'a, T>: Encode + From<&'a T> { +impl<'a, T: 'a> EncodeAsRef<'a, T> for Compact +where + CompactRef<'a, T>: Encode + From<&'a T>, +{ type RefType = CompactRef<'a, T>; } #[cfg(feature = "max-encoded-len")] -impl MaxEncodedLen for Compact where T: CompactAs, Compact: MaxEncodedLen, Compact: Encode { +impl MaxEncodedLen for Compact +where + T: CompactAs, + Compact: MaxEncodedLen, + Compact: Encode, +{ fn max_encoded_len() -> usize { Compact::::max_encoded_len() } } -impl HasCompact for T where - Compact: for<'a> EncodeAsRef<'a, T> + Decode + From + Into + MaybeMaxEncodedLen +impl HasCompact for T +where + Compact: for<'a> EncodeAsRef<'a, T> + Decode + From + Into + MaybeMaxEncodedLen, { type Type = Compact; } impl<'a> Encode for CompactRef<'a, ()> { - fn encode_to(&self, _dest: &mut W) { - } + fn encode_to(&self, _dest: &mut W) {} fn using_encoded R>(&self, f: F) -> R { f(&[]) @@ -325,11 +354,12 @@ impl<'a> Encode for CompactRef<'a, u32> { match self.0 { 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2), 0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest), - 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => ((*self.0 << 2) | 0b10).encode_to(dest), + 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => + ((*self.0 << 2) | 0b10).encode_to(dest), _ => { dest.push_byte(0b11); self.0.encode_to(dest); - } + }, } } @@ -360,10 +390,14 @@ impl<'a> Encode for CompactRef<'a, u64> { match self.0 { 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2), 0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest), - 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => (((*self.0 as u32) << 2) | 0b10).encode_to(dest), + 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => + (((*self.0 as u32) << 2) | 0b10).encode_to(dest), _ => { let bytes_needed = 8 - self.0.leading_zeros() / 8; - assert!(bytes_needed >= 4, "Previous match arm matches anyting less than 2^30; qed"); + assert!( + bytes_needed >= 4, + "Previous match arm matches anyting less than 2^30; qed" + ); dest.push_byte(0b11 + ((bytes_needed - 4) << 2) as u8); let mut v = *self.0; for _ in 0..bytes_needed { @@ -371,7 +405,7 @@ impl<'a> Encode for CompactRef<'a, u64> { v >>= 8; } assert_eq!(v, 0, "shifted sufficient bits right to lead only leading zeros; qed") - } + }, } } @@ -388,9 +422,7 @@ impl CompactLen for Compact { 0..=0b0011_1111 => 1, 0..=0b0011_1111_1111_1111 => 2, 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => 4, - _ => { - (8 - val.leading_zeros() / 8) as usize + 1 - }, + _ => (8 - val.leading_zeros() / 8) as usize + 1, } } } @@ -404,10 +436,14 @@ impl<'a> Encode for CompactRef<'a, u128> { match self.0 { 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2), 0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest), - 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => (((*self.0 as u32) << 2) | 0b10).encode_to(dest), + 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => + (((*self.0 as u32) << 2) | 0b10).encode_to(dest), _ => { let bytes_needed = 16 - self.0.leading_zeros() / 8; - assert!(bytes_needed >= 4, "Previous match arm matches anyting less than 2^30; qed"); + assert!( + bytes_needed >= 4, + "Previous match arm matches anyting less than 2^30; qed" + ); dest.push_byte(0b11 + ((bytes_needed - 4) << 2) as u8); let mut v = *self.0; for _ in 0..bytes_needed { @@ -415,7 +451,7 @@ impl<'a> Encode for CompactRef<'a, u128> { v >>= 8; } assert_eq!(v, 0, "shifted sufficient bits right to lead only leading zeros; qed") - } + }, } } @@ -432,9 +468,7 @@ impl CompactLen for Compact { 0..=0b0011_1111 => 1, 0..=0b0011_1111_1111_1111 => 2, 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => 4, - _ => { - (16 - val.leading_zeros() / 8) as usize + 1 - }, + _ => (16 - val.leading_zeros() / 8) as usize + 1, } } } @@ -457,7 +491,7 @@ impl Decode for Compact { Ok(Compact(match prefix % 4 { 0 => prefix >> 2, 1 => { - let x = u16::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; + let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2; if x > 0b0011_1111 && x <= 255 { x as u8 } else { @@ -475,7 +509,7 @@ impl Decode for Compact { Ok(Compact(match prefix % 4 { 0 => u16::from(prefix) >> 2, 1 => { - let x = u16::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; + let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2; if x > 0b0011_1111 && x <= 0b0011_1111_1111_1111 { x } else { @@ -483,7 +517,7 @@ impl Decode for Compact { } }, 2 => { - let x = u32::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; + let x = u32::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2; if x > 0b0011_1111_1111_1111 && x < 65536 { x as u16 } else { @@ -501,7 +535,7 @@ impl Decode for Compact { Ok(Compact(match prefix % 4 { 0 => u32::from(prefix) >> 2, 1 => { - let x = u16::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; + let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2; if x > 0b0011_1111 && x <= 0b0011_1111_1111_1111 { u32::from(x) } else { @@ -509,7 +543,7 @@ impl Decode for Compact { } }, 2 => { - let x = u32::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; + let x = u32::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2; if x > 0b0011_1111_1111_1111 && x <= u32::MAX >> 2 { x } else { @@ -541,7 +575,7 @@ impl Decode for Compact { Ok(Compact(match prefix % 4 { 0 => u64::from(prefix) >> 2, 1 => { - let x = u16::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; + let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2; if x > 0b0011_1111 && x <= 0b0011_1111_1111_1111 { u64::from(x) } else { @@ -549,7 +583,7 @@ impl Decode for Compact { } }, 2 => { - let x = u32::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; + let x = u32::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2; if x > 0b0011_1111_1111_1111 && x <= u32::MAX >> 2 { u64::from(x) } else { @@ -597,7 +631,7 @@ impl Decode for Compact { Ok(Compact(match prefix % 4 { 0 => u128::from(prefix) >> 2, 1 => { - let x = u16::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; + let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2; if x > 0b0011_1111 && x <= 0b0011_1111_1111_1111 { u128::from(x) } else { @@ -605,7 +639,7 @@ impl Decode for Compact { } }, 2 => { - let x = u32::decode(&mut PrefixInput{prefix: Some(prefix), input})? >> 2; + let x = u32::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2; if x > 0b0011_1111_1111_1111 && x <= u32::MAX >> 2 { u128::from(x) } else { @@ -662,12 +696,30 @@ mod tests { #[test] fn compact_128_encoding_works() { let tests = [ - (0u128, 1usize), (63, 1), (64, 2), (16383, 2), - (16384, 4), (1073741823, 4), - (1073741824, 5), ((1 << 32) - 1, 5), - (1 << 32, 6), (1 << 40, 7), (1 << 48, 8), ((1 << 56) - 1, 8), (1 << 56, 9), ((1 << 64) - 1, 9), - (1 << 64, 10), (1 << 72, 11), (1 << 80, 12), (1 << 88, 13), (1 << 96, 14), (1 << 104, 15), - (1 << 112, 16), ((1 << 120) - 1, 16), (1 << 120, 17), (u128::MAX, 17) + (0u128, 1usize), + (63, 1), + (64, 2), + (16383, 2), + (16384, 4), + (1073741823, 4), + (1073741824, 5), + ((1 << 32) - 1, 5), + (1 << 32, 6), + (1 << 40, 7), + (1 << 48, 8), + ((1 << 56) - 1, 8), + (1 << 56, 9), + ((1 << 64) - 1, 9), + (1 << 64, 10), + (1 << 72, 11), + (1 << 80, 12), + (1 << 88, 13), + (1 << 96, 14), + (1 << 104, 15), + (1 << 112, 16), + ((1 << 120) - 1, 16), + (1 << 120, 17), + (u128::MAX, 17), ]; for &(n, l) in &tests { let encoded = Compact(n as u128).encode(); @@ -680,10 +732,20 @@ mod tests { #[test] fn compact_64_encoding_works() { let tests = [ - (0u64, 1usize), (63, 1), (64, 2), (16383, 2), - (16384, 4), (1073741823, 4), - (1073741824, 5), ((1 << 32) - 1, 5), - (1 << 32, 6), (1 << 40, 7), (1 << 48, 8), ((1 << 56) - 1, 8), (1 << 56, 9), (u64::MAX, 9) + (0u64, 1usize), + (63, 1), + (64, 2), + (16383, 2), + (16384, 4), + (1073741823, 4), + (1073741824, 5), + ((1 << 32) - 1, 5), + (1 << 32, 6), + (1 << 40, 7), + (1 << 48, 8), + ((1 << 56) - 1, 8), + (1 << 56, 9), + (u64::MAX, 9), ]; for &(n, l) in &tests { let encoded = Compact(n as u64).encode(); @@ -695,7 +757,16 @@ mod tests { #[test] fn compact_32_encoding_works() { - let tests = [(0u32, 1usize), (63, 1), (64, 2), (16383, 2), (16384, 4), (1073741823, 4), (1073741824, 5), (u32::MAX, 5)]; + let tests = [ + (0u32, 1usize), + (63, 1), + (64, 2), + (16383, 2), + (16384, 4), + (1073741823, 4), + (1073741824, 5), + (u32::MAX, 5), + ]; for &(n, l) in &tests { let encoded = Compact(n as u32).encode(); assert_eq!(encoded.len(), l); @@ -729,7 +800,11 @@ mod tests { } fn hexify(bytes: &[u8]) -> String { - bytes.iter().map(|ref b| format!("{:02x}", b)).collect::>().join(" ") + bytes + .iter() + .map(|ref b| format!("{:02x}", b)) + .collect::>() + .join(" ") } #[test] @@ -748,7 +823,7 @@ mod tests { (1 << 48, "0f 00 00 00 00 00 00 01"), ((1 << 56) - 1, "0f ff ff ff ff ff ff ff"), (1 << 56, "13 00 00 00 00 00 00 00 01"), - (u64::MAX, "13 ff ff ff ff ff ff ff ff") + (u64::MAX, "13 ff ff ff ff ff ff ff ff"), ]; for &(n, s) in &tests { // Verify u64 encoding @@ -806,7 +881,7 @@ mod tests { let encoded = compact.encode(); assert_eq!(encoded.len(), l); assert_eq!(Compact::compact_len(&n), l); - let decoded = >::decode(&mut & encoded[..]).unwrap(); + let decoded = >::decode(&mut &encoded[..]).unwrap(); let wrapper: Wrapper = decoded.into(); assert_eq!(wrapper, Wrapper(n)); } @@ -899,7 +974,9 @@ mod tests { (u64::MAX << 8) - 1, u64::MAX << 16, (u64::MAX << 16) - 1, - ].iter() { + ] + .iter() + { let e = Compact::::encode(&Compact(*a)); let d = Compact::::decode(&mut &e[..]).unwrap().0; assert_eq!(*a, d); @@ -908,12 +985,7 @@ mod tests { #[test] fn compact_u128_test() { - for a in [ - u64::MAX as u128, - (u64::MAX - 10) as u128, - u128::MAX, - u128::MAX - 10, - ].iter() { + for a in [u64::MAX as u128, (u64::MAX - 10) as u128, u128::MAX, u128::MAX - 10].iter() { let e = Compact::::encode(&Compact(*a)); let d = Compact::::decode(&mut &e[..]).unwrap().0; assert_eq!(*a, d); @@ -923,16 +995,33 @@ mod tests { #[test] fn should_avoid_overlapping_definition() { check_bound!( - 0b01, u8, u16, [ (u8, U8_OUT_OF_RANGE), (u16, U16_OUT_OF_RANGE), - (u32, U32_OUT_OF_RANGE), (u64, U64_OUT_OF_RANGE), (u128, U128_OUT_OF_RANGE)] + 0b01, + u8, + u16, + [ + (u8, U8_OUT_OF_RANGE), + (u16, U16_OUT_OF_RANGE), + (u32, U32_OUT_OF_RANGE), + (u64, U64_OUT_OF_RANGE), + (u128, U128_OUT_OF_RANGE) + ] ); check_bound!( - 0b10, u16, u32, [ (u16, U16_OUT_OF_RANGE), - (u32, U32_OUT_OF_RANGE), (u64, U64_OUT_OF_RANGE), (u128, U128_OUT_OF_RANGE)] - ); - check_bound_u32!( - [(u32, U32_OUT_OF_RANGE), (u64, U64_OUT_OF_RANGE), (u128, U128_OUT_OF_RANGE)] + 0b10, + u16, + u32, + [ + (u16, U16_OUT_OF_RANGE), + (u32, U32_OUT_OF_RANGE), + (u64, U64_OUT_OF_RANGE), + (u128, U128_OUT_OF_RANGE) + ] ); + check_bound_u32!([ + (u32, U32_OUT_OF_RANGE), + (u64, U64_OUT_OF_RANGE), + (u128, U128_OUT_OF_RANGE) + ]); for i in 5..=8 { check_bound_high!(i, [(u64, U64_OUT_OF_RANGE), (u128, U128_OUT_OF_RANGE)]); } diff --git a/src/const_encoded_len.rs b/src/const_encoded_len.rs index 6a0ee33c..8b5625f5 100644 --- a/src/const_encoded_len.rs +++ b/src/const_encoded_len.rs @@ -13,16 +13,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Contains the [`ConstEncodedLen`] trait. +//! Contains the [`ConstEncodedLen`] trait. -use crate::MaxEncodedLen; +use crate::{alloc::boxed::Box, MaxEncodedLen}; use core::{ marker::PhantomData, num::*, ops::{Range, RangeInclusive}, time::Duration, }; -use crate::alloc::boxed::Box; use impl_trait_for_tuples::impl_for_tuples; /// Types that have a constant encoded length. This implies [`MaxEncodedLen`]. @@ -31,9 +30,9 @@ use impl_trait_for_tuples::impl_for_tuples; pub trait ConstEncodedLen: MaxEncodedLen {} #[impl_for_tuples(18)] -impl ConstEncodedLen for Tuple { } +impl ConstEncodedLen for Tuple {} -impl ConstEncodedLen for [T; N] { } +impl ConstEncodedLen for [T; N] {} /// Mark `T` or `T` as `CEL`. macro_rules! mark_cel { @@ -50,7 +49,18 @@ macro_rules! mark_cel { } mark_cel!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, bool); -mark_cel!(NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128); +mark_cel!( + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128, + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroI128 +); mark_cel!(Duration); mark_cel!(PhantomData); @@ -85,7 +95,7 @@ mod tests { test_cel_compliance!(Void); test_cel_compliance!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, bool); - + type TupleArithmetic = (u8, u16, u32, u64, u128, i8, i16, i32, i64, i128); test_cel_compliance!(TupleArithmetic); diff --git a/src/decode_all.rs b/src/decode_all.rs index 448afbd5..62836190 100644 --- a/src/decode_all.rs +++ b/src/decode_all.rs @@ -17,8 +17,8 @@ use crate::{Decode, Error}; /// The error message returned when `decode_all` fails. pub(crate) const DECODE_ALL_ERR_MSG: &str = "Input buffer has still data left after decoding!"; -/// Extension trait to [`Decode`] that ensures that the given input data is consumed completely while -/// decoding. +/// Extension trait to [`Decode`] that ensures that the given input data is consumed completely +/// while decoding. pub trait DecodeAll: Sized { /// Decode `Self` and consume all of the given input data. /// diff --git a/src/encode_append.rs b/src/encode_append.rs index 6f60f6aa..82cf4f81 100644 --- a/src/encode_append.rs +++ b/src/encode_append.rs @@ -14,10 +14,12 @@ use core::iter::ExactSizeIterator; -use crate::alloc::vec::Vec; -use crate::{Encode, Decode, Error}; -use crate::compact::{Compact, CompactLen}; -use crate::encode_like::EncodeLike; +use crate::{ + alloc::vec::Vec, + compact::{Compact, CompactLen}, + encode_like::EncodeLike, + Decode, Encode, Error, +}; /// Trait that allows to append items to an encoded representation without /// decoding all previous added items. @@ -31,7 +33,7 @@ pub trait EncodeAppend { /// # Example /// /// ``` - ///# use parity_scale_codec::EncodeAppend; + /// # use parity_scale_codec::EncodeAppend; /// /// // Some encoded data /// let data = Vec::new(); @@ -42,10 +44,7 @@ pub trait EncodeAppend { /// // Add multiple element /// as EncodeAppend>::append_or_new(encoded, &[700u32, 800u32, 10u32]).expect("Adds new elements"); /// ``` - fn append_or_new( - self_encoded: Vec, - iter: I, - ) -> Result, Error> + fn append_or_new(self_encoded: Vec, iter: I) -> Result, Error> where I: IntoIterator, EncodeLikeItem: EncodeLike, @@ -55,10 +54,7 @@ pub trait EncodeAppend { impl EncodeAppend for Vec { type Item = T; - fn append_or_new( - self_encoded: Vec, - iter: I, - ) -> Result, Error> + fn append_or_new(self_encoded: Vec, iter: I) -> Result, Error> where I: IntoIterator, EncodeLikeItem: EncodeLike, @@ -71,10 +67,7 @@ impl EncodeAppend for Vec { impl EncodeAppend for crate::alloc::collections::VecDeque { type Item = T; - fn append_or_new( - self_encoded: Vec, - iter: I, - ) -> Result, Error> + fn append_or_new(self_encoded: Vec, iter: I) -> Result, Error> where I: IntoIterator, EncodeLikeItem: EncodeLike, @@ -87,10 +80,7 @@ impl EncodeAppend for crate::alloc::collections::VecDeque { /// Extends a SCALE-encoded vector with elements from the given `iter`. /// /// `vec` must either be empty, or contain a valid SCALE-encoded `Vec` payload. -fn append_or_new_impl( - mut vec: Vec, - iter: I, -) -> Result, Error> +fn append_or_new_impl(mut vec: Vec, iter: I) -> Result, Error> where Item: Encode, I: IntoIterator, @@ -113,9 +103,9 @@ where if old_item_count_encoded_bytesize == new_item_count_encoded_bytesize { // The size of the length as encoded by SCALE didn't change, so we can just // keep the old buffer as-is. We just need to update the length prefix. - Compact(new_item_count).using_encoded(|length_encoded| + Compact(new_item_count).using_encoded(|length_encoded| { vec[..old_item_count_encoded_bytesize].copy_from_slice(length_encoded) - ); + }); } else { // We can't update the length as the new length prefix will take up more // space when encoded, so we need to move our data to make space for it. @@ -143,14 +133,18 @@ where #[cfg(test)] mod tests { use super::*; - use crate::{Input, Encode, EncodeLike}; + use crate::{Encode, EncodeLike, Input}; use std::collections::VecDeque; const TEST_VALUE: u32 = { #[cfg(not(miri))] - { 1_000_000 } + { + 1_000_000 + } #[cfg(miri)] - { 1_000 } + { + 1_000 + } }; #[test] @@ -204,7 +198,9 @@ mod tests { #[test] fn append_non_copyable() { #[derive(Eq, PartialEq, Debug)] - struct NoCopy { data: u32 } + struct NoCopy { + data: u32, + } impl EncodeLike for NoCopy {} @@ -222,7 +218,8 @@ mod tests { let append = NoCopy { data: 100 }; let data = Vec::new(); - let encoded = as EncodeAppend>::append_or_new(data, std::iter::once(&append)).unwrap(); + let encoded = + as EncodeAppend>::append_or_new(data, std::iter::once(&append)).unwrap(); let decoded = >::decode(&mut &encoded[..]).unwrap(); assert_eq!(vec![append], decoded); @@ -231,7 +228,8 @@ mod tests { #[test] fn vec_encode_like_append_works() { let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| { - as EncodeAppend>::append_or_new(encoded, std::iter::once(Box::new(v as u32))).unwrap() + as EncodeAppend>::append_or_new(encoded, std::iter::once(Box::new(v as u32))) + .unwrap() }); let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); diff --git a/src/encode_like.rs b/src/encode_like.rs index 36023dd9..80fc2947 100644 --- a/src/encode_like.rs +++ b/src/encode_like.rs @@ -22,7 +22,7 @@ use crate::codec::Encode; /// # Example /// /// ``` -///# use parity_scale_codec::{EncodeLike, Encode}; +/// # use parity_scale_codec::{EncodeLike, Encode}; /// fn encode_like>(data: &R) { /// data.encode(); // Valid `T` encoded value. /// } @@ -51,7 +51,7 @@ use crate::codec::Encode; /// combination or use [`Ref`](./struct.Ref.html) reference wrapper or define your own wrapper /// and implement `EncodeLike` on it as such: /// ``` -///# use parity_scale_codec::{EncodeLike, Encode, WrapperTypeEncode}; +/// # use parity_scale_codec::{EncodeLike, Encode, WrapperTypeEncode}; /// fn encode_like>(data: &R) { /// data.encode(); // Valid `T` encoded value. /// } @@ -88,8 +88,10 @@ pub trait EncodeLike: Sized + Encode {} /// ``` pub struct Ref<'a, T: EncodeLike, U: Encode>(&'a T, core::marker::PhantomData); impl<'a, T: EncodeLike, U: Encode> core::ops::Deref for Ref<'a, T, U> { - type Target = T; - fn deref(&self) -> &Self::Target { self.0 } + type Target = T; + fn deref(&self) -> &Self::Target { + self.0 + } } impl<'a, T: EncodeLike, U: Encode> From<&'a T> for Ref<'a, T, U> { @@ -109,7 +111,10 @@ mod tests { struct ComplexStuff(T); impl ComplexStuff { - fn complex_method(value: &R) -> Vec where T: EncodeLike { + fn complex_method(value: &R) -> Vec + where + T: EncodeLike, + { value.encode() } } diff --git a/src/generic_array.rs b/src/generic_array.rs index a346b355..18dffceb 100644 --- a/src/generic_array.rs +++ b/src/generic_array.rs @@ -12,9 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::alloc::vec::Vec; -use crate::{Encode, Decode, Input, Output, Error}; -use crate::encode_like::EncodeLike; +use crate::{alloc::vec::Vec, encode_like::EncodeLike, Decode, Encode, Error, Input, Output}; impl> Encode for generic_array::GenericArray { fn encode_to(&self, dest: &mut W) { @@ -44,7 +42,7 @@ impl> Decode for generic_array::Gene #[cfg(test)] mod tests { use super::*; - use generic_array::{typenum, GenericArray, arr}; + use generic_array::{arr, typenum, GenericArray}; #[test] fn generic_array() { diff --git a/src/joiner.rs b/src/joiner.rs index 6dd44589..1baa026d 100644 --- a/src/joiner.rs +++ b/src/joiner.rs @@ -25,7 +25,10 @@ pub trait Joiner { fn and(self, value: &V) -> Self; } -impl Joiner for T where T: for<'a> Extend<&'a u8> { +impl Joiner for T +where + T: for<'a> Extend<&'a u8>, +{ fn and(mut self, value: &V) -> Self { value.using_encoded(|s| self.extend(s)); self diff --git a/src/keyedvec.rs b/src/keyedvec.rs index 20e76e71..78f00673 100644 --- a/src/keyedvec.rs +++ b/src/keyedvec.rs @@ -16,8 +16,7 @@ use core::iter::Extend; -use crate::alloc::vec::Vec; -use crate::codec::Codec; +use crate::{alloc::vec::Vec, codec::Codec}; /// Trait to allow itself to be serialised and prepended by a given slice. pub trait KeyedVec { diff --git a/src/lib.rs b/src/lib.rs index fb247601..9f95cf69 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,54 +36,49 @@ pub use parity_scale_codec_derive::*; #[cfg(feature = "std")] #[doc(hidden)] pub mod alloc { - pub use std::boxed; - pub use std::vec; - pub use std::string; - pub use std::borrow; - pub use std::collections; - pub use std::sync; - pub use std::rc; - pub use std::alloc; + pub use std::{alloc, borrow, boxed, collections, rc, string, sync, vec}; } -mod codec; -mod compact; -mod joiner; -mod keyedvec; #[cfg(feature = "bit-vec")] mod bit_vec; -#[cfg(feature = "generic-array")] -mod generic_array; +mod codec; +mod compact; +#[cfg(feature = "max-encoded-len")] +mod const_encoded_len; mod decode_all; mod decode_finished; mod depth_limit; mod encode_append; mod encode_like; mod error; +#[cfg(feature = "generic-array")] +mod generic_array; +mod joiner; +mod keyedvec; #[cfg(feature = "max-encoded-len")] mod max_encoded_len; -#[cfg(feature = "max-encoded-len")] -mod const_encoded_len; -pub use self::error::Error; -pub use self::codec::{ - Input, Output, Decode, Encode, Codec, EncodeAsRef, WrapperTypeEncode, WrapperTypeDecode, - OptionBool, DecodeLength, FullCodec, FullEncode, decode_vec_with_len, -}; #[cfg(feature = "std")] pub use self::codec::IoReader; -pub use self::compact::{Compact, HasCompact, CompactAs, CompactLen, CompactRef}; -pub use self::joiner::Joiner; -pub use self::keyedvec::KeyedVec; -pub use self::decode_all::DecodeAll; -pub use self::decode_finished::DecodeFinished; -pub use self::depth_limit::DecodeLimit; -pub use self::encode_append::EncodeAppend; -pub use self::encode_like::{EncodeLike, Ref}; -#[cfg(feature = "max-encoded-len")] -pub use max_encoded_len::MaxEncodedLen; +pub use self::{ + codec::{ + decode_vec_with_len, Codec, Decode, DecodeLength, Encode, EncodeAsRef, FullCodec, + FullEncode, Input, OptionBool, Output, WrapperTypeDecode, WrapperTypeEncode, + }, + compact::{Compact, CompactAs, CompactLen, CompactRef, HasCompact}, + decode_all::DecodeAll, + decode_finished::DecodeFinished, + depth_limit::DecodeLimit, + encode_append::EncodeAppend, + encode_like::{EncodeLike, Ref}, + error::Error, + joiner::Joiner, + keyedvec::KeyedVec, +}; #[cfg(feature = "max-encoded-len")] pub use const_encoded_len::ConstEncodedLen; +#[cfg(feature = "max-encoded-len")] +pub use max_encoded_len::MaxEncodedLen; /// Derive macro for [`MaxEncodedLen`][max_encoded_len::MaxEncodedLen]. /// @@ -117,9 +112,10 @@ pub use const_encoded_len::ConstEncodedLen; /// /// # Within other macros /// -/// Sometimes the `MaxEncodedLen` trait and macro are used within another macro, and it can't be -/// guaranteed that the `parity_scale_codec` module is available at the call site. In that case, the -/// macro should reexport the `parity_scale_codec` module and specify the path to the reexport: +/// Sometimes the `MaxEncodedLen` trait and macro are used within another macro, and it can't +/// be guaranteed that the `parity_scale_codec` module is available at the call site. In that +/// case, the macro should reexport the `parity_scale_codec` module and specify the path to the +/// reexport: /// /// ```ignore /// pub use parity_scale_codec as codec; diff --git a/src/max_encoded_len.rs b/src/max_encoded_len.rs index 1e857595..2c08dc81 100644 --- a/src/max_encoded_len.rs +++ b/src/max_encoded_len.rs @@ -15,10 +15,15 @@ //! `trait MaxEncodedLen` bounds the maximum encoded length of items. -use crate::{Compact, Encode}; +use crate::{alloc::boxed::Box, Compact, Encode}; +use core::{ + marker::PhantomData, + mem, + num::*, + ops::{Range, RangeInclusive}, + time::Duration, +}; use impl_trait_for_tuples::impl_for_tuples; -use core::{mem, marker::PhantomData, num::*, ops::{Range, RangeInclusive}, time::Duration}; -use crate::alloc::boxed::Box; #[cfg(target_has_atomic = "ptr")] use crate::alloc::sync::Arc; @@ -47,9 +52,27 @@ macro_rules! impl_primitives { } impl_primitives!( - u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, bool, - NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroI8, NonZeroI16, NonZeroI32, - NonZeroI64, NonZeroI128 + u8, + i8, + u16, + i16, + u32, + i32, + u64, + i64, + u128, + i128, + bool, + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128, + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroI128 ); macro_rules! impl_compact { @@ -78,7 +101,8 @@ impl_compact!( u128 => 17; ); -// impl_for_tuples for values 19 and higher fails because that's where the WrapperTypeEncode impl stops. +// impl_for_tuples for values 19 and higher fails because that's where the WrapperTypeEncode impl +// stops. #[impl_for_tuples(18)] impl MaxEncodedLen for Tuple { fn max_encoded_len() -> usize { @@ -96,7 +120,7 @@ impl MaxEncodedLen for [T; N] { impl MaxEncodedLen for Box { fn max_encoded_len() -> usize { - T::max_encoded_len() + T::max_encoded_len() } } @@ -131,19 +155,19 @@ impl MaxEncodedLen for PhantomData { impl MaxEncodedLen for Duration { fn max_encoded_len() -> usize { - u64::max_encoded_len() + u32::max_encoded_len() + u64::max_encoded_len() + u32::max_encoded_len() } } impl MaxEncodedLen for Range { fn max_encoded_len() -> usize { - T::max_encoded_len().saturating_mul(2) + T::max_encoded_len().saturating_mul(2) } } impl MaxEncodedLen for RangeInclusive { fn max_encoded_len() -> usize { - T::max_encoded_len().saturating_mul(2) + T::max_encoded_len().saturating_mul(2) } } diff --git a/tests/chain-error.rs b/tests/chain-error.rs index b8c764be..9503bd9b 100644 --- a/tests/chain-error.rs +++ b/tests/chain-error.rs @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -use parity_scale_codec_derive::Decode as DeriveDecode; use parity_scale_codec::Decode; +use parity_scale_codec_derive::Decode as DeriveDecode; #[derive(DeriveDecode, Debug)] struct Wrapper(T); #[derive(DeriveDecode, Debug)] struct StructNamed { - _foo: u16 + _foo: u16, } #[derive(DeriveDecode, Debug)] @@ -28,7 +28,7 @@ struct StructUnnamed(u16); #[derive(DeriveDecode, Debug)] enum E { - VariantNamed { _foo: u16, }, + VariantNamed { _foo: u16 }, VariantUnnamed(u16), } @@ -65,10 +65,7 @@ fn full_error_enum_unknown_variant() { let encoded = vec![2]; let err = r#"Could not decode `E`, variant doesn't exist"#; - assert_eq!( - E::decode(&mut &encoded[..]).unwrap_err().to_string(), - String::from(err), - ); + assert_eq!(E::decode(&mut &encoded[..]).unwrap_err().to_string(), String::from(err),); } #[test] @@ -78,10 +75,7 @@ fn full_error_enum_named_field() { Not enough data to fill buffer "#; - assert_eq!( - E::decode(&mut &encoded[..]).unwrap_err().to_string(), - String::from(err), - ); + assert_eq!(E::decode(&mut &encoded[..]).unwrap_err().to_string(), String::from(err),); } #[test] @@ -91,8 +85,5 @@ fn full_error_enum_unnamed_field() { Not enough data to fill buffer "#; - assert_eq!( - E::decode(&mut &encoded[..]).unwrap_err().to_string(), - String::from(err), - ); + assert_eq!(E::decode(&mut &encoded[..]).unwrap_err().to_string(), String::from(err),); } diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs index 6924aa37..6a15e95b 100644 --- a/tests/max_encoded_len.rs +++ b/tests/max_encoded_len.rs @@ -80,7 +80,6 @@ fn compact_field_max_length() { ); } - #[derive(Encode, MaxEncodedLen)] struct CompactFieldGenerics { #[codec(compact)] @@ -90,10 +89,7 @@ struct CompactFieldGenerics { #[test] fn compact_field_generics_max_length() { - assert_eq!( - CompactFieldGenerics::::max_encoded_len(), - CompactField::max_encoded_len() - ); + assert_eq!(CompactFieldGenerics::::max_encoded_len(), CompactField::max_encoded_len()); } #[derive(Encode, MaxEncodedLen)] diff --git a/tests/mod.rs b/tests/mod.rs index 93d2595b..952d6f2a 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -679,15 +679,17 @@ fn decoding_a_huge_boxed_newtype_array_does_not_overflow_the_stack() { fn decoding_two_indirectly_boxed_arrays_works() { // This test will fail if the check for `#[repr(transparent)]` in the derive crate // doesn't work when implementing `Decode::decode_into`. - #[derive(DeriveDecode)] - #[derive(PartialEq, Eq, Debug)] + #[derive(DeriveDecode, PartialEq, Eq, Debug)] struct SmallArrays([u8; 2], [u8; 2]); #[derive(DeriveDecode)] struct SmallArraysBox(Box); let data = &[1, 2, 3, 4]; - assert_eq!(*SmallArraysBox::decode(&mut data.as_slice()).unwrap().0, SmallArrays([1, 2], [3, 4])); + assert_eq!( + *SmallArraysBox::decode(&mut data.as_slice()).unwrap().0, + SmallArrays([1, 2], [3, 4]) + ); } #[test] @@ -708,7 +710,7 @@ fn zero_sized_types_are_properly_decoded_in_a_transparent_boxed_struct() { _zst_2: ZstTransparent, _zst_3: ZstNonTransparent, field: [u8; 1], - _zst_4: ConsumeByte + _zst_4: ConsumeByte, } #[derive(DeriveDecode)] diff --git a/tests/single_field_struct_encoding.rs b/tests/single_field_struct_encoding.rs index cbf5cf66..565a7d72 100644 --- a/tests/single_field_struct_encoding.rs +++ b/tests/single_field_struct_encoding.rs @@ -1,6 +1,8 @@ -use parity_scale_codec_derive::{Encode as DeriveEncode, Decode as DeriveDecode, CompactAs as DeriveCompactAs}; use parity_scale_codec::{Compact, Decode, Encode, HasCompact}; -use serde_derive::{Serialize, Deserialize}; +use parity_scale_codec_derive::{ + CompactAs as DeriveCompactAs, Decode as DeriveDecode, Encode as DeriveEncode, +}; +use serde_derive::{Deserialize, Serialize}; #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] struct S { @@ -35,7 +37,9 @@ struct U(u32); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] -struct U2 { a: u64 } +struct U2 { + a: u64, +} #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] diff --git a/tests/skip.rs b/tests/skip.rs index 0c9439cf..20f37311 100644 --- a/tests/skip.rs +++ b/tests/skip.rs @@ -1,5 +1,5 @@ -use parity_scale_codec_derive::{Encode as DeriveEncode, Decode as DeriveDecode}; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Decode, Encode}; +use parity_scale_codec_derive::{Decode as DeriveDecode, Encode as DeriveEncode}; #[test] fn enum_struct_test() { @@ -9,9 +9,9 @@ fn enum_struct_test() { #[derive(PartialEq, Debug)] struct UncodecUndefaultType; -use parity_scale_codec_derive::{Encode as DeriveEncode, Decode as DeriveDecode}; + use parity_scale_codec_derive::{Decode as DeriveDecode, Encode as DeriveEncode}; #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode)] - enum Enum { + enum Enum { #[codec(skip)] A(S), B { @@ -19,26 +19,18 @@ use parity_scale_codec_derive::{Encode as DeriveEncode, Decode as DeriveDecode}; _b1: T, b2: u32, }, - C( - #[codec(skip)] - T, - u32, - ), + C(#[codec(skip)] T, u32), } #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode)] - struct StructNamed { + struct StructNamed { #[codec(skip)] a: T, b: u32, } #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode)] - struct StructUnnamed( - #[codec(skip)] - T, - u32, - ); + struct StructUnnamed(#[codec(skip)] T, u32); let ea: Enum = Enum::A(UncodecUndefaultType); let eb: Enum = Enum::B { _b1: UncodecType, b2: 1 }; @@ -70,7 +62,7 @@ fn skip_enum_struct_inner_variant() { some_named: u32, #[codec(skip)] ignore: Option, - } + }, } let encoded = Enum::Data { some_named: 1, ignore: Some(1) }.encode(); diff --git a/tests/type_inference.rs b/tests/type_inference.rs index 97967632..613e7aa5 100644 --- a/tests/type_inference.rs +++ b/tests/type_inference.rs @@ -14,8 +14,8 @@ //! Test for type inference issue in decode. -use parity_scale_codec_derive::Decode as DeriveDecode; use parity_scale_codec::Decode; +use parity_scale_codec_derive::Decode as DeriveDecode; pub trait Trait { type Value; @@ -24,10 +24,7 @@ pub trait Trait { #[derive(DeriveDecode)] pub enum A { - _C( - (T::AccountId, T::AccountId), - Vec<(T::Value, T::Value)>, - ), + _C((T::AccountId, T::AccountId), Vec<(T::Value, T::Value)>), } #[derive(DeriveDecode)] diff --git a/tests/variant_number.rs b/tests/variant_number.rs index 54a900d3..9bdaba0a 100644 --- a/tests/variant_number.rs +++ b/tests/variant_number.rs @@ -1,5 +1,5 @@ -use parity_scale_codec_derive::Encode as DeriveEncode; use parity_scale_codec::Encode; +use parity_scale_codec_derive::Encode as DeriveEncode; #[test] fn discriminant_variant_counted_in_default_index() { From fa95ed81e6638472e4f397360e6b865329d8f30b Mon Sep 17 00:00:00 2001 From: Alexander Kalankhodzhaev Date: Tue, 30 Apr 2024 21:24:17 +0700 Subject: [PATCH 238/286] Fix PrefixInput read (#582) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: fix typo * fix: PrefixInput read --------- Co-authored-by: Bastian Köcher --- src/codec.rs | 2 +- src/compact.rs | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index 6beebad2..c8d9e40d 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -75,7 +75,7 @@ pub trait Input { /// Descend into nested reference when decoding. /// This is called when decoding a new refence-based instance, - /// such as `Vec` or `Box`. Currently all such types are + /// such as `Vec` or `Box`. Currently, all such types are /// allocated on the heap. fn descend_ref(&mut self) -> Result<(), Error> { Ok(()) diff --git a/src/compact.rs b/src/compact.rs index 9299db6b..71563d50 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -64,8 +64,11 @@ impl<'a, T: 'a + Input> Input for PrefixInput<'a, T> { } fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + if buffer.is_empty() { + return Ok(()); + } match self.prefix.take() { - Some(v) if !buffer.is_empty() => { + Some(v) => { buffer[0] = v; self.input.read(&mut buffer[1..]) }, @@ -693,6 +696,16 @@ impl Decode for Compact { mod tests { use super::*; + #[test] + fn prefix_input_empty_read_unchanged() { + let mut input = PrefixInput { prefix: Some(1), input: &mut &vec![2, 3, 4][..] }; + assert_eq!(input.remaining_len(), Ok(Some(4))); + let mut empty_buf = []; + assert_eq!(input.read(&mut empty_buf[..]), Ok(())); + assert_eq!(input.remaining_len(), Ok(Some(4))); + assert_eq!(input.read_byte(), Ok(1)); + } + #[test] fn compact_128_encoding_works() { let tests = [ From a7d323c99d7432e6b72125ef43e3fcca17050684 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 21:43:44 +0200 Subject: [PATCH 239/286] Bump serde from 1.0.199 to 1.0.200 (#585) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.199 to 1.0.200. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.199...v1.0.200) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99b8867d..367da6db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -881,18 +881,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 22317957..5c968a60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.199", default-features = false, optional = true } +serde = { version = "1.0.200", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From d8e3e9f37950e6521af8d4d8a2a035e24c3d713a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 21:31:35 +0200 Subject: [PATCH 240/286] Bump trybuild from 1.0.91 to 1.0.94 (#589) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.91 to 1.0.94. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.91...1.0.94) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 11 ++--------- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 367da6db..2750c510 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -561,12 +561,6 @@ dependencies = [ "libc", ] -[[package]] -name = "once_cell" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" - [[package]] name = "oorandom" version = "11.1.3" @@ -1032,12 +1026,11 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.91" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad7eb6319ebadebca3dacf1f85a93bc54b73dd81b9036795f73de7ddfe27d5a" +checksum = "bfe21c256d6fba8499cf9d9b1c24971bec43a369d81c52e024adc7670cf112df" dependencies = [ "glob", - "once_cell", "serde", "serde_derive", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 5c968a60..2dc0ced9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.3.1" -trybuild = "1.0.91" +trybuild = "1.0.94" paste = "1" [[bench]] From 65c58b341c8733a93545536a9f677f7a60513813 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 22:44:31 +0200 Subject: [PATCH 241/286] Bump proc-macro2 from 1.0.81 to 1.0.82 (#588) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.81 to 1.0.82. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.81...1.0.82) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2750c510..91b3d6d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,9 +656,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index f0c8bb59..ae4369c3 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.36" -proc-macro2 = "1.0.81" +proc-macro2 = "1.0.82" proc-macro-crate = "3.1.0" [dev-dependencies] From 8c922a59fcafbacb331e0d1f26501df583d7a45c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 23:33:01 +0200 Subject: [PATCH 242/286] Bump serde from 1.0.200 to 1.0.201 (#592) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.200 to 1.0.201. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.200...v1.0.201) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91b3d6d5..e8d7ffc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,18 +875,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 2dc0ced9..286f7b28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.200", default-features = false, optional = true } +serde = { version = "1.0.201", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 0c5c1c44f68520d9819909071e70c93d8e378312 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 22:30:41 +0200 Subject: [PATCH 243/286] Bump trybuild from 1.0.94 to 1.0.95 (#593) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.94 to 1.0.95. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.94...1.0.95) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e8d7ffc6..e35215ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,9 +1026,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe21c256d6fba8499cf9d9b1c24971bec43a369d81c52e024adc7670cf112df" +checksum = "4ddb747392ea12569d501a5bbca08852e4c8cd88b92566074b2243b8846f09e6" dependencies = [ "glob", "serde", diff --git a/Cargo.toml b/Cargo.toml index 286f7b28..e1f3317b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.3.1" -trybuild = "1.0.94" +trybuild = "1.0.95" paste = "1" [[bench]] From 463fae16eeee34c05cb0c3308bfdbc37aff46bba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 16:40:13 +0200 Subject: [PATCH 244/286] Bump paste from 1.0.14 to 1.0.15 (#594) Bumps [paste](https://github.com/dtolnay/paste) from 1.0.14 to 1.0.15. - [Release notes](https://github.com/dtolnay/paste/releases) - [Commits](https://github.com/dtolnay/paste/compare/1.0.14...1.0.15) --- updated-dependencies: - dependency-name: paste dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e35215ec..72851cfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -607,9 +607,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "plotters" From 24e3877a09b62dc0f6beadbe4ccc7094743a50a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Szab=C3=B3?= Date: Tue, 14 May 2024 10:58:13 +0300 Subject: [PATCH 245/286] Add the repository field to Cargo.toml (#595) --- derive/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/derive/Cargo.toml b/derive/Cargo.toml index ae4369c3..f32ca279 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -6,6 +6,7 @@ authors = ["Parity Technologies "] license = "Apache-2.0" edition = "2021" rust-version = "1.56.1" +repository = "https://github.com/paritytech/parity-scale-codec" [lib] proc-macro = true From 00ca61923178988db8fb34616ff952a0be355648 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 21:32:21 +0200 Subject: [PATCH 246/286] Bump serde from 1.0.201 to 1.0.202 (#596) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.201 to 1.0.202. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.201...v1.0.202) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72851cfd..06ed102d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,18 +875,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.201" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index e1f3317b..af8ec90c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.201", default-features = false, optional = true } +serde = { version = "1.0.202", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 9dd3f402567ca5efd38fb9a77cb9152eb6df94ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 17:09:07 +0200 Subject: [PATCH 247/286] Bump trybuild from 1.0.95 to 1.0.96 (#597) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.95 to 1.0.96. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.95...1.0.96) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06ed102d..c21695d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,9 +1026,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.95" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddb747392ea12569d501a5bbca08852e4c8cd88b92566074b2243b8846f09e6" +checksum = "33a5f13f11071020bb12de7a16b925d2d58636175c20c11dc5f96cb64bb6c9b3" dependencies = [ "glob", "serde", diff --git a/Cargo.toml b/Cargo.toml index af8ec90c..a810eb01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.3.1" -trybuild = "1.0.95" +trybuild = "1.0.96" paste = "1" [[bench]] From 684c34c2107029ef89ff59b396e66b658c9cb81f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 00:33:53 +0200 Subject: [PATCH 248/286] Bump proc-macro2 from 1.0.82 to 1.0.83 (#598) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.82 to 1.0.83. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.82...1.0.83) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c21695d8..cd2d055a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,9 +656,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index f32ca279..03967761 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.36" -proc-macro2 = "1.0.82" +proc-macro2 = "1.0.83" proc-macro-crate = "3.1.0" [dev-dependencies] From 5e582753797bbd3e0d1f2dc88b6d19d11998b813 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 17:43:25 +0200 Subject: [PATCH 249/286] --- (#599) updated-dependencies: - dependency-name: honggfuzz dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 12 ++++++------ fuzzer/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd2d055a..c1b384db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -399,9 +399,9 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "honggfuzz" -version = "0.5.55" +version = "0.5.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848e9c511092e0daa0a35a63e8e6e475a3e8f870741448b9f6028d69b142f18e" +checksum = "7c76b6234c13c9ea73946d1379d33186151148e0da231506b964b44f3d023505" dependencies = [ "arbitrary", "lazy_static", @@ -492,9 +492,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" @@ -525,9 +525,9 @@ checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.10" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" dependencies = [ "libc", ] diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 9ace1624..56642e4d 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -8,6 +8,6 @@ publish = false [dependencies] parity-scale-codec = { path = "..", features = ["derive", "bit-vec", "fuzz"] } -honggfuzz = "0.5.55" +honggfuzz = "0.5.56" arbitrary = { version = "1.3.2", features = ["derive"] } bitvec = { version = "1", features = ["alloc"] } From 056d5d64ed1f4260316a3e776d98edecc637a625 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 21:39:47 +0200 Subject: [PATCH 250/286] Bump proc-macro2 from 1.0.83 to 1.0.84 (#600) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.83 to 1.0.84. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.83...1.0.84) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1b384db..a3ce92b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,9 +656,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 03967761..c20fd4ff 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.36" -proc-macro2 = "1.0.83" +proc-macro2 = "1.0.84" proc-macro-crate = "3.1.0" [dev-dependencies] From 1b3e59435f3b296700e4f5f5e17e97eec8202dab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 18:56:33 +0200 Subject: [PATCH 251/286] Bump serde from 1.0.202 to 1.0.203 (#601) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.202 to 1.0.203. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.202...v1.0.203) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3ce92b4..0de54c2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,18 +875,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a810eb01..0ef93c75 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.202", default-features = false, optional = true } +serde = { version = "1.0.203", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 51106c8cf098f372852ea53a319e040b45c00abc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 22:12:09 +0200 Subject: [PATCH 252/286] Bump proc-macro2 from 1.0.84 to 1.0.85 (#604) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.84 to 1.0.85. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.84...1.0.85) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0de54c2f..abd19a0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,9 +656,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index c20fd4ff..49602f67 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.36" -proc-macro2 = "1.0.84" +proc-macro2 = "1.0.85" proc-macro-crate = "3.1.0" [dev-dependencies] From f8e228a4212bf7421800d2579f9cc4f623abf59a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jun 2024 17:29:41 +0200 Subject: [PATCH 253/286] Bump proc-macro2 from 1.0.85 to 1.0.86 (#606) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.85 to 1.0.86. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.85...1.0.86) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index abd19a0b..99b4590b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,9 +656,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 49602f67..99046c4a 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.36" -proc-macro2 = "1.0.85" +proc-macro2 = "1.0.86" proc-macro-crate = "3.1.0" [dev-dependencies] From 2f4fdaabcc0f9fac26fe76295bbf0a5d422303a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 20:10:15 +0200 Subject: [PATCH 254/286] Bump proptest from 1.3.1 to 1.5.0 (#607) Bumps [proptest](https://github.com/proptest-rs/proptest) from 1.3.1 to 1.5.0. - [Release notes](https://github.com/proptest-rs/proptest/releases) - [Changelog](https://github.com/proptest-rs/proptest/blob/master/CHANGELOG.md) - [Commits](https://github.com/proptest-rs/proptest/compare/v1.3.1...v1.5.0) --- updated-dependencies: - dependency-name: proptest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 10 +++++----- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99b4590b..83401fd1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -665,9 +665,9 @@ dependencies = [ [[package]] name = "proptest" -version = "1.3.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", @@ -677,7 +677,7 @@ dependencies = [ "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.7.5", + "regex-syntax 0.8.4", "rusty-fork", "tempfile", "unarray", @@ -807,9 +807,9 @@ checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rustc_version" diff --git a/Cargo.toml b/Cargo.toml index 0ef93c75..0d3f91e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ criterion = "0.4.0" serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" -proptest = "1.3.1" +proptest = "1.5.0" trybuild = "1.0.96" paste = "1" From 4682c529e16c71c9624b22ac7a715edf52a9eeaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 21:47:47 +0200 Subject: [PATCH 255/286] Bump serde from 1.0.203 to 1.0.204 (#611) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.203 to 1.0.204. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.203...v1.0.204) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83401fd1..b026434e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,18 +875,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 0d3f91e9..9e9e5f76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.203", default-features = false, optional = true } +serde = { version = "1.0.204", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 3ab562447b231376038f254f61db7d99816345a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 22:13:15 +0200 Subject: [PATCH 256/286] Bump trybuild from 1.0.96 to 1.0.97 (#612) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.96 to 1.0.97. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.96...1.0.97) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b026434e..0155afa9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,9 +1026,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a5f13f11071020bb12de7a16b925d2d58636175c20c11dc5f96cb64bb6c9b3" +checksum = "5b1e5645f2ee8025c2f1d75e1138f2dd034d74e6ba54620f3c569ba2a2a1ea06" dependencies = [ "glob", "serde", diff --git a/Cargo.toml b/Cargo.toml index 9e9e5f76..24d553c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.5.0" -trybuild = "1.0.96" +trybuild = "1.0.97" paste = "1" [[bench]] From 5af99fc47ffc90c470509bb7fb0636d452fcdbdf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 18:47:19 +0200 Subject: [PATCH 257/286] Bump bytes from 1.6.0 to 1.6.1 (#614) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.6.0 to 1.6.1. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.6.0...v1.6.1) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0155afa9..f28c33e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,9 +102,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytes" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "cast" From 36baa4f01c50211e7c89e1f24320902cc279a9a5 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Fri, 19 Jul 2024 08:33:51 +0300 Subject: [PATCH 258/286] Use `MAX_PREALLOCATION` consistently (#605) * Use `MAX_PREALLOCATION` consistently Use `MAX_PREALLOCATION` both when reading a vec from bytes and when decoding each element. * Simplify VecDeque::encode_to() * Increase MAX_PREALLOCATION Increase MAX_PREALLOCATION in order to avoid calling realloc too often --- src/codec.rs | 210 ++++++++++++++++++++++----------------------------- 1 file changed, 90 insertions(+), 120 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index c8d9e40d..3408acb7 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -47,7 +47,7 @@ use crate::{ DecodeFinished, Error, }; -pub(crate) const MAX_PREALLOCATION: usize = 4 * 1024; +pub(crate) const MAX_PREALLOCATION: usize = 16 * 1024; const A_BILLION: u32 = 1_000_000_000; /// Trait that allows reading of data into a slice. @@ -834,52 +834,6 @@ pub(crate) fn encode_slice_no_len(slice: &[T], de } } -/// Decode the vec (without a prepended len). -/// -/// This is equivalent to decode all elements one by one, but it is optimized in some -/// situation. -pub fn decode_vec_with_len( - input: &mut I, - len: usize, -) -> Result, Error> { - fn decode_unoptimized( - input: &mut I, - items_len: usize, - ) -> Result, Error> { - let input_capacity = input - .remaining_len()? - .unwrap_or(MAX_PREALLOCATION) - .checked_div(mem::size_of::()) - .unwrap_or(0); - let mut r = Vec::with_capacity(input_capacity.min(items_len)); - input.descend_ref()?; - for _ in 0..items_len { - r.push(T::decode(input)?); - } - input.ascend_ref(); - Ok(r) - } - - macro_rules! decode { - ( $ty:ty, $input:ident, $len:ident ) => {{ - if cfg!(target_endian = "little") || mem::size_of::() == 1 { - let vec = read_vec_from_u8s::<_, $ty>($input, $len)?; - Ok(unsafe { mem::transmute::, Vec>(vec) }) - } else { - decode_unoptimized($input, $len) - } - }}; - } - - with_type_info! { - ::TYPE_INFO, - decode(input, len), - { - decode_unoptimized(input, len) - }, - } -} - impl_for_non_zero! { NonZeroI8, NonZeroI16, @@ -1113,71 +1067,110 @@ impl Encode for [T] { } } -/// Create a `Vec` by casting directly from a buffer of read `u8`s -/// -/// The encoding of `T` must be equal to its binary representation, and size of `T` must be less or -/// equal to [`MAX_PREALLOCATION`]. -pub(crate) fn read_vec_from_u8s(input: &mut I, items_len: usize) -> Result, Error> +fn decode_vec_chunked(len: usize, mut decode_chunk: F) -> Result, Error> where - I: Input, - T: ToMutByteSlice + Default + Clone, + F: FnMut(&mut Vec, usize) -> Result<(), Error>, { debug_assert!(MAX_PREALLOCATION >= mem::size_of::(), "Invalid precondition"); + let chunk_len = MAX_PREALLOCATION / mem::size_of::(); - let byte_len = items_len - .checked_mul(mem::size_of::()) - .ok_or("Item is too big and cannot be allocated")?; + let mut decoded_vec = vec![]; + let mut num_undecoded_items = len; + while num_undecoded_items > 0 { + let chunk_len = chunk_len.min(num_undecoded_items); + decoded_vec.reserve_exact(chunk_len); - let input_len = input.remaining_len()?; + decode_chunk(&mut decoded_vec, chunk_len)?; - // If there is input len and it cannot be pre-allocated then return directly. - if input_len.map(|l| l < byte_len).unwrap_or(false) { - return Err("Not enough data to decode vector".into()); + num_undecoded_items = num_undecoded_items.saturating_sub(chunk_len); } - // In both these branches we're going to be creating and resizing a Vec, - // but casting it to a &mut [u8] for reading. - - // Note: we checked that if input_len is some then it can preallocated. - let r = if input_len.is_some() || byte_len < MAX_PREALLOCATION { - // Here we pre-allocate the whole buffer. - let mut items: Vec = vec![Default::default(); items_len]; - let bytes_slice = items.as_mut_byte_slice(); - input.read(bytes_slice)?; + Ok(decoded_vec) +} - items - } else { - // An allowed number of preallocated item. - // Note: `MAX_PREALLOCATION` is expected to be more or equal to size of `T`, precondition. - let max_preallocated_items = MAX_PREALLOCATION / mem::size_of::(); +/// Create a `Vec` by casting directly from a buffer of read `u8`s +/// +/// The encoding of `T` must be equal to its binary representation, and size of `T` must be less +/// or equal to [`MAX_PREALLOCATION`]. +fn read_vec_from_u8s(input: &mut I, len: usize) -> Result, Error> +where + T: ToMutByteSlice + Default + Clone, + I: Input, +{ + let byte_len = len + .checked_mul(mem::size_of::()) + .ok_or("Item is too big and cannot be allocated")?; - // Here we pre-allocate only the maximum pre-allocation - let mut items: Vec = vec![]; + // Check if there is enough data in the input buffer. + if let Some(input_len) = input.remaining_len()? { + if input_len < byte_len { + return Err("Not enough data to decode vector".into()); + } + } - let mut items_remains = items_len; + decode_vec_chunked(len, |decoded_vec, chunk_len| { + let decoded_vec_len = decoded_vec.len(); + let decoded_vec_size = decoded_vec_len * mem::size_of::(); + unsafe { + decoded_vec.set_len(decoded_vec_len + chunk_len); + } - while items_remains > 0 { - let items_len_read = max_preallocated_items.min(items_remains); + let bytes_slice = decoded_vec.as_mut_byte_slice(); + input.read(&mut bytes_slice[decoded_vec_size..]) + }) +} - let items_len_filled = items.len(); - let items_new_size = items_len_filled + items_len_read; +fn decode_vec_from_items(input: &mut I, len: usize) -> Result, Error> +where + T: Decode, + I: Input, +{ + // Check if there is enough data in the input buffer. + if let Some(input_len) = input.remaining_len()? { + if input_len < len { + return Err("Not enough data to decode vector".into()); + } + } - items.reserve_exact(items_len_read); - unsafe { - items.set_len(items_new_size); - } + input.descend_ref()?; + let vec = decode_vec_chunked(len, |decoded_vec, chunk_len| { + for _ in 0..chunk_len { + decoded_vec.push(T::decode(input)?); + } - let bytes_slice = items.as_mut_byte_slice(); - let bytes_len_filled = items_len_filled * mem::size_of::(); - input.read(&mut bytes_slice[bytes_len_filled..])?; + Ok(()) + })?; + input.ascend_ref(); - items_remains = items_remains.saturating_sub(items_len_read); - } + Ok(vec) +} - items - }; +/// Decode the vec (without a prepended len). +/// +/// This is equivalent to decode all elements one by one, but it is optimized in some +/// situation. +pub fn decode_vec_with_len( + input: &mut I, + len: usize, +) -> Result, Error> { + macro_rules! decode { + ( $ty:ty, $input:ident, $len:ident ) => {{ + if cfg!(target_endian = "little") || mem::size_of::() == 1 { + let vec = read_vec_from_u8s::<$ty, _>($input, $len)?; + Ok(unsafe { mem::transmute::, Vec>(vec) }) + } else { + decode_vec_from_items::($input, $len) + } + }}; + } - Ok(r) + with_type_info! { + ::TYPE_INFO, + decode(input, len), + { + decode_vec_from_items::(input, len) + }, + } } impl WrapperTypeEncode for Vec {} @@ -1260,32 +1253,9 @@ impl Encode for VecDeque { fn encode_to(&self, dest: &mut W) { compact_encode_len_to(dest, self.len()).expect("Compact encodes length"); - macro_rules! encode_to { - ( $ty:ty, $self:ident, $dest:ident ) => {{ - if cfg!(target_endian = "little") || mem::size_of::() == 1 { - let slices = $self.as_slices(); - let typed = - unsafe { core::mem::transmute::<(&[T], &[T]), (&[$ty], &[$ty])>(slices) }; - - $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.0)); - $dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.1)); - } else { - for item in $self { - item.encode_to($dest); - } - } - }}; - } - - with_type_info! { - ::TYPE_INFO, - encode_to(self, dest), - { - for item in self { - item.encode_to(dest); - } - }, - } + let slices = self.as_slices(); + encode_slice_no_len(slices.0, dest); + encode_slice_no_len(slices.1, dest); } } From a388fa9dc30526080d0ef6df3010ab83ca6ded9d Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Tue, 23 Jul 2024 15:33:27 +0300 Subject: [PATCH 259/286] Follow-up on #605 (#615) * Address #605 code review comments * Check MAX_PREALLOCATION >= mem::size_of:: statically * Update CI image to paritytech/ci-unified:bullseye-1.79.0 This reverts commit c54689d4b97b7b21a5b70a39fe10e1a254947fb2. --- .github/workflows/ci.yml | 2 +- .github/workflows/publish.yml | 2 +- benches/benches.rs | 2 +- derive/src/encode.rs | 8 +-- derive/src/lib.rs | 2 +- derive/src/max_encoded_len.rs | 20 ++------ fuzzer/src/main.rs | 7 ++- src/codec.rs | 33 ++++++------ src/compact.rs | 18 +++---- src/encode_append.rs | 6 +-- src/encode_like.rs | 2 +- tests/chain-error.rs | 14 +++--- tests/max_encoded_len_ui/crate_str.stderr | 50 ++++++++++++++----- .../max_encoded_len_ui/incomplete_attr.stderr | 50 ++++++++++++++----- .../missing_crate_specifier.stderr | 50 ++++++++++++++----- tests/max_encoded_len_ui/not_encode.stderr | 24 ++++----- tests/max_encoded_len_ui/not_mel.stderr | 5 +- .../unsupported_variant.stderr | 16 +++--- tests/mod.rs | 22 ++++---- tests/type_inference.rs | 2 +- 20 files changed, 205 insertions(+), 130 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da548f02..4f762bfe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: pull_request: env: - IMAGE: paritytech/ci-unified:bullseye-1.73.0 + IMAGE: paritytech/ci-unified:bullseye-1.79.0 concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2e9f3322..db290d49 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,7 +9,7 @@ jobs: publish-crate: runs-on: ubuntu-latest environment: release - container: paritytech/ci-unified:bullseye-1.73.0 + container: paritytech/ci-unified:bullseye-1.79.0 steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/benches/benches.rs b/benches/benches.rs index 16d225fa..8ac3b0c2 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -184,7 +184,7 @@ fn encode_decode_complex_type(c: &mut Criterion) { let complex_types = vec![ ComplexType { _val: 3, _other_val: 345634635, _vec: vec![1, 2, 3, 5, 6, 7] }, - ComplexType { _val: 1000, _other_val: 0980345634635, _vec: vec![1, 2, 3, 5, 6, 7] }, + ComplexType { _val: 1000, _other_val: 980345634635, _vec: vec![1, 2, 3, 5, 6, 7] }, ComplexType { _val: 43564, _other_val: 342342345634635, _vec: vec![1, 2, 3, 5, 6, 7] }, ]; diff --git a/derive/src/encode.rs b/derive/src/encode.rs index a29eec78..142bb439 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -103,7 +103,7 @@ enum FieldAttribute<'a> { None(&'a Field), Compact(&'a Field), EncodedAs { field: &'a Field, encoded_as: &'a TokenStream }, - Skip(&'a Field), + Skip, } fn iterate_over_fields( @@ -138,7 +138,7 @@ where } else if let Some(ref encoded_as) = encoded_as { field_handler(field, FieldAttribute::EncodedAs { field: f, encoded_as }) } else if skip { - field_handler(field, FieldAttribute::Skip(f)) + field_handler(field, FieldAttribute::Skip) } else { field_handler(field, FieldAttribute::None(f)) } @@ -191,7 +191,7 @@ where } } }, - FieldAttribute::Skip(_) => quote! { + FieldAttribute::Skip => quote! { let _ = #field; }, }, @@ -236,7 +236,7 @@ where )) } }, - FieldAttribute::Skip(_) => quote!(), + FieldAttribute::Skip => quote!(), }, |recurse| { quote! { diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 47c26dc4..a74f6262 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -309,7 +309,7 @@ pub fn compact_as_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStr (&field.ty, quote!(&self.#field_name), constructor) }, Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => { - let recurse = fields.unnamed.iter().enumerate().map(|(_, f)| { + let recurse = fields.unnamed.iter().map(|f| { let val_or_default = val_or_default(f); quote_spanned!(f.span()=> #val_or_default) }); diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index 008ffd28..c3c30abd 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -66,20 +66,10 @@ pub fn derive_max_encoded_len(input: proc_macro::TokenStream) -> proc_macro::Tok /// generate an expression to sum up the max encoded length from several fields fn fields_length_expr(fields: &Fields, crate_path: &syn::Path) -> proc_macro2::TokenStream { let fields_iter: Box> = match fields { - Fields::Named(ref fields) => Box::new(fields.named.iter().filter_map(|field| { - if should_skip(&field.attrs) { - None - } else { - Some(field) - } - })), - Fields::Unnamed(ref fields) => Box::new(fields.unnamed.iter().filter_map(|field| { - if should_skip(&field.attrs) { - None - } else { - Some(field) - } - })), + Fields::Named(ref fields) => + Box::new(fields.named.iter().filter(|field| !should_skip(&field.attrs))), + Fields::Unnamed(ref fields) => + Box::new(fields.unnamed.iter().filter(|field| !should_skip(&field.attrs))), Fields::Unit => Box::new(std::iter::empty()), }; // expands to an expression like @@ -94,7 +84,7 @@ fn fields_length_expr(fields: &Fields, crate_path: &syn::Path) -> proc_macro2::T // caused the issue. let expansion = fields_iter.map(|field| { let ty = &field.ty; - if utils::is_compact(&field) { + if utils::is_compact(field) { quote_spanned! { ty.span() => .saturating_add( <<#ty as #crate_path::HasCompact>::Type as #crate_path::MaxEncodedLen>::max_encoded_len() diff --git a/fuzzer/src/main.rs b/fuzzer/src/main.rs index fba804c9..198058e6 100644 --- a/fuzzer/src/main.rs +++ b/fuzzer/src/main.rs @@ -47,8 +47,13 @@ pub enum MockEnum { Empty, Unit(u32), UnitVec(Vec), - Complex { data: Vec, bitvec: BitVecWrapper, string: String }, + Complex { + data: Vec, + bitvec: BitVecWrapper, + string: String, + }, Mock(MockStruct), + #[allow(clippy::type_complexity)] NestedVec(Vec>>>>>>>>), } diff --git a/src/codec.rs b/src/codec.rs index 3408acb7..664116c7 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -1071,8 +1071,10 @@ fn decode_vec_chunked(len: usize, mut decode_chunk: F) -> Result, E where F: FnMut(&mut Vec, usize) -> Result<(), Error>, { - debug_assert!(MAX_PREALLOCATION >= mem::size_of::(), "Invalid precondition"); - let chunk_len = MAX_PREALLOCATION / mem::size_of::(); + const { assert!(MAX_PREALLOCATION >= mem::size_of::()) } + // we have to account for the fact that `mem::size_of::` can be 0 for types like `()` + // for example. + let chunk_len = MAX_PREALLOCATION.checked_div(mem::size_of::()).unwrap_or(usize::MAX); let mut decoded_vec = vec![]; let mut num_undecoded_items = len; @@ -1082,7 +1084,7 @@ where decode_chunk(&mut decoded_vec, chunk_len)?; - num_undecoded_items = num_undecoded_items.saturating_sub(chunk_len); + num_undecoded_items -= chunk_len; } Ok(decoded_vec) @@ -1125,13 +1127,6 @@ where T: Decode, I: Input, { - // Check if there is enough data in the input buffer. - if let Some(input_len) = input.remaining_len()? { - if input_len < len { - return Err("Not enough data to decode vector".into()); - } - } - input.descend_ref()?; let vec = decode_vec_chunked(len, |decoded_vec, chunk_len| { for _ in 0..chunk_len { @@ -1668,6 +1663,14 @@ mod tests { assert_eq!(>::decode(&mut &encoded[..]).unwrap(), value); } + #[test] + fn vec_of_empty_tuples_encoded_as_expected() { + let value = vec![(), (), (), (), ()]; + let encoded = value.encode(); + assert_eq!(hexify(&encoded), "14"); + assert_eq!(>::decode(&mut &encoded[..]).unwrap(), value); + } + #[cfg(feature = "bytes")] #[test] fn bytes_works_as_expected() { @@ -1699,7 +1702,7 @@ mod tests { assert_eq!(decoded, &b"hello"[..]); // The `slice_ref` will panic if the `decoded` is not a subslice of `encoded`. - assert_eq!(encoded.slice_ref(&decoded), &b"hello"[..]); + assert_eq!(encoded.slice_ref(decoded), &b"hello"[..]); } fn test_encode_length(thing: &T, len: usize) { @@ -1890,8 +1893,8 @@ mod tests { fn boolean() { assert_eq!(true.encode(), vec![1]); assert_eq!(false.encode(), vec![0]); - assert_eq!(bool::decode(&mut &[1][..]).unwrap(), true); - assert_eq!(bool::decode(&mut &[0][..]).unwrap(), false); + assert!(bool::decode(&mut &[1][..]).unwrap()); + assert!(!bool::decode(&mut &[0][..]).unwrap()); } #[test] @@ -1908,7 +1911,7 @@ mod tests { let encoded = data.encode(); let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); - assert!(decoded.iter().all(|v| data.contains(&v))); + assert!(decoded.iter().all(|v| data.contains(v))); assert_eq!(data.len(), decoded.len()); let encoded = decoded.encode(); @@ -1939,7 +1942,7 @@ mod tests { let num_nanos = 37; let duration = Duration::new(num_secs, num_nanos); - let expected = (num_secs, num_nanos as u32).encode(); + let expected = (num_secs, num_nanos).encode(); assert_eq!(duration.encode(), expected); assert_eq!(Duration::decode(&mut &expected[..]).unwrap(), duration); diff --git a/src/compact.rs b/src/compact.rs index 71563d50..db5b1768 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -735,7 +735,7 @@ mod tests { (u128::MAX, 17), ]; for &(n, l) in &tests { - let encoded = Compact(n as u128).encode(); + let encoded = Compact(n).encode(); assert_eq!(encoded.len(), l); assert_eq!(Compact::compact_len(&n), l); assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); @@ -761,7 +761,7 @@ mod tests { (u64::MAX, 9), ]; for &(n, l) in &tests { - let encoded = Compact(n as u64).encode(); + let encoded = Compact(n).encode(); assert_eq!(encoded.len(), l); assert_eq!(Compact::compact_len(&n), l); assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); @@ -781,7 +781,7 @@ mod tests { (u32::MAX, 5), ]; for &(n, l) in &tests { - let encoded = Compact(n as u32).encode(); + let encoded = Compact(n).encode(); assert_eq!(encoded.len(), l); assert_eq!(Compact::compact_len(&n), l); assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); @@ -792,7 +792,7 @@ mod tests { fn compact_16_encoding_works() { let tests = [(0u16, 1usize), (63, 1), (64, 2), (16383, 2), (16384, 4), (65535, 4)]; for &(n, l) in &tests { - let encoded = Compact(n as u16).encode(); + let encoded = Compact(n).encode(); assert_eq!(encoded.len(), l); assert_eq!(Compact::compact_len(&n), l); assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); @@ -804,7 +804,7 @@ mod tests { fn compact_8_encoding_works() { let tests = [(0u8, 1usize), (63, 1), (64, 2), (255, 2)]; for &(n, l) in &tests { - let encoded = Compact(n as u8).encode(); + let encoded = Compact(n).encode(); assert_eq!(encoded.len(), l); assert_eq!(Compact::compact_len(&n), l); assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); @@ -840,7 +840,7 @@ mod tests { ]; for &(n, s) in &tests { // Verify u64 encoding - let encoded = Compact(n as u64).encode(); + let encoded = Compact(n).encode(); assert_eq!(hexify(&encoded), s); assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); @@ -849,19 +849,19 @@ mod tests { assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u32); let encoded = Compact(n as u32).encode(); assert_eq!(hexify(&encoded), s); - assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u64); + assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); } if n <= u16::MAX as u64 { assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u16); let encoded = Compact(n as u16).encode(); assert_eq!(hexify(&encoded), s); - assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u64); + assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); } if n <= u8::MAX as u64 { assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u8); let encoded = Compact(n as u8).encode(); assert_eq!(hexify(&encoded), s); - assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n as u64); + assert_eq!(>::decode(&mut &encoded[..]).unwrap().0, n); } } } diff --git a/src/encode_append.rs b/src/encode_append.rs index 82cf4f81..bb992fd8 100644 --- a/src/encode_append.rs +++ b/src/encode_append.rs @@ -160,7 +160,7 @@ mod tests { #[test] fn vec_encode_append_multiple_items_works() { let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| { - as EncodeAppend>::append_or_new(encoded, &[v, v, v, v]).unwrap() + as EncodeAppend>::append_or_new(encoded, [v, v, v, v]).unwrap() }); let decoded = Vec::::decode(&mut &encoded[..]).unwrap(); @@ -184,7 +184,7 @@ mod tests { #[test] fn vecdeque_encode_append_multiple_items_works() { let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| { - as EncodeAppend>::append_or_new(encoded, &[v, v, v, v]).unwrap() + as EncodeAppend>::append_or_new(encoded, [v, v, v, v]).unwrap() }); let decoded = VecDeque::::decode(&mut &encoded[..]).unwrap(); @@ -228,7 +228,7 @@ mod tests { #[test] fn vec_encode_like_append_works() { let encoded = (0..TEST_VALUE).fold(Vec::new(), |encoded, v| { - as EncodeAppend>::append_or_new(encoded, std::iter::once(Box::new(v as u32))) + as EncodeAppend>::append_or_new(encoded, std::iter::once(Box::new(v))) .unwrap() }); diff --git a/src/encode_like.rs b/src/encode_like.rs index 80fc2947..8280b85d 100644 --- a/src/encode_like.rs +++ b/src/encode_like.rs @@ -122,7 +122,7 @@ mod tests { #[test] fn vec_and_slice_are_working() { let slice: &[u8] = &[1, 2, 3, 4]; - let data: Vec = slice.iter().copied().collect(); + let data: Vec = slice.to_vec(); let data_encoded = data.encode(); let slice_encoded = ComplexStuff::>::complex_method(&slice); diff --git a/tests/chain-error.rs b/tests/chain-error.rs index 9503bd9b..49062905 100644 --- a/tests/chain-error.rs +++ b/tests/chain-error.rs @@ -24,17 +24,17 @@ struct StructNamed { } #[derive(DeriveDecode, Debug)] -struct StructUnnamed(u16); +struct StructUnnamed(#[allow(dead_code)] u16); #[derive(DeriveDecode, Debug)] enum E { VariantNamed { _foo: u16 }, - VariantUnnamed(u16), + VariantUnnamed(#[allow(dead_code)] u16), } #[test] fn full_error_struct_named() { - let encoded = vec![0]; + let encoded = [0]; let err = r#"Could not decode `Wrapper.0`: Could not decode `StructNamed::_foo`: Not enough data to fill buffer @@ -48,7 +48,7 @@ fn full_error_struct_named() { #[test] fn full_error_struct_unnamed() { - let encoded = vec![0]; + let encoded = [0]; let err = r#"Could not decode `Wrapper.0`: Could not decode `StructUnnamed.0`: Not enough data to fill buffer @@ -62,7 +62,7 @@ fn full_error_struct_unnamed() { #[test] fn full_error_enum_unknown_variant() { - let encoded = vec![2]; + let encoded = [2]; let err = r#"Could not decode `E`, variant doesn't exist"#; assert_eq!(E::decode(&mut &encoded[..]).unwrap_err().to_string(), String::from(err),); @@ -70,7 +70,7 @@ fn full_error_enum_unknown_variant() { #[test] fn full_error_enum_named_field() { - let encoded = vec![0, 0]; + let encoded = [0, 0]; let err = r#"Could not decode `E::VariantNamed::_foo`: Not enough data to fill buffer "#; @@ -80,7 +80,7 @@ fn full_error_enum_named_field() { #[test] fn full_error_enum_unnamed_field() { - let encoded = vec![1, 0]; + let encoded = [1, 0]; let err = r#"Could not decode `E::VariantUnnamed.0`: Not enough data to fill buffer "#; diff --git a/tests/max_encoded_len_ui/crate_str.stderr b/tests/max_encoded_len_ui/crate_str.stderr index 23a451f6..0583b229 100644 --- a/tests/max_encoded_len_ui/crate_str.stderr +++ b/tests/max_encoded_len_ui/crate_str.stderr @@ -4,25 +4,51 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = pa 4 | #[codec(crate = "parity_scale_codec")] | ^^^^^ -error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied +error[E0277]: the trait bound `Example: Encode` is not satisfied --> tests/max_encoded_len_ui/crate_str.rs:5:8 | 5 | struct Example; - | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` | - = help: the following other types implement trait `WrapperTypeEncode`: - Box - Cow<'a, T> - parity_scale_codec::Ref<'a, T, U> - Rc - Arc - Vec - String - &T - &mut T + = help: the following other types implement trait `Encode`: + () + (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + and $N others = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { | ^^^^^^ required by this bound in `MaxEncodedLen` + +error[E0277]: the trait bound `Example: Encode` is not satisfied + --> tests/max_encoded_len_ui/crate_str.rs:8:10 + | +8 | let _ = Example::max_encoded_len(); + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` + | + = help: the following other types implement trait `Encode`: + () + (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + and $N others + = note: required for `Example` to implement `Encode` +note: required by a bound in `max_encoded_len` + --> src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ^^^^^^ required by this bound in `MaxEncodedLen::max_encoded_len` + | /// Upper bound, in bytes, of the maximum encoded size of this item. + | fn max_encoded_len() -> usize; + | --------------- required by a bound in this associated function diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr index b5ab07c7..a7649942 100644 --- a/tests/max_encoded_len_ui/incomplete_attr.stderr +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -4,25 +4,51 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = pa 4 | #[codec(crate)] | ^^^^^ -error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied +error[E0277]: the trait bound `Example: Encode` is not satisfied --> tests/max_encoded_len_ui/incomplete_attr.rs:5:8 | 5 | struct Example; - | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` | - = help: the following other types implement trait `WrapperTypeEncode`: - Box - Cow<'a, T> - parity_scale_codec::Ref<'a, T, U> - Rc - Arc - Vec - String - &T - &mut T + = help: the following other types implement trait `Encode`: + () + (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + and $N others = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { | ^^^^^^ required by this bound in `MaxEncodedLen` + +error[E0277]: the trait bound `Example: Encode` is not satisfied + --> tests/max_encoded_len_ui/incomplete_attr.rs:8:10 + | +8 | let _ = Example::max_encoded_len(); + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` + | + = help: the following other types implement trait `Encode`: + () + (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + and $N others + = note: required for `Example` to implement `Encode` +note: required by a bound in `max_encoded_len` + --> src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ^^^^^^ required by this bound in `MaxEncodedLen::max_encoded_len` + | /// Upper bound, in bytes, of the maximum encoded size of this item. + | fn max_encoded_len() -> usize; + | --------------- required by a bound in this associated function diff --git a/tests/max_encoded_len_ui/missing_crate_specifier.stderr b/tests/max_encoded_len_ui/missing_crate_specifier.stderr index 68e98a6a..b575f512 100644 --- a/tests/max_encoded_len_ui/missing_crate_specifier.stderr +++ b/tests/max_encoded_len_ui/missing_crate_specifier.stderr @@ -4,25 +4,51 @@ error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = pa 4 | #[codec(parity_scale_codec)] | ^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `Example: WrapperTypeEncode` is not satisfied +error[E0277]: the trait bound `Example: Encode` is not satisfied --> tests/max_encoded_len_ui/missing_crate_specifier.rs:5:8 | 5 | struct Example; - | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example` + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` | - = help: the following other types implement trait `WrapperTypeEncode`: - Box - Cow<'a, T> - parity_scale_codec::Ref<'a, T, U> - Rc - Arc - Vec - String - &T - &mut T + = help: the following other types implement trait `Encode`: + () + (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + and $N others = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs | | pub trait MaxEncodedLen: Encode { | ^^^^^^ required by this bound in `MaxEncodedLen` + +error[E0277]: the trait bound `Example: Encode` is not satisfied + --> tests/max_encoded_len_ui/missing_crate_specifier.rs:8:10 + | +8 | let _ = Example::max_encoded_len(); + | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` + | + = help: the following other types implement trait `Encode`: + () + (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + and $N others + = note: required for `Example` to implement `Encode` +note: required by a bound in `max_encoded_len` + --> src/max_encoded_len.rs + | + | pub trait MaxEncodedLen: Encode { + | ^^^^^^ required by this bound in `MaxEncodedLen::max_encoded_len` + | /// Upper bound, in bytes, of the maximum encoded size of this item. + | fn max_encoded_len() -> usize; + | --------------- required by a bound in this associated function diff --git a/tests/max_encoded_len_ui/not_encode.stderr b/tests/max_encoded_len_ui/not_encode.stderr index b2fb1d85..cd0695a3 100644 --- a/tests/max_encoded_len_ui/not_encode.stderr +++ b/tests/max_encoded_len_ui/not_encode.stderr @@ -1,19 +1,19 @@ -error[E0277]: the trait bound `NotEncode: WrapperTypeEncode` is not satisfied +error[E0277]: the trait bound `NotEncode: Encode` is not satisfied --> tests/max_encoded_len_ui/not_encode.rs:4:8 | 4 | struct NotEncode; - | ^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `NotEncode` + | ^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `NotEncode`, which is required by `NotEncode: Encode` | - = help: the following other types implement trait `WrapperTypeEncode`: - Box - Cow<'a, T> - parity_scale_codec::Ref<'a, T, U> - Rc - Arc - Vec - String - &T - &mut T + = help: the following other types implement trait `Encode`: + () + (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) + and $N others = note: required for `NotEncode` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs diff --git a/tests/max_encoded_len_ui/not_mel.stderr b/tests/max_encoded_len_ui/not_mel.stderr index d0a0891c..5bf7e12d 100644 --- a/tests/max_encoded_len_ui/not_mel.stderr +++ b/tests/max_encoded_len_ui/not_mel.stderr @@ -5,10 +5,7 @@ error[E0599]: the function or associated item `max_encoded_len` exists for struc | ------------- doesn't satisfy `NotMel: MaxEncodedLen` ... 7 | struct Generic { - | ----------------- - | | - | function or associated item `max_encoded_len` not found for this struct - | doesn't satisfy `Generic: MaxEncodedLen` + | ----------------- function or associated item `max_encoded_len` not found for this struct because it doesn't satisfy `Generic: MaxEncodedLen` ... 12 | let _ = Generic::::max_encoded_len(); | ^^^^^^^^^^^^^^^ function or associated item cannot be called on `Generic` due to unsatisfied trait bounds diff --git a/tests/max_encoded_len_ui/unsupported_variant.stderr b/tests/max_encoded_len_ui/unsupported_variant.stderr index 848139a1..c4a48c60 100644 --- a/tests/max_encoded_len_ui/unsupported_variant.stderr +++ b/tests/max_encoded_len_ui/unsupported_variant.stderr @@ -5,12 +5,12 @@ error[E0277]: the trait bound `NotMel: MaxEncodedLen` is not satisfied | ^^^^^^ the trait `MaxEncodedLen` is not implemented for `NotMel` | = help: the following other types implement trait `MaxEncodedLen`: - bool - i8 - i16 - i32 - i64 - i128 - u8 - u16 + () + (TupleElement0, TupleElement1) + (TupleElement0, TupleElement1, TupleElement2) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) and $N others diff --git a/tests/mod.rs b/tests/mod.rs index 952d6f2a..ff86c646 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -234,11 +234,11 @@ const U64_TEST_COMPACT_VALUES: &[(u64, usize)] = &[ (16384, 4), (1073741823, 4), (1073741824, 5), - (1 << 32 - 1, 5), + (1 << (32 - 1), 5), (1 << 32, 6), (1 << 40, 7), (1 << 48, 8), - (1 << 56 - 1, 8), + (1 << (56 - 1), 8), (1 << 56, 9), (u64::MAX, 9), ]; @@ -251,11 +251,11 @@ const U64_TEST_COMPACT_VALUES_FOR_ENUM: &[(u64, usize)] = &[ (16384, 5), (1073741823, 5), (1073741824, 6), - (1 << 32 - 1, 6), + (1 << (32 - 1), 6), (1 << 32, 7), (1 << 40, 8), (1 << 48, 9), - (1 << 56 - 1, 9), + (1 << (56 - 1), 9), (1 << 56, 10), (u64::MAX, 10), ]; @@ -351,6 +351,7 @@ fn associated_type_bounds() { } #[test] +#[allow(non_local_definitions)] fn generic_bound_encoded_as() { // This struct does not impl Codec nor HasCompact struct StructEncodeAsRef; @@ -669,7 +670,7 @@ fn decoding_a_huge_boxed_newtype_array_does_not_overflow_the_stack() { struct HugeArrayNewtype([u8; 100 * 1024 * 1024]); #[derive(DeriveDecode)] - struct HugeArrayNewtypeBox(Box); + struct HugeArrayNewtypeBox(#[allow(dead_code)] Box); let data = &[]; assert!(HugeArrayNewtypeBox::decode(&mut data.as_slice()).is_err()); @@ -714,7 +715,7 @@ fn zero_sized_types_are_properly_decoded_in_a_transparent_boxed_struct() { } #[derive(DeriveDecode)] - struct NewtypeWithZstBox(Box); + struct NewtypeWithZstBox(#[allow(dead_code)] Box); impl Decode for ConsumeByte { fn decode(input: &mut I) -> Result { @@ -761,11 +762,11 @@ fn decoding_an_array_of_boxed_zero_sized_types_works() { #[test] fn incomplete_decoding_of_an_array_drops_partially_read_elements_if_reading_fails() { thread_local! { - pub static COUNTER: core::cell::Cell = core::cell::Cell::new(0); + pub static COUNTER: core::cell::Cell = const { core::cell::Cell::new(0) }; } #[derive(DeriveDecode)] - struct Foobar(u8); + struct Foobar(#[allow(dead_code)] u8); impl Drop for Foobar { fn drop(&mut self) { @@ -786,10 +787,10 @@ fn incomplete_decoding_of_an_array_drops_partially_read_elements_if_reading_fail #[test] fn incomplete_decoding_of_an_array_drops_partially_read_elements_if_reading_panics() { thread_local! { - pub static COUNTER: core::cell::Cell = core::cell::Cell::new(0); + pub static COUNTER: core::cell::Cell = const { core::cell::Cell::new(0) }; } - struct Foobar(u8); + struct Foobar(#[allow(dead_code)] u8); impl Decode for Foobar { fn decode(input: &mut I) -> Result { @@ -825,6 +826,7 @@ fn deserializing_of_big_recursively_nested_enum_works() { struct Data([u8; 1472]); #[derive(PartialEq, Eq, DeriveDecode, DeriveEncode)] + #[allow(clippy::large_enum_variant)] enum Enum { Nested(Vec), Data(Data), diff --git a/tests/type_inference.rs b/tests/type_inference.rs index 613e7aa5..dc91d7f5 100644 --- a/tests/type_inference.rs +++ b/tests/type_inference.rs @@ -28,4 +28,4 @@ pub enum A { } #[derive(DeriveDecode)] -pub struct B((T::AccountId, T::AccountId), Vec<(T::Value, T::Value)>); +pub struct B((T::AccountId, T::AccountId), #[allow(dead_code)] Vec<(T::Value, T::Value)>); From 4687bb503b7b98f1a19e346817ea7cd7f93ef087 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:00:20 +0200 Subject: [PATCH 260/286] Bump trybuild from 1.0.97 to 1.0.98 (#617) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.97 to 1.0.98. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.97...1.0.98) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f28c33e9..83626cff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,9 +1026,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1e5645f2ee8025c2f1d75e1138f2dd034d74e6ba54620f3c569ba2a2a1ea06" +checksum = "b55265878356bdd85c9baa15859c87de93b2bf1f33acf752040a561e4a228f62" dependencies = [ "glob", "serde", diff --git a/Cargo.toml b/Cargo.toml index 24d553c9..be390be0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.5.0" -trybuild = "1.0.97" +trybuild = "1.0.98" paste = "1" [[bench]] From ec0a8e1231b2da7ec5e17a24f1fbbe6c8aa7b7cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:31:41 +0200 Subject: [PATCH 261/286] Bump bytes from 1.6.1 to 1.7.1 (#620) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.6.1 to 1.7.1. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.6.1...v1.7.1) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83626cff..c823ce12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,9 +102,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cast" From bc659798c200ff1ca8f949fdaa40efeab6809c1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:32:43 +0200 Subject: [PATCH 262/286] Bump trybuild from 1.0.98 to 1.0.99 (#619) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.98 to 1.0.99. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.98...1.0.99) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c823ce12..11aebeab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,9 +1026,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55265878356bdd85c9baa15859c87de93b2bf1f33acf752040a561e4a228f62" +checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8" dependencies = [ "glob", "serde", diff --git a/Cargo.toml b/Cargo.toml index be390be0..e842834f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.5.0" -trybuild = "1.0.98" +trybuild = "1.0.99" paste = "1" [[bench]] From 1dba1fabf63d63788284a1a78a2ca6a02d210a70 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Fri, 23 Aug 2024 17:44:22 +0900 Subject: [PATCH 263/286] Fix `MaxEncodedLen` derive macro for enum with skipped variant (#622) * fix enum skip variant max encoded len * trigger CI * trigger CI This reverts commit 40f632b90663e49ef79b1d19d054c672d46b22d5. * fmt * fix warnings --- derive/src/max_encoded_len.rs | 15 ++++++++------ tests/max_encoded_len.rs | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index c3c30abd..b9bcf580 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -119,12 +119,15 @@ fn data_length_expr(data: &Data, crate_path: &syn::Path) -> proc_macro2::TokenSt // // Each variant expression's sum is computed the way an equivalent struct's would be. - let expansion = data.variants.iter().map(|variant| { - let variant_expression = fields_length_expr(&variant.fields, crate_path); - quote! { - .max(#variant_expression) - } - }); + let expansion = + data.variants.iter().filter(|variant| !should_skip(&variant.attrs)).map( + |variant| { + let variant_expression = fields_length_expr(&variant.fields, crate_path); + quote! { + .max(#variant_expression) + } + }, + ); quote! { 0_usize #( #expansion )* .saturating_add(1) diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs index 6a15e95b..ceb2810c 100644 --- a/tests/max_encoded_len.rs +++ b/tests/max_encoded_len.rs @@ -246,3 +246,41 @@ fn skip_type_params() { assert_eq!(SomeData::::max_encoded_len(), 4); } + +#[test] +fn skip_enum_struct_test() { + #[derive(Default)] + struct NoCodecType; + + struct NoCodecNoDefaultType; + + #[derive(Encode, Decode, MaxEncodedLen)] + enum Enum { + #[codec(skip)] + A(S), + B { + #[codec(skip)] + _b1: T, + b2: u32, + }, + C(#[codec(skip)] T, u32), + } + + #[derive(Encode, Decode, MaxEncodedLen)] + struct StructNamed { + #[codec(skip)] + a: T, + b: u32, + } + + #[derive(Encode, Decode, MaxEncodedLen)] + struct StructUnnamed(#[codec(skip)] T, u32); + + assert_eq!(Enum::::max_encoded_len(), 5); + assert_eq!(StructNamed::::max_encoded_len(), 4); + assert_eq!(StructUnnamed::::max_encoded_len(), 4); + + // Use the fields to avoid unused warnings. + let _ = Enum::::A(NoCodecNoDefaultType); + let _ = StructNamed:: { a: NoCodecType, b: 0 }.a; +} From 230c7da81fa6c2e539dda965a0e331ed60d5c29c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 17:32:49 +0200 Subject: [PATCH 264/286] Bump serde from 1.0.204 to 1.0.209 (#625) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.204 to 1.0.209. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.204...v1.0.209) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11aebeab..cedc4ef6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,18 +875,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index e842834f..4d4b80ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.204", default-features = false, optional = true } +serde = { version = "1.0.209", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From 5b665014537c2f7c65bef05105342f1beb2d843a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 17:55:08 +0200 Subject: [PATCH 265/286] Bump arrayvec from 0.7.4 to 0.7.6 (#624) Bumps [arrayvec](https://github.com/bluss/arrayvec) from 0.7.4 to 0.7.6. - [Release notes](https://github.com/bluss/arrayvec/releases) - [Changelog](https://github.com/bluss/arrayvec/blob/master/CHANGELOG.md) - [Commits](https://github.com/bluss/arrayvec/compare/0.7.4...0.7.6) --- updated-dependencies: - dependency-name: arrayvec dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cedc4ef6..b2fd9993 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "atty" From fb00f2ef49efab05f278f4c7fd3e953934339973 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 23:17:14 +0200 Subject: [PATCH 266/286] Bump quote from 1.0.36 to 1.0.37 (#626) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.36 to 1.0.37. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.36...1.0.37) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2fd9993..ee8a1a42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,9 +702,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 99046c4a..3cd387c9 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } -quote = "1.0.36" +quote = "1.0.37" proc-macro2 = "1.0.86" proc-macro-crate = "3.1.0" From 224b834554897d578af7a56ad9f62b487ecb1153 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 22:56:46 +0200 Subject: [PATCH 267/286] Bump serde from 1.0.209 to 1.0.210 (#627) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.209 to 1.0.210. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.209...v1.0.210) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee8a1a42..12079950 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,18 +875,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 4d4b80ea..d13333e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.209", default-features = false, optional = true } +serde = { version = "1.0.210", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } bytes = { version = "1", default-features = false, optional = true } From f8f2d9c7b398ccc64ccb3fdacab94772d7a011c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:17:08 +0200 Subject: [PATCH 268/286] Bump bytes from 1.7.1 to 1.7.2 (#629) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.7.1 to 1.7.2. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.7.1...v1.7.2) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12079950..d7b7497d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,9 +102,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cast" From 2c61d4ab70dfa157556430546441cd2deb5031f2 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Tue, 24 Sep 2024 19:20:43 +0900 Subject: [PATCH 269/286] Introduce `CountedInput`. a wrapper which counts the number of bytes successfully read (#630) * impl * use u32 * Revert "use u32" This reverts commit 72bd97c607fadaf4d79f3dc9f203af91f428ee65. * easy impl * fix tests * fmt --- src/counted_input.rs | 149 +++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 + 2 files changed, 151 insertions(+) create mode 100644 src/counted_input.rs diff --git a/src/counted_input.rs b/src/counted_input.rs new file mode 100644 index 00000000..d25cb410 --- /dev/null +++ b/src/counted_input.rs @@ -0,0 +1,149 @@ +// Copyright 2017-2024 Parity Technologies +// +// 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. + +/// A wrapper for `Input` which tracks the number fo bytes that are successfully read. +/// +/// If inner `Input` fails to read, the counter is not incremented. +/// +/// It can count until `u64::MAX - 1` accurately then saturate. +pub struct CountedInput<'a, I: crate::Input> { + input: &'a mut I, + counter: u64, +} + +impl<'a, I: crate::Input> CountedInput<'a, I> { + /// Create a new `CountedInput` with the given input. + pub fn new(input: &'a mut I) -> Self { + Self { input, counter: 0 } + } + + /// Get the number of bytes successfully read. + pub fn count(&self) -> u64 { + self.counter + } +} + +impl crate::Input for CountedInput<'_, I> { + fn remaining_len(&mut self) -> Result, crate::Error> { + self.input.remaining_len() + } + + fn read(&mut self, into: &mut [u8]) -> Result<(), crate::Error> { + self.input.read(into).map(|r| { + self.counter = self.counter.saturating_add(into.len().try_into().unwrap_or(u64::MAX)); + r + }) + } + + fn read_byte(&mut self) -> Result { + self.input.read_byte().map(|r| { + self.counter = self.counter.saturating_add(1); + r + }) + } + + fn ascend_ref(&mut self) { + self.input.ascend_ref() + } + + fn descend_ref(&mut self) -> Result<(), crate::Error> { + self.input.descend_ref() + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::Input; + + #[test] + fn test_counted_input_input_impl() { + let mut input = &[1u8, 2, 3, 4, 5][..]; + let mut counted_input = CountedInput::new(&mut input); + + assert_eq!(counted_input.remaining_len().unwrap(), Some(5)); + assert_eq!(counted_input.count(), 0); + + counted_input.read_byte().unwrap(); + + assert_eq!(counted_input.remaining_len().unwrap(), Some(4)); + assert_eq!(counted_input.count(), 1); + + counted_input.read(&mut [0u8; 2][..]).unwrap(); + + assert_eq!(counted_input.remaining_len().unwrap(), Some(2)); + assert_eq!(counted_input.count(), 3); + + counted_input.ascend_ref(); + counted_input.descend_ref().unwrap(); + + counted_input.read(&mut [0u8; 2][..]).unwrap(); + + assert_eq!(counted_input.remaining_len().unwrap(), Some(0)); + assert_eq!(counted_input.count(), 5); + + assert_eq!(counted_input.read_byte(), Err("Not enough data to fill buffer".into())); + + assert_eq!(counted_input.remaining_len().unwrap(), Some(0)); + assert_eq!(counted_input.count(), 5); + + assert_eq!( + counted_input.read(&mut [0u8; 2][..]), + Err("Not enough data to fill buffer".into()) + ); + + assert_eq!(counted_input.remaining_len().unwrap(), Some(0)); + assert_eq!(counted_input.count(), 5); + } + + #[test] + fn test_counted_input_max_count_read_byte() { + let max_exact_count = u64::MAX - 1; + + let mut input = &[0u8; 1000][..]; + let mut counted_input = CountedInput::new(&mut input); + + counted_input.counter = max_exact_count; + + assert_eq!(counted_input.count(), max_exact_count); + + counted_input.read_byte().unwrap(); + + assert_eq!(counted_input.count(), u64::MAX); + + counted_input.read_byte().unwrap(); + + assert_eq!(counted_input.count(), u64::MAX); + } + + #[test] + fn test_counted_input_max_count_read() { + let max_exact_count = u64::MAX - 1; + + let mut input = &[0u8; 1000][..]; + let mut counted_input = CountedInput::new(&mut input); + + counted_input.counter = max_exact_count; + + assert_eq!(counted_input.count(), max_exact_count); + + counted_input.read(&mut [0u8; 2][..]).unwrap(); + + assert_eq!(counted_input.count(), u64::MAX); + + counted_input.read(&mut [0u8; 2][..]).unwrap(); + + assert_eq!(counted_input.count(), u64::MAX); + } +} diff --git a/src/lib.rs b/src/lib.rs index 9f95cf69..b178239c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,6 +45,7 @@ mod codec; mod compact; #[cfg(feature = "max-encoded-len")] mod const_encoded_len; +mod counted_input; mod decode_all; mod decode_finished; mod depth_limit; @@ -66,6 +67,7 @@ pub use self::{ FullEncode, Input, OptionBool, Output, WrapperTypeDecode, WrapperTypeEncode, }, compact::{Compact, CompactAs, CompactLen, CompactRef, HasCompact}, + counted_input::CountedInput, decode_all::DecodeAll, decode_finished::DecodeFinished, depth_limit::DecodeLimit, From f2823c3f4a675ce85774a5e02c7a711932aeb684 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 22:38:02 +0200 Subject: [PATCH 270/286] Bump proc-macro2 from 1.0.86 to 1.0.87 (#632) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.86 to 1.0.87. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.86...1.0.87) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7b7497d..a1ff410e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,9 +656,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 3cd387c9..ab437cab 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.37" -proc-macro2 = "1.0.86" +proc-macro2 = "1.0.87" proc-macro-crate = "3.1.0" [dev-dependencies] From be670ab51ffdce624d5921e469e64436a0550e42 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Wed, 9 Oct 2024 15:23:01 +0300 Subject: [PATCH 271/286] Decode with mem limit (#616) --- .github/workflows/ci.yml | 33 ++-- Cargo.lock | 9 +- Cargo.toml | 9 +- build.rs | 6 + derive/src/decode.rs | 98 +++++++---- derive/src/encode.rs | 27 ++- derive/src/lib.rs | 50 +++++- derive/src/trait_bounds.rs | 10 +- derive/src/utils.rs | 49 +++++- src/bit_vec.rs | 7 +- src/btree_utils.rs | 110 ++++++++++++ src/codec.rs | 160 +++++++++++++++--- src/compact.rs | 21 ++- src/depth_limit.rs | 4 + src/lib.rs | 5 + src/mem_tracking.rs | 97 +++++++++++ tests/clippy.rs | 4 +- tests/decode_with_mem_tracking_ui.rs | 22 +++ .../trait_bound_not_satisfied.rs | 11 ++ .../trait_bound_not_satisfied.stderr | 22 +++ tests/max_encoded_len_ui/crate_str.stderr | 2 +- .../max_encoded_len_ui/incomplete_attr.stderr | 2 +- .../missing_crate_specifier.stderr | 2 +- tests/mem_tracking.rs | 153 +++++++++++++++++ tests/mod.rs | 108 +++++++----- tests/single_field_struct_encoding.rs | 78 +++++++-- tests/skip.rs | 18 +- tests/type_inference.rs | 8 +- 28 files changed, 946 insertions(+), 179 deletions(-) create mode 100644 build.rs create mode 100644 src/btree_utils.rs create mode 100644 src/mem_tracking.rs create mode 100644 tests/decode_with_mem_tracking_ui.rs create mode 100644 tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.rs create mode 100644 tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.stderr create mode 100644 tests/mem_tracking.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f762bfe..471f61fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,10 +22,10 @@ jobs: - id: set_image run: echo "IMAGE=${{ env.IMAGE }}" >> $GITHUB_OUTPUT -# Checks + # Checks fmt: runs-on: ubuntu-latest - needs: [set-image] + needs: [ set-image ] container: ${{ needs.set-image.outputs.IMAGE }} steps: - name: Checkout code @@ -39,7 +39,7 @@ jobs: clippy: runs-on: ubuntu-latest - needs: [set-image] + needs: [ set-image ] container: ${{ needs.set-image.outputs.IMAGE }} steps: - name: Checkout code/. @@ -64,7 +64,7 @@ jobs: checks: runs-on: ubuntu-latest - needs: [set-image] + needs: [ set-image ] container: ${{ needs.set-image.outputs.IMAGE }} steps: - name: Checkout code @@ -99,10 +99,10 @@ jobs: export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' time cargo +stable check --verbose --features max-encoded-len -# Tests + # Tests tests: runs-on: ubuntu-latest - needs: [set-image] + needs: [ set-image ] container: ${{ needs.set-image.outputs.IMAGE }} steps: - name: Checkout code @@ -139,13 +139,18 @@ jobs: export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' time cargo +stable test --verbose --features max-encoded-len,std --no-default-features -# Benches + - name: Run Nightly Tests + run: | + export RUSTFLAGS='-Cdebug-assertions=y -Dwarnings' + time cargo +nightly test --verbose --lib btree_utils + + # Benches bench-rust-nightly: runs-on: ubuntu-latest - needs: [set-image] + needs: [ set-image ] strategy: matrix: - feature: [bit-vec,bytes,generic-array,derive,max-encoded-len] + feature: [ bit-vec,bytes,generic-array,derive,max-encoded-len ] container: ${{ needs.set-image.outputs.IMAGE }} steps: - name: Checkout code @@ -163,10 +168,10 @@ jobs: miri: runs-on: ubuntu-latest - needs: [set-image] + needs: [ set-image ] strategy: matrix: - feature: [bit-vec,bytes,generic-array,arbitrary] + feature: [ bit-vec,bytes,generic-array,arbitrary ] container: ${{ needs.set-image.outputs.IMAGE }} steps: - name: Checkout code @@ -184,11 +189,11 @@ jobs: export MIRIFLAGS='-Zmiri-disable-isolation' time cargo +nightly miri test --features ${{ matrix.feature }} --release -# Build + # Build build-linux-ubuntu-amd64: runs-on: ubuntu-latest - needs: [set-image, clippy, checks, tests] + needs: [ set-image, clippy, checks, tests ] container: ${{ needs.set-image.outputs.IMAGE }} steps: - name: Checkout code @@ -204,7 +209,7 @@ jobs: publish-dry-run: runs-on: ubuntu-latest - needs: [set-image, build-linux-ubuntu-amd64] + needs: [ set-image, build-linux-ubuntu-amd64 ] container: ${{ needs.set-image.outputs.IMAGE }} steps: - name: Checkout code diff --git a/Cargo.lock b/Cargo.lock index a1ff410e..8ffea3f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -575,7 +575,7 @@ checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "parity-scale-codec" -version = "3.6.8" +version = "3.7.0" dependencies = [ "arbitrary", "arrayvec", @@ -589,6 +589,7 @@ dependencies = [ "paste", "proptest", "quickcheck", + "rustversion", "serde", "serde_derive", "trybuild", @@ -834,6 +835,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + [[package]] name = "rusty-fork" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index d13333e2..b65d333a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,20 @@ [package] name = "parity-scale-codec" description = "SCALE - Simple Concatenating Aggregated Little Endians" -version = "3.6.8" +version = "3.7.0" authors = ["Parity Technologies "] license = "Apache-2.0" repository = "https://github.com/paritytech/parity-scale-codec" categories = ["encoding"] edition = "2021" +build = "build.rs" rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } serde = { version = "1.0.210", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } -bitvec = { version = "1", default-features = false, features = [ "alloc" ], optional = true } +bitvec = { version = "1", default-features = false, features = ["alloc"], optional = true } bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } generic-array = { version = "0.14.7", optional = true } @@ -28,6 +29,10 @@ quickcheck = "1.0" proptest = "1.5.0" trybuild = "1.0.99" paste = "1" +rustversion = "1" + +[build-dependencies] +rustversion = "1" [[bench]] name = "benches" diff --git a/build.rs b/build.rs new file mode 100644 index 00000000..76854863 --- /dev/null +++ b/build.rs @@ -0,0 +1,6 @@ +fn main() { + println!("cargo:rustc-check-cfg=cfg(nightly)"); + if rustversion::cfg!(nightly) { + println!("cargo:rustc-cfg=nightly"); + } +} diff --git a/derive/src/decode.rs b/derive/src/decode.rs index 7f2d08b2..1e228776 100644 --- a/derive/src/decode.rs +++ b/derive/src/decode.rs @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::utils; use proc_macro2::{Ident, Span, TokenStream}; +use quote::ToTokens; +use std::iter; use syn::{spanned::Spanned, Data, Error, Field, Fields}; -use crate::utils; - /// Generate function block for function `Decode::decode`. /// /// * data: data info of the type, @@ -31,33 +32,20 @@ pub fn quote( crate_path: &syn::Path, ) -> TokenStream { match *data { - Data::Struct(ref data) => match data.fields { - Fields::Named(_) | Fields::Unnamed(_) => create_instance( - quote! { #type_name #type_generics }, - &type_name.to_string(), - input, - &data.fields, - crate_path, - ), - Fields::Unit => { - quote_spanned! { data.fields.span() => - ::core::result::Result::Ok(#type_name) - } - }, - }, + Data::Struct(ref data) => create_instance( + quote! { #type_name #type_generics }, + &type_name.to_string(), + input, + &data.fields, + crate_path, + ), Data::Enum(ref data) => { - let data_variants = - || data.variants.iter().filter(|variant| !utils::should_skip(&variant.attrs)); - - if data_variants().count() > 256 { - return Error::new( - data.variants.span(), - "Currently only enums with at most 256 variants are encodable.", - ) - .to_compile_error(); - } + let variants = match utils::try_get_variants(data) { + Ok(variants) => variants, + Err(e) => return e.to_compile_error(), + }; - let recurse = data_variants().enumerate().map(|(i, v)| { + let recurse = variants.iter().enumerate().map(|(i, v)| { let name = &v.ident; let index = utils::variant_index(v, i); @@ -198,12 +186,12 @@ fn create_decode_expr( crate_path: &syn::Path, ) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); - let compact = utils::is_compact(field); + let compact = utils::get_compact_type(field, crate_path); let skip = utils::should_skip(&field.attrs); let res = quote!(__codec_res_edqy); - if encoded_as.is_some() as u8 + compact as u8 + skip as u8 > 1 { + if encoded_as.is_some() as u8 + compact.is_some() as u8 + skip as u8 > 1 { return Error::new( field.span(), "`encoded_as`, `compact` and `skip` can only be used one at a time!", @@ -213,13 +201,10 @@ fn create_decode_expr( let err_msg = format!("Could not decode `{}`", name); - if compact { - let field_type = &field.ty; + if let Some(compact) = compact { quote_spanned! { field.span() => { - let #res = < - <#field_type as #crate_path::HasCompact>::Type as #crate_path::Decode - >::decode(#input); + let #res = <#compact as #crate_path::Decode>::decode(#input); match #res { ::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)), ::core::result::Result::Ok(#res) => #res.into(), @@ -300,3 +285,48 @@ fn create_instance( }, } } + +pub fn quote_decode_with_mem_tracking_checks(data: &Data, crate_path: &syn::Path) -> TokenStream { + let fields: Box> = match data { + Data::Struct(data) => Box::new(data.fields.iter()), + Data::Enum(ref data) => { + let variants = match utils::try_get_variants(data) { + Ok(variants) => variants, + Err(e) => return e.to_compile_error(), + }; + + let mut fields: Box> = Box::new(iter::empty()); + for variant in variants { + fields = Box::new(fields.chain(variant.fields.iter())); + } + fields + }, + Data::Union(_) => { + return Error::new(Span::call_site(), "Union types are not supported.") + .to_compile_error(); + }, + }; + + let processed_fields = fields.filter_map(|field| { + if utils::should_skip(&field.attrs) { + return None; + } + + let field_type = if let Some(compact) = utils::get_compact_type(field, crate_path) { + compact + } else if let Some(encoded_as) = utils::get_encoded_as_type(field) { + encoded_as + } else { + field.ty.to_token_stream() + }; + Some(quote_spanned! {field.span() => #field_type}) + }); + + quote! { + fn check_field() {} + + #( + check_field::<#processed_fields>(); + )* + } +} diff --git a/derive/src/encode.rs b/derive/src/encode.rs index 142bb439..df7af38a 100644 --- a/derive/src/encode.rs +++ b/derive/src/encode.rs @@ -28,7 +28,7 @@ fn encode_single_field( crate_path: &syn::Path, ) -> TokenStream { let encoded_as = utils::get_encoded_as_type(field); - let compact = utils::is_compact(field); + let compact = utils::get_compact_type(field, crate_path); if utils::should_skip(&field.attrs) { return Error::new( @@ -38,7 +38,7 @@ fn encode_single_field( .to_compile_error(); } - if encoded_as.is_some() && compact { + if encoded_as.is_some() && compact.is_some() { return Error::new( Span::call_site(), "`encoded_as` and `compact` can not be used at the same time!", @@ -46,12 +46,11 @@ fn encode_single_field( .to_compile_error(); } - let final_field_variable = if compact { + let final_field_variable = if let Some(compact) = compact { let field_type = &field.ty; quote_spanned! { field.span() => { - <<#field_type as #crate_path::HasCompact>::Type as - #crate_path::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) + <#compact as #crate_path::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name) } } } else if let Some(encoded_as) = encoded_as { @@ -298,23 +297,17 @@ fn impl_encode(data: &Data, type_name: &Ident, crate_path: &syn::Path) -> TokenS Fields::Unit => [quote! { 0_usize }, quote!()], }, Data::Enum(ref data) => { - let data_variants = - || data.variants.iter().filter(|variant| !utils::should_skip(&variant.attrs)); - - if data_variants().count() > 256 { - return Error::new( - data.variants.span(), - "Currently only enums with at most 256 variants are encodable.", - ) - .to_compile_error(); - } + let variants = match utils::try_get_variants(data) { + Ok(variants) => variants, + Err(e) => return e.to_compile_error(), + }; // If the enum has no variants, we don't need to encode anything. - if data_variants().count() == 0 { + if variants.is_empty() { return quote!(); } - let recurse = data_variants().enumerate().map(|(i, f)| { + let recurse = variants.iter().enumerate().map(|(i, f)| { let name = &f.ident; let index = utils::variant_index(f, i); diff --git a/derive/src/lib.rs b/derive/src/lib.rs index a74f6262..2f9ea7d9 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -168,7 +168,7 @@ pub fn encode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream wrap_with_dummy_const(input, impl_block) } -/// Derive `parity_scale_codec::Decode` and for struct and enum. +/// Derive `parity_scale_codec::Decode` for struct and enum. /// /// see derive `Encode` documentation. #[proc_macro_derive(Decode, attributes(codec))] @@ -240,6 +240,54 @@ pub fn decode_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream wrap_with_dummy_const(input, impl_block) } +/// Derive `parity_scale_codec::DecodeWithMemTracking` for struct and enum. +#[proc_macro_derive(DecodeWithMemTracking, attributes(codec))] +pub fn decode_with_mem_tracking_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let mut input: DeriveInput = match syn::parse(input) { + Ok(input) => input, + Err(e) => return e.to_compile_error().into(), + }; + + if let Err(e) = utils::check_attributes(&input) { + return e.to_compile_error().into(); + } + + let crate_path = match codec_crate_path(&input.attrs) { + Ok(crate_path) => crate_path, + Err(error) => return error.into_compile_error().into(), + }; + + if let Err(e) = trait_bounds::add( + &input.ident, + &mut input.generics, + &input.data, + utils::custom_decode_with_mem_tracking_trait_bound(&input.attrs), + parse_quote!(#crate_path::DecodeWithMemTracking), + Some(parse_quote!(Default)), + utils::has_dumb_trait_bound(&input.attrs), + &crate_path, + ) { + return e.to_compile_error().into(); + } + + let name = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + + let decode_with_mem_tracking_checks = + decode::quote_decode_with_mem_tracking_checks(&input.data, &crate_path); + let impl_block = quote! { + fn check_struct #impl_generics() #where_clause { + #decode_with_mem_tracking_checks + } + + #[automatically_derived] + impl #impl_generics #crate_path::DecodeWithMemTracking for #name #ty_generics #where_clause { + } + }; + + wrap_with_dummy_const(input, impl_block) +} + /// Derive `parity_scale_codec::Compact` and `parity_scale_codec::CompactAs` for struct with single /// field. /// diff --git a/derive/src/trait_bounds.rs b/derive/src/trait_bounds.rs index 209e1bf6..40cb97db 100644 --- a/derive/src/trait_bounds.rs +++ b/derive/src/trait_bounds.rs @@ -162,10 +162,12 @@ pub fn add( .into_iter() .for_each(|ty| where_clause.predicates.push(parse_quote!(#ty : #codec_bound))); - let has_compact_bound: syn::Path = parse_quote!(#crate_path::HasCompact); - compact_types - .into_iter() - .for_each(|ty| where_clause.predicates.push(parse_quote!(#ty : #has_compact_bound))); + compact_types.into_iter().for_each(|ty| { + where_clause.predicates.push(parse_quote!(#ty : #crate_path::HasCompact)); + where_clause + .predicates + .push(parse_quote!(<#ty as #crate_path::HasCompact>::Type : #codec_bound)); + }); skip_types.into_iter().for_each(|ty| { let codec_skip_bound = codec_skip_bound.as_ref(); diff --git a/derive/src/utils.rs b/derive/src/utils.rs index 091a45ee..9f737afa 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -22,8 +22,9 @@ use std::str::FromStr; use proc_macro2::TokenStream; use quote::{quote, ToTokens}; use syn::{ - parse::Parse, punctuated::Punctuated, spanned::Spanned, token, Attribute, Data, DeriveInput, - Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, MetaNameValue, NestedMeta, Path, Variant, + parse::Parse, punctuated::Punctuated, spanned::Spanned, token, Attribute, Data, DataEnum, + DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, MetaNameValue, NestedMeta, + Path, Variant, }; fn find_meta_item<'a, F, R, I, M>(mut itr: I, mut pred: F) -> Option @@ -84,18 +85,24 @@ pub fn get_encoded_as_type(field: &Field) -> Option { }) } -/// Look for a `#[codec(compact)]` outer attribute on the given `Field`. -pub fn is_compact(field: &Field) -> bool { +/// Look for a `#[codec(compact)]` outer attribute on the given `Field`. If the attribute is found, +/// return the compact type associated with the field type. +pub fn get_compact_type(field: &Field, crate_path: &syn::Path) -> Option { find_meta_item(field.attrs.iter(), |meta| { if let NestedMeta::Meta(Meta::Path(ref path)) = meta { if path.is_ident("compact") { - return Some(()); + let field_type = &field.ty; + return Some(quote! {<#field_type as #crate_path::HasCompact>::Type}); } } None }) - .is_some() +} + +/// Look for a `#[codec(compact)]` outer attribute on the given `Field`. +pub fn is_compact(field: &Field) -> bool { + get_compact_type(field, &parse_quote!(::crate)).is_some() } /// Look for a `#[codec(skip)]` in the given attributes. @@ -229,6 +236,7 @@ impl Parse for CustomTraitBound { syn::custom_keyword!(encode_bound); syn::custom_keyword!(decode_bound); +syn::custom_keyword!(decode_with_mem_tracking_bound); syn::custom_keyword!(mel_bound); syn::custom_keyword!(skip_type_params); @@ -239,6 +247,15 @@ pub fn custom_decode_trait_bound(attrs: &[Attribute]) -> Option Option> { + find_meta_item(attrs.iter(), Some) +} + /// Look for a `#[codec(encode_bound(T: Encode))]` in the given attributes. /// /// If found, it should be used as trait bounds when deriving the `Encode` trait. @@ -405,11 +422,13 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { let top_error = "Invalid attribute: only `#[codec(dumb_trait_bound)]`, \ `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, \ - `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` \ - are accepted as top attribute"; + `#[codec(decode_bound(T: Decode))]`, \ + `#[codec(decode_bound_with_mem_tracking_bound(T: DecodeWithMemTracking))]` or \ + `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute"; if attr.path.is_ident("codec") && attr.parse_args::>().is_err() && attr.parse_args::>().is_err() && + attr.parse_args::>().is_err() && attr.parse_args::>().is_err() && codec_crate_path_inner(attr).is_none() { @@ -449,3 +468,17 @@ pub fn is_transparent(attrs: &[syn::Attribute]) -> bool { // TODO: When migrating to syn 2 the `"(transparent)"` needs to be changed into `"transparent"`. check_repr(attrs, "(transparent)") } + +pub fn try_get_variants(data: &DataEnum) -> Result, syn::Error> { + let data_variants: Vec<_> = + data.variants.iter().filter(|variant| !should_skip(&variant.attrs)).collect(); + + if data_variants.len() > 256 { + return Err(syn::Error::new( + data.variants.span(), + "Currently only enums with at most 256 variants are encodable/decodable.", + )) + } + + Ok(data_variants) +} diff --git a/src/bit_vec.rs b/src/bit_vec.rs index c4a00669..20d65120 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -15,7 +15,8 @@ //! `BitVec` specific serialization. use crate::{ - codec::decode_vec_with_len, Compact, Decode, Encode, EncodeLike, Error, Input, Output, + codec::decode_vec_with_len, Compact, Decode, DecodeWithMemTracking, Encode, EncodeLike, Error, + Input, Output, }; use bitvec::{ boxed::BitBox, order::BitOrder, slice::BitSlice, store::BitStore, vec::BitVec, view::BitView, @@ -74,6 +75,8 @@ impl Decode for BitVec { } } +impl DecodeWithMemTracking for BitVec {} + impl Encode for BitBox { fn encode_to(&self, dest: &mut W) { self.as_bitslice().encode_to(dest) @@ -88,6 +91,8 @@ impl Decode for BitBox { } } +impl DecodeWithMemTracking for BitBox {} + #[cfg(test)] mod tests { use super::*; diff --git a/src/btree_utils.rs b/src/btree_utils.rs new file mode 100644 index 00000000..e6c49da5 --- /dev/null +++ b/src/btree_utils.rs @@ -0,0 +1,110 @@ +// Copyright 2017-2018 Parity Technologies +// +// 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 core::mem::size_of; + +// Constants from rust's source: +// https://doc.rust-lang.org/src/alloc/collections/btree/node.rs.html#43-45 +const B: usize = 6; +const CAPACITY: usize = 2 * B - 1; +const MIN_LEN_AFTER_SPLIT: usize = B - 1; + +/// Estimate the mem size of a btree. +pub fn mem_size_of_btree(len: u32) -> usize { + if len == 0 { + return 0; + } + + // We try to estimate the size of the `InternalNode` struct from: + // https://doc.rust-lang.org/src/alloc/collections/btree/node.rs.html#97 + // A btree `LeafNode` has 2*B - 1 (K,V) pairs and (usize, u16, u16) overhead. + let leaf_node_size = size_of::<(usize, u16, u16, [T; CAPACITY])>(); + // An `InternalNode` additionally has 2*B `usize` overhead. + let internal_node_size = leaf_node_size + size_of::<[usize; 2 * B]>(); + // A node can contain between B - 1 and 2*B - 1 elements. We assume 2/3 occupancy. + let num_nodes = (len as usize).saturating_div((CAPACITY + MIN_LEN_AFTER_SPLIT) * 2 / 3); + + // If the tree has only one node, it's a leaf node. + if num_nodes == 0 { + return leaf_node_size; + } + num_nodes.saturating_mul(internal_node_size) +} + +#[cfg(test)] +#[cfg(not(miri))] +#[rustversion::nightly] +mod test { + use super::*; + use crate::alloc::{ + collections::{BTreeMap, BTreeSet}, + sync::{Arc, Mutex}, + }; + use core::{ + alloc::{AllocError, Allocator, Layout}, + ptr::NonNull, + }; + + #[derive(Clone)] + struct MockAllocator { + total: Arc>, + } + + unsafe impl Allocator for MockAllocator { + fn allocate(&self, layout: Layout) -> Result, AllocError> { + let ptr = std::alloc::System.allocate(layout); + if ptr.is_ok() { + *self.total.lock().unwrap() += layout.size(); + } + ptr + } + + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + *self.total.lock().unwrap() -= layout.size(); + std::alloc::System.deallocate(ptr, layout) + } + } + + fn check_btree_size(expected_size: usize, actual_size: Arc>) { + // Check that the margin of error is at most 25%. + assert!(*actual_size.lock().unwrap() as f64 * 0.75 <= expected_size as f64); + assert!(*actual_size.lock().unwrap() as f64 * 1.25 >= expected_size as f64); + } + + #[test] + fn mem_size_of_btree_works() { + let map_allocator = MockAllocator { total: Arc::new(Mutex::new(0)) }; + let map_actual_size = map_allocator.total.clone(); + let mut map = BTreeMap::::new_in(map_allocator); + + let set_allocator = MockAllocator { total: Arc::new(Mutex::new(0)) }; + let set_actual_size = set_allocator.total.clone(); + let mut set = BTreeSet::::new_in(set_allocator); + + for i in 0..1000000 { + map.insert(i, 0); + set.insert(i as u128); + + // For small number of elements, the differences between the expected size and + // the actual size can be higher. + if i > 100 { + let map_expected_size = mem_size_of_btree::<(u32, u32)>(map.len() as u32); + check_btree_size(map_expected_size, map_actual_size.clone()); + + let set_expected_size = mem_size_of_btree::(set.len() as u32); + check_btree_size(set_expected_size, set_actual_size.clone()); + } + } + } +} diff --git a/src/codec.rs b/src/codec.rs index 664116c7..1dce353a 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -44,6 +44,7 @@ use crate::{ }, compact::Compact, encode_like::EncodeLike, + mem_tracking::DecodeWithMemTracking, DecodeFinished, Error, }; @@ -85,6 +86,17 @@ pub trait Input { /// This is called when decoding reference-based type is finished. fn ascend_ref(&mut self) {} + /// Hook that is called before allocating memory on the heap. + /// + /// The aim is to get a reasonable approximation of memory usage, especially with variably + /// sized types like `Vec`s. Depending on the structure, it is acceptable to be off by a bit. + /// In some cases we might not track the memory used by internal sub-structures, and + /// also we don't take alignment or memory layouts into account. + /// But we should always track the memory used by the decoded data inside the type. + fn on_before_alloc_mem(&mut self, _size: usize) -> Result<(), Error> { + Ok(()) + } + /// !INTERNAL USE ONLY! /// /// Decodes a `bytes::Bytes`. @@ -440,6 +452,7 @@ impl Input for BytesCursor { return Err("Not enough data to fill buffer".into()); } + self.on_before_alloc_mem(length)?; Ok(self.bytes.split_to(length)) } } @@ -477,6 +490,9 @@ impl Decode for bytes::Bytes { } } +#[cfg(feature = "bytes")] +impl DecodeWithMemTracking for bytes::Bytes {} + impl Encode for X where T: Encode + ?Sized, @@ -538,6 +554,7 @@ impl WrapperTypeDecode for Box { // TODO: Use `Box::new_uninit` once that's stable. let layout = core::alloc::Layout::new::>(); + input.on_before_alloc_mem(layout.size())?; let ptr: *mut MaybeUninit = if layout.size() == 0 { core::ptr::NonNull::dangling().as_ptr() } else { @@ -576,6 +593,8 @@ impl WrapperTypeDecode for Box { } } +impl DecodeWithMemTracking for Box {} + impl WrapperTypeDecode for Rc { type Wrapped = T; @@ -588,6 +607,9 @@ impl WrapperTypeDecode for Rc { } } +// `Rc` uses `Box::::decode()` internally, so it supports `DecodeWithMemTracking`. +impl DecodeWithMemTracking for Rc {} + #[cfg(target_has_atomic = "ptr")] impl WrapperTypeDecode for Arc { type Wrapped = T; @@ -601,6 +623,9 @@ impl WrapperTypeDecode for Arc { } } +// `Arc` uses `Box::::decode()` internally, so it supports `DecodeWithMemTracking`. +impl DecodeWithMemTracking for Arc {} + impl Decode for X where T: Decode + Into, @@ -690,6 +715,8 @@ impl Decode for Result { } } +impl DecodeWithMemTracking for Result {} + /// Shim type because we can't do a specialised implementation for `Option` directly. #[derive(Eq, PartialEq, Clone, Copy)] pub struct OptionBool(pub Option); @@ -727,6 +754,8 @@ impl Decode for OptionBool { } } +impl DecodeWithMemTracking for OptionBool {} + impl, U: Encode> EncodeLike> for Option {} impl Encode for Option { @@ -763,6 +792,8 @@ impl Decode for Option { } } +impl DecodeWithMemTracking for Option {} + macro_rules! impl_for_non_zero { ( $( $name:ty ),* $(,)? ) => { $( @@ -792,6 +823,8 @@ macro_rules! impl_for_non_zero { .ok_or_else(|| Error::from("cannot create non-zero number from 0")) } } + + impl DecodeWithMemTracking for $name {} )* } } @@ -995,6 +1028,8 @@ impl Decode for [T; N] { } } +impl DecodeWithMemTracking for [T; N] {} + impl, U: Encode, const N: usize> EncodeLike<[U; N]> for [T; N] {} impl Encode for str { @@ -1024,6 +1059,11 @@ where } } +impl<'a, T: ToOwned + DecodeWithMemTracking> DecodeWithMemTracking for Cow<'a, T> where + Cow<'a, T>: Decode +{ +} + impl EncodeLike for PhantomData {} impl Encode for PhantomData { @@ -1036,12 +1076,16 @@ impl Decode for PhantomData { } } +impl DecodeWithMemTracking for PhantomData where PhantomData: Decode {} + impl Decode for String { fn decode(input: &mut I) -> Result { Self::from_utf8(Vec::decode(input)?).map_err(|_| "Invalid utf8 sequence".into()) } } +impl DecodeWithMemTracking for String {} + /// Writes the compact encoding of `len` do `dest`. pub(crate) fn compact_encode_len_to( dest: &mut W, @@ -1067,9 +1111,13 @@ impl Encode for [T] { } } -fn decode_vec_chunked(len: usize, mut decode_chunk: F) -> Result, Error> +fn decode_vec_chunked( + input: &mut I, + len: usize, + mut decode_chunk: F, +) -> Result, Error> where - F: FnMut(&mut Vec, usize) -> Result<(), Error>, + F: FnMut(&mut I, &mut Vec, usize) -> Result<(), Error>, { const { assert!(MAX_PREALLOCATION >= mem::size_of::()) } // we have to account for the fact that `mem::size_of::` can be 0 for types like `()` @@ -1080,9 +1128,10 @@ where let mut num_undecoded_items = len; while num_undecoded_items > 0 { let chunk_len = chunk_len.min(num_undecoded_items); + input.on_before_alloc_mem(chunk_len.saturating_mul(mem::size_of::()))?; decoded_vec.reserve_exact(chunk_len); - decode_chunk(&mut decoded_vec, chunk_len)?; + decode_chunk(input, &mut decoded_vec, chunk_len)?; num_undecoded_items -= chunk_len; } @@ -1110,7 +1159,7 @@ where } } - decode_vec_chunked(len, |decoded_vec, chunk_len| { + decode_vec_chunked(input, len, |input, decoded_vec, chunk_len| { let decoded_vec_len = decoded_vec.len(); let decoded_vec_size = decoded_vec_len * mem::size_of::(); unsafe { @@ -1128,7 +1177,7 @@ where I: Input, { input.descend_ref()?; - let vec = decode_vec_chunked(len, |decoded_vec, chunk_len| { + let vec = decode_vec_chunked(input, len, |input, decoded_vec, chunk_len| { for _ in 0..chunk_len { decoded_vec.push(T::decode(input)?); } @@ -1180,7 +1229,9 @@ impl Decode for Vec { } } -macro_rules! impl_codec_through_iterator { +impl DecodeWithMemTracking for Vec {} + +macro_rules! impl_encode_for_collection { ($( $type:ident { $( $generics:ident $( : $decode_additional:ident )? ),* } @@ -1189,7 +1240,7 @@ macro_rules! impl_codec_through_iterator { )*) => {$( impl<$( $generics: Encode ),*> Encode for $type<$( $generics, )*> { fn size_hint(&self) -> usize { - mem::size_of::() $( + mem::size_of::<$generics>() * self.len() )* + mem::size_of::() + mem::size_of::<($($generics,)*)>().saturating_mul(self.len()) } fn encode_to(&self, dest: &mut W) { @@ -1201,19 +1252,6 @@ macro_rules! impl_codec_through_iterator { } } - impl<$( $generics: Decode $( + $decode_additional )? ),*> Decode - for $type<$( $generics, )*> - { - fn decode(input: &mut I) -> Result { - >::decode(input).and_then(move |Compact(len)| { - input.descend_ref()?; - let result = Result::from_iter((0..len).map(|_| Decode::decode(input))); - input.ascend_ref(); - result - }) - } - } - impl<$( $impl_like_generics )*> EncodeLike<$type<$( $type_like_generics ),*>> for $type<$( $generics ),*> {} impl<$( $impl_like_generics )*> EncodeLike<&[( $( $type_like_generics, )* )]> @@ -1223,17 +1261,83 @@ macro_rules! impl_codec_through_iterator { )*} } -impl_codec_through_iterator! { +impl_encode_for_collection! { BTreeMap { K: Ord, V } { LikeK, LikeV} { K: EncodeLike, LikeK: Encode, V: EncodeLike, LikeV: Encode } +} + +impl Decode for BTreeMap { + fn decode(input: &mut I) -> Result { + >::decode(input).and_then(move |Compact(len)| { + input.descend_ref()?; + input.on_before_alloc_mem(super::btree_utils::mem_size_of_btree::<(K, V)>(len))?; + let result = Result::from_iter((0..len).map(|_| Decode::decode(input))); + input.ascend_ref(); + result + }) + } +} + +impl DecodeWithMemTracking for BTreeMap where + BTreeMap: Decode +{ +} + +impl_encode_for_collection! { BTreeSet { T: Ord } { LikeT } { T: EncodeLike, LikeT: Encode } +} + +impl Decode for BTreeSet { + fn decode(input: &mut I) -> Result { + >::decode(input).and_then(move |Compact(len)| { + input.descend_ref()?; + input.on_before_alloc_mem(super::btree_utils::mem_size_of_btree::(len))?; + let result = Result::from_iter((0..len).map(|_| Decode::decode(input))); + input.ascend_ref(); + result + }) + } +} +impl DecodeWithMemTracking for BTreeSet where BTreeSet: Decode {} + +impl_encode_for_collection! { LinkedList { T } { LikeT } { T: EncodeLike, LikeT: Encode } +} + +impl Decode for LinkedList { + fn decode(input: &mut I) -> Result { + >::decode(input).and_then(move |Compact(len)| { + input.descend_ref()?; + // We account for the size of the `prev` and `next` pointers of each list node, + // plus the decoded element. + input.on_before_alloc_mem((len as usize).saturating_mul(mem::size_of::<( + usize, + usize, + T, + )>()))?; + let result = Result::from_iter((0..len).map(|_| Decode::decode(input))); + input.ascend_ref(); + result + }) + } +} + +impl DecodeWithMemTracking for LinkedList where LinkedList: Decode {} + +impl_encode_for_collection! { BinaryHeap { T: Ord } { LikeT } { T: EncodeLike, LikeT: Encode } } +impl Decode for BinaryHeap { + fn decode(input: &mut I) -> Result { + Ok(Vec::decode(input)?.into()) + } +} +impl DecodeWithMemTracking for BinaryHeap where BinaryHeap: Decode {} + impl EncodeLike for VecDeque {} impl, U: Encode> EncodeLike<&[U]> for VecDeque {} impl, U: Encode> EncodeLike> for &[T] {} @@ -1260,6 +1364,8 @@ impl Decode for VecDeque { } } +impl DecodeWithMemTracking for VecDeque {} + impl EncodeLike for () {} impl Encode for () { @@ -1440,6 +1546,8 @@ macro_rules! impl_endians { Some(mem::size_of::<$t>()) } } + + impl DecodeWithMemTracking for $t {} )* } } macro_rules! impl_one_byte { @@ -1465,6 +1573,8 @@ macro_rules! impl_one_byte { Ok(input.read_byte()? as $t) } } + + impl DecodeWithMemTracking for $t {} )* } } @@ -1500,6 +1610,8 @@ impl Decode for bool { } } +impl DecodeWithMemTracking for bool {} + impl Encode for Duration { fn size_hint(&self) -> usize { mem::size_of::() + mem::size_of::() @@ -1524,6 +1636,8 @@ impl Decode for Duration { } } +impl DecodeWithMemTracking for Duration {} + impl EncodeLike for Duration {} impl Encode for Range @@ -1550,6 +1664,8 @@ where } } +impl DecodeWithMemTracking for Range {} + impl Encode for RangeInclusive where T: Encode, @@ -1574,6 +1690,8 @@ where } } +impl DecodeWithMemTracking for RangeInclusive {} + #[cfg(test)] mod tests { use super::*; diff --git a/src/compact.rs b/src/compact.rs index db5b1768..ffcd2ae4 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -22,7 +22,7 @@ use crate::{ alloc::vec::Vec, codec::{Decode, Encode, EncodeAsRef, Input, Output}, encode_like::EncodeLike, - Error, + DecodeWithMemTracking, Error, }; #[cfg(feature = "fuzz")] use arbitrary::Arbitrary; @@ -175,6 +175,13 @@ where } } +impl DecodeWithMemTracking for Compact +where + T: CompactAs, + Compact: DecodeWithMemTracking, +{ +} + macro_rules! impl_from_compact { ( $( $ty:ty ),* ) => { $( @@ -482,6 +489,8 @@ impl Decode for Compact<()> { } } +impl DecodeWithMemTracking for Compact<()> {} + const U8_OUT_OF_RANGE: &str = "out of range decoding Compact"; const U16_OUT_OF_RANGE: &str = "out of range decoding Compact"; const U32_OUT_OF_RANGE: &str = "out of range decoding Compact"; @@ -506,6 +515,8 @@ impl Decode for Compact { } } +impl DecodeWithMemTracking for Compact {} + impl Decode for Compact { fn decode(input: &mut I) -> Result { let prefix = input.read_byte()?; @@ -532,6 +543,8 @@ impl Decode for Compact { } } +impl DecodeWithMemTracking for Compact {} + impl Decode for Compact { fn decode(input: &mut I) -> Result { let prefix = input.read_byte()?; @@ -572,6 +585,8 @@ impl Decode for Compact { } } +impl DecodeWithMemTracking for Compact {} + impl Decode for Compact { fn decode(input: &mut I) -> Result { let prefix = input.read_byte()?; @@ -628,6 +643,8 @@ impl Decode for Compact { } } +impl DecodeWithMemTracking for Compact {} + impl Decode for Compact { fn decode(input: &mut I) -> Result { let prefix = input.read_byte()?; @@ -692,6 +709,8 @@ impl Decode for Compact { } } +impl DecodeWithMemTracking for Compact {} + #[cfg(test)] mod tests { use super::*; diff --git a/src/depth_limit.rs b/src/depth_limit.rs index 2af17843..8b3a7edf 100644 --- a/src/depth_limit.rs +++ b/src/depth_limit.rs @@ -64,6 +64,10 @@ impl<'a, I: Input> Input for DepthTrackingInput<'a, I> { self.input.ascend_ref(); self.depth -= 1; } + + fn on_before_alloc_mem(&mut self, size: usize) -> Result<(), Error> { + self.input.on_before_alloc_mem(size) + } } impl DecodeLimit for T { diff --git a/src/lib.rs b/src/lib.rs index b178239c..f4152ddb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![cfg_attr(all(test, nightly), feature(allocator_api))] +#![cfg_attr(all(test, nightly), feature(btreemap_alloc))] #![doc = include_str!("../README.md")] #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] @@ -41,6 +43,7 @@ pub mod alloc { #[cfg(feature = "bit-vec")] mod bit_vec; +mod btree_utils; mod codec; mod compact; #[cfg(feature = "max-encoded-len")] @@ -58,6 +61,7 @@ mod joiner; mod keyedvec; #[cfg(feature = "max-encoded-len")] mod max_encoded_len; +mod mem_tracking; #[cfg(feature = "std")] pub use self::codec::IoReader; @@ -76,6 +80,7 @@ pub use self::{ error::Error, joiner::Joiner, keyedvec::KeyedVec, + mem_tracking::{DecodeWithMemLimit, DecodeWithMemTracking, MemTrackingInput}, }; #[cfg(feature = "max-encoded-len")] pub use const_encoded_len::ConstEncodedLen; diff --git a/src/mem_tracking.rs b/src/mem_tracking.rs new file mode 100644 index 00000000..25ec3372 --- /dev/null +++ b/src/mem_tracking.rs @@ -0,0 +1,97 @@ +// 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 crate::{Decode, Error, Input}; +use impl_trait_for_tuples::impl_for_tuples; + +/// Marker trait used for identifying types that call the [`Input::on_before_alloc_mem`] hook +/// while decoding. +pub trait DecodeWithMemTracking: Decode {} + +const DECODE_OOM_MSG: &str = "Heap memory limit exceeded while decoding"; + +#[impl_for_tuples(18)] +impl DecodeWithMemTracking for Tuple {} + +/// `Input` implementation that can be used for limiting the heap memory usage while decoding. +pub struct MemTrackingInput<'a, I> { + input: &'a mut I, + used_mem: usize, + mem_limit: usize, +} + +impl<'a, I: Input> MemTrackingInput<'a, I> { + /// Create a new instance of `MemTrackingInput`. + pub fn new(input: &'a mut I, mem_limit: usize) -> Self { + Self { input, used_mem: 0, mem_limit } + } + + /// Get the `used_mem` field. + pub fn used_mem(&self) -> usize { + self.used_mem + } +} + +impl<'a, I: Input> Input for MemTrackingInput<'a, I> { + fn remaining_len(&mut self) -> Result, Error> { + self.input.remaining_len() + } + + fn read(&mut self, into: &mut [u8]) -> Result<(), Error> { + self.input.read(into) + } + + fn read_byte(&mut self) -> Result { + self.input.read_byte() + } + + fn descend_ref(&mut self) -> Result<(), Error> { + self.input.descend_ref() + } + + fn ascend_ref(&mut self) { + self.input.ascend_ref() + } + + fn on_before_alloc_mem(&mut self, size: usize) -> Result<(), Error> { + self.input.on_before_alloc_mem(size)?; + + self.used_mem = self.used_mem.saturating_add(size); + if self.used_mem >= self.mem_limit { + return Err(DECODE_OOM_MSG.into()) + } + + Ok(()) + } +} + +/// Extension trait to [`Decode`] for decoding with a maximum memory limit. +pub trait DecodeWithMemLimit: DecodeWithMemTracking { + /// Decode `Self` with the given maximum memory limit and advance `input` by the number of + /// bytes consumed. + /// + /// If `mem_limit` is hit, an error is returned. + fn decode_with_mem_limit(input: &mut I, mem_limit: usize) -> Result; +} + +impl DecodeWithMemLimit for T +where + T: DecodeWithMemTracking, +{ + fn decode_with_mem_limit(input: &mut I, mem_limit: usize) -> Result { + let mut input = MemTrackingInput::new(input, mem_limit); + T::decode(&mut input) + } +} diff --git a/tests/clippy.rs b/tests/clippy.rs index f1cb7e6d..3b552645 100644 --- a/tests/clippy.rs +++ b/tests/clippy.rs @@ -16,10 +16,10 @@ //! This file is checked by clippy to make sure that the code generated by the derive macro //! doesn't spew out warnings/errors in users' code. -use parity_scale_codec_derive::{Decode, Encode}; +use parity_scale_codec_derive::{Decode, DecodeWithMemTracking, Encode}; #[repr(u8)] -#[derive(Decode, Encode)] +#[derive(Decode, DecodeWithMemTracking, Encode)] pub enum CLike { Foo = 0, Bar = 1, diff --git a/tests/decode_with_mem_tracking_ui.rs b/tests/decode_with_mem_tracking_ui.rs new file mode 100644 index 00000000..7a916829 --- /dev/null +++ b/tests/decode_with_mem_tracking_ui.rs @@ -0,0 +1,22 @@ +// Copyright (C) 2020-2021 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. + +#[test] +#[cfg(feature = "derive")] +fn derive_no_bound_ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/decode_with_mem_tracking_ui/*.rs"); + t.pass("tests/decode_with_mem_tracking_ui/pass/*.rs"); +} diff --git a/tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.rs b/tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.rs new file mode 100644 index 00000000..5384b536 --- /dev/null +++ b/tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.rs @@ -0,0 +1,11 @@ +use parity_scale_codec::{Decode, DecodeWithMemTracking}; + +#[derive(Decode)] +struct Base {} + +#[derive(Decode, DecodeWithMemTracking)] +struct Wrapper { + base: Base, +} + +fn main() {} diff --git a/tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.stderr b/tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.stderr new file mode 100644 index 00000000..c98fcf03 --- /dev/null +++ b/tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `Base: DecodeWithMemTracking` is not satisfied + --> tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.rs:8:8 + | +8 | base: Base, + | ^^^^ the trait `DecodeWithMemTracking` is not implemented for `Base` + | + = help: the following other types implement trait `DecodeWithMemTracking`: + () + (TupleElement0, TupleElement1) + (TupleElement0, TupleElement1, TupleElement2) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) + (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) + and $N others +note: required by a bound in `check_field` + --> tests/decode_with_mem_tracking_ui/trait_bound_not_satisfied.rs:6:18 + | +6 | #[derive(Decode, DecodeWithMemTracking)] + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check_field` + = note: this error originates in the derive macro `DecodeWithMemTracking` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/max_encoded_len_ui/crate_str.stderr b/tests/max_encoded_len_ui/crate_str.stderr index 0583b229..a90fdb79 100644 --- a/tests/max_encoded_len_ui/crate_str.stderr +++ b/tests/max_encoded_len_ui/crate_str.stderr @@ -1,4 +1,4 @@ -error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, `#[codec(decode_bound_with_mem_tracking_bound(T: DecodeWithMemTracking))]` or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute --> tests/max_encoded_len_ui/crate_str.rs:4:9 | 4 | #[codec(crate = "parity_scale_codec")] diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr index a7649942..2f17bdbf 100644 --- a/tests/max_encoded_len_ui/incomplete_attr.stderr +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -1,4 +1,4 @@ -error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, `#[codec(decode_bound_with_mem_tracking_bound(T: DecodeWithMemTracking))]` or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute --> tests/max_encoded_len_ui/incomplete_attr.rs:4:9 | 4 | #[codec(crate)] diff --git a/tests/max_encoded_len_ui/missing_crate_specifier.stderr b/tests/max_encoded_len_ui/missing_crate_specifier.stderr index b575f512..ab5a74aa 100644 --- a/tests/max_encoded_len_ui/missing_crate_specifier.stderr +++ b/tests/max_encoded_len_ui/missing_crate_specifier.stderr @@ -1,4 +1,4 @@ -error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute +error: Invalid attribute: only `#[codec(dumb_trait_bound)]`, `#[codec(crate = path::to::crate)]`, `#[codec(encode_bound(T: Encode))]`, `#[codec(decode_bound(T: Decode))]`, `#[codec(decode_bound_with_mem_tracking_bound(T: DecodeWithMemTracking))]` or `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute --> tests/max_encoded_len_ui/missing_crate_specifier.rs:4:9 | 4 | #[codec(parity_scale_codec)] diff --git a/tests/mem_tracking.rs b/tests/mem_tracking.rs new file mode 100644 index 00000000..721d3b51 --- /dev/null +++ b/tests/mem_tracking.rs @@ -0,0 +1,153 @@ +// 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 core::fmt::Debug; +use parity_scale_codec::{ + alloc::{ + collections::{BTreeMap, BTreeSet, LinkedList, VecDeque}, + rc::Rc, + }, + DecodeWithMemLimit, DecodeWithMemTracking, Encode, Error, MemTrackingInput, +}; +use parity_scale_codec_derive::{ + Decode as DeriveDecode, DecodeWithMemTracking as DeriveDecodeWithMemTracking, + Encode as DeriveEncode, +}; + +const ARRAY: [u8; 1000] = [11; 1000]; + +#[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking, PartialEq, Debug)] +#[allow(clippy::large_enum_variant)] +enum TestEnum { + Empty, + Array([u8; 1000]), +} + +#[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking, PartialEq, Debug)] +struct ComplexStruct { + test_enum: TestEnum, + boxed_test_enum: Box, + box_field: Box, + vec: Vec, +} + +fn decode_object(obj: T, mem_limit: usize, expected_used_mem: usize) -> Result +where + T: Encode + DecodeWithMemTracking + DecodeWithMemLimit + PartialEq + Debug, +{ + let encoded_bytes = obj.encode(); + + let decoded_obj = T::decode_with_mem_limit(&mut &encoded_bytes[..], mem_limit)?; + assert_eq!(&decoded_obj, &obj); + + let raw_input = &mut &encoded_bytes[..]; + let mut input = MemTrackingInput::new(raw_input, mem_limit); + let decoded_obj = T::decode(&mut input)?; + assert_eq!(&decoded_obj, &obj); + assert_eq!(input.used_mem(), expected_used_mem); + if expected_used_mem > 0 { + let raw_input = &mut &encoded_bytes[..]; + let mut input = MemTrackingInput::new(raw_input, expected_used_mem); + assert!(T::decode(&mut input).is_err()); + } + + Ok(decoded_obj) +} + +#[test] +fn decode_simple_objects_works() { + // Test simple objects + assert!(decode_object(ARRAY, usize::MAX, 0).is_ok()); + assert!(decode_object(Some(ARRAY), usize::MAX, 0).is_ok()); + assert!(decode_object((ARRAY, ARRAY), usize::MAX, 0).is_ok()); + assert!(decode_object(1u8, usize::MAX, 0).is_ok()); + assert!(decode_object(1u32, usize::MAX, 0).is_ok()); + assert!(decode_object(1f64, usize::MAX, 0).is_ok()); + + // Test heap objects + assert!(decode_object(Box::new(ARRAY), usize::MAX, 1000).is_ok()); + #[cfg(target_has_atomic = "ptr")] + { + use parity_scale_codec::alloc::sync::Arc; + assert!(decode_object(Arc::new(ARRAY), usize::MAX, 1000).is_ok()); + } + assert!(decode_object(Rc::new(ARRAY), usize::MAX, 1000).is_ok()); + // Simple collections + assert!(decode_object(vec![ARRAY; 3], usize::MAX, 3000).is_ok()); + assert!(decode_object(VecDeque::from(vec![ARRAY; 5]), usize::MAX, 5000).is_ok()); + assert!(decode_object(String::from("test"), usize::MAX, 4).is_ok()); + #[cfg(feature = "bytes")] + assert!(decode_object(bytes::Bytes::from(&ARRAY[..]), usize::MAX, 1000).is_ok()); + // Complex Collections + assert!(decode_object(BTreeMap::::from([(1, 2), (2, 3)]), usize::MAX, 40).is_ok()); + assert!(decode_object( + BTreeMap::from([ + ("key1".to_string(), "value1".to_string()), + ("key2".to_string(), "value2".to_string()), + ]), + usize::MAX, + 564, + ) + .is_ok()); + assert!(decode_object(BTreeSet::::from([1, 2, 3, 4, 5]), usize::MAX, 24).is_ok()); + assert!(decode_object(LinkedList::::from([1, 2, 3, 4, 5]), usize::MAX, 120).is_ok()); +} + +#[test] +fn decode_complex_objects_works() { + assert!(decode_object(vec![vec![vec![vec![vec![1u8]]]]], usize::MAX, 97).is_ok()); + assert!(decode_object(Box::new(Rc::new(vec![String::from("test")])), usize::MAX, 60).is_ok()); +} + +#[test] +fn decode_complex_derived_struct_works() { + assert!(decode_object( + ComplexStruct { + test_enum: TestEnum::Array([0; 1000]), + boxed_test_enum: Box::new(TestEnum::Empty), + box_field: Box::new(1), + vec: vec![1; 10], + }, + usize::MAX, + 1015 + ) + .is_ok()); +} + +#[test] +fn mem_limit_exceeded_is_triggered() { + // Test simple heap object + assert_eq!( + decode_object(Box::new(ARRAY), 999, 999).unwrap_err().to_string(), + "Heap memory limit exceeded while decoding" + ); + + // Test complex derived struct + assert_eq!( + decode_object( + ComplexStruct { + test_enum: TestEnum::Array([0; 1000]), + boxed_test_enum: Box::new(TestEnum::Empty), + box_field: Box::new(1), + vec: vec![1; 10], + }, + 1014, + 1014 + ) + .unwrap_err() + .to_string(), + "Could not decode `ComplexStruct::vec`:\n\tHeap memory limit exceeded while decoding\n" + ); +} diff --git a/tests/mod.rs b/tests/mod.rs index ff86c646..f78feb7c 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -13,25 +13,29 @@ // limitations under the License. use parity_scale_codec::{ - Compact, CompactAs, Decode, Encode, EncodeAsRef, Error, HasCompact, Output, + Compact, CompactAs, Decode, DecodeWithMemTracking, Encode, EncodeAsRef, Error, HasCompact, + Output, +}; +use parity_scale_codec_derive::{ + Decode as DeriveDecode, DecodeWithMemTracking as DeriveDecodeWithMemTracking, + Encode as DeriveEncode, }; -use parity_scale_codec_derive::{Decode as DeriveDecode, Encode as DeriveEncode}; use serde_derive::{Deserialize, Serialize}; -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct Unit; -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct Indexed(u32, u64); -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking, Default)] struct Struct { pub a: A, pub b: B, pub c: C, } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct StructWithPhantom { pub a: u32, pub b: u64, @@ -46,7 +50,7 @@ impl Struct { } } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] enum EnumType { #[codec(index = 15)] A, @@ -57,26 +61,29 @@ enum EnumType { }, } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] enum EnumWithDiscriminant { A = 1, B = 15, C = 255, } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] -struct TestHasCompact { +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] +struct TestHasCompact +where + ::Type: DecodeWithMemTracking, +{ #[codec(encoded_as = "::Type")] bar: T, } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct TestCompactHasCompact { #[codec(compact)] bar: T, } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] enum TestHasCompactEnum { Unnamed(#[codec(encoded_as = "::Type")] T), Named { @@ -90,13 +97,13 @@ enum TestHasCompactEnum { }, } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct TestCompactAttribute { #[codec(compact)] bar: u64, } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] enum TestCompactAttributeEnum { Unnamed(#[codec(compact)] u64), Named { @@ -329,7 +336,7 @@ fn associated_type_bounds() { type NonEncodableType; } - #[derive(DeriveEncode, DeriveDecode, Debug, PartialEq)] + #[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking, Debug, PartialEq)] struct Struct { field: (Vec, Type), } @@ -372,7 +379,7 @@ fn generic_bound_encoded_as() { type RefType = &'a u32; } - #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct TestGeneric> where u32: for<'a> EncodeAsRef<'a, A>, @@ -408,7 +415,7 @@ fn generic_bound_hascompact() { } } - #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] enum TestGenericHasCompact { A { #[codec(compact)] @@ -429,14 +436,14 @@ fn generic_trait() { struct StructNoCodec; - #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct StructCodec; impl TraitNoCodec for StructNoCodec { type Type = StructCodec; } - #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] + #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct TestGenericTrait { t: T::Type, } @@ -448,7 +455,9 @@ fn generic_trait() { #[test] fn recursive_variant_1_encode_works() { - #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] + #[derive( + Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking, Default, + )] struct Recursive { data: N, other: Vec>, @@ -460,7 +469,9 @@ fn recursive_variant_1_encode_works() { #[test] fn recursive_variant_2_encode_works() { - #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] + #[derive( + Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking, Default, + )] struct Recursive { data: N, other: Vec>>, @@ -476,10 +487,14 @@ fn private_type_in_where_bound() { // an error. #![deny(warnings)] - #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] + #[derive( + Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking, Default, + )] struct Private; - #[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, Default)] + #[derive( + Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking, Default, + )] #[codec(dumb_trait_bound)] pub struct Test { data: Vec<(N, Private)>, @@ -491,7 +506,7 @@ fn private_type_in_where_bound() { #[test] fn encode_decode_empty_enum() { - #[derive(DeriveEncode, DeriveDecode, PartialEq, Debug)] + #[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking, PartialEq, Debug)] enum EmptyEnumDerive {} fn impls_encode_decode() {} @@ -513,13 +528,13 @@ fn codec_vec_u8() { #[test] fn recursive_type() { - #[derive(DeriveEncode, DeriveDecode)] + #[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] pub enum Foo { T(Box), A, } - #[derive(DeriveEncode, DeriveDecode)] + #[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] pub struct Bar { field: Foo, } @@ -567,7 +582,7 @@ fn weird_derive() { }; } - make_struct!(#[derive(DeriveEncode, DeriveDecode)]); + make_struct!(#[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)]); } #[test] @@ -577,15 +592,16 @@ fn output_trait_object() { #[test] fn custom_trait_bound() { - #[derive(DeriveEncode, DeriveDecode)] + #[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] #[codec(encode_bound(N: Encode, T: Default))] #[codec(decode_bound(N: Decode, T: Default))] + #[codec(decode_with_mem_tracking_bound(N: DecodeWithMemTracking, T: Default))] struct Something { hello: Hello, val: N, } - #[derive(DeriveEncode, DeriveDecode)] + #[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] #[codec(encode_bound())] #[codec(decode_bound())] struct Hello { @@ -620,7 +636,7 @@ fn bit_vec_works() { assert_eq!(original_vec, original_vec_clone); - #[derive(DeriveDecode, DeriveEncode, PartialEq, Debug)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking, DeriveEncode, PartialEq, Debug)] struct MyStruct { v: BitVec, x: u8, @@ -637,7 +653,7 @@ fn bit_vec_works() { #[test] fn no_warning_for_deprecated() { - #[derive(DeriveEncode, DeriveDecode)] + #[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] pub enum MyEnum { VariantA, #[deprecated] @@ -665,11 +681,11 @@ fn decoding_a_huge_array_inside_of_arc_does_not_overflow_the_stack() { #[test] fn decoding_a_huge_boxed_newtype_array_does_not_overflow_the_stack() { - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] #[repr(transparent)] struct HugeArrayNewtype([u8; 100 * 1024 * 1024]); - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] struct HugeArrayNewtypeBox(#[allow(dead_code)] Box); let data = &[]; @@ -680,10 +696,10 @@ fn decoding_a_huge_boxed_newtype_array_does_not_overflow_the_stack() { fn decoding_two_indirectly_boxed_arrays_works() { // This test will fail if the check for `#[repr(transparent)]` in the derive crate // doesn't work when implementing `Decode::decode_into`. - #[derive(DeriveDecode, PartialEq, Eq, Debug)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking, PartialEq, Eq, Debug)] struct SmallArrays([u8; 2], [u8; 2]); - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] struct SmallArraysBox(Box); let data = &[1, 2, 3, 4]; @@ -695,16 +711,16 @@ fn decoding_two_indirectly_boxed_arrays_works() { #[test] fn zero_sized_types_are_properly_decoded_in_a_transparent_boxed_struct() { - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] #[repr(transparent)] struct ZstTransparent; - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] struct ZstNonTransparent; struct ConsumeByte; - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] #[repr(transparent)] struct NewtypeWithZst { _zst_1: ConsumeByte, @@ -714,7 +730,7 @@ fn zero_sized_types_are_properly_decoded_in_a_transparent_boxed_struct() { _zst_4: ConsumeByte, } - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] struct NewtypeWithZstBox(#[allow(dead_code)] Box); impl Decode for ConsumeByte { @@ -725,21 +741,23 @@ fn zero_sized_types_are_properly_decoded_in_a_transparent_boxed_struct() { } } + impl DecodeWithMemTracking for ConsumeByte {} + let data = &[1, 2, 3]; assert_eq!(NewtypeWithZst::decode(&mut data.as_slice()).unwrap().field, [2]); } #[test] fn boxed_zero_sized_newtype_with_everything_being_transparent_is_decoded_correctly() { - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] #[repr(transparent)] struct Zst; - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] #[repr(transparent)] struct NewtypeWithZst(Zst); - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] #[repr(transparent)] struct NewtypeWithZstBox(Box); @@ -765,7 +783,7 @@ fn incomplete_decoding_of_an_array_drops_partially_read_elements_if_reading_fail pub static COUNTER: core::cell::Cell = const { core::cell::Cell::new(0) }; } - #[derive(DeriveDecode)] + #[derive(DeriveDecode, DeriveDecodeWithMemTracking)] struct Foobar(#[allow(dead_code)] u8); impl Drop for Foobar { @@ -822,10 +840,10 @@ fn incomplete_decoding_of_an_array_drops_partially_read_elements_if_reading_pani #[test] fn deserializing_of_big_recursively_nested_enum_works() { - #[derive(PartialEq, Eq, DeriveDecode, DeriveEncode)] + #[derive(PartialEq, Eq, DeriveDecode, DeriveDecodeWithMemTracking, DeriveEncode)] struct Data([u8; 1472]); - #[derive(PartialEq, Eq, DeriveDecode, DeriveEncode)] + #[derive(PartialEq, Eq, DeriveDecode, DeriveDecodeWithMemTracking, DeriveEncode)] #[allow(clippy::large_enum_variant)] enum Enum { Nested(Vec), diff --git a/tests/single_field_struct_encoding.rs b/tests/single_field_struct_encoding.rs index 565a7d72..c3f83a4e 100644 --- a/tests/single_field_struct_encoding.rs +++ b/tests/single_field_struct_encoding.rs @@ -1,16 +1,27 @@ -use parity_scale_codec::{Compact, Decode, Encode, HasCompact}; +use parity_scale_codec::{Compact, Decode, DecodeWithMemTracking, Encode, HasCompact}; use parity_scale_codec_derive::{ - CompactAs as DeriveCompactAs, Decode as DeriveDecode, Encode as DeriveEncode, + CompactAs as DeriveCompactAs, Decode as DeriveDecode, + DecodeWithMemTracking as DeriveDecodeWithMemTracking, Encode as DeriveEncode, }; use serde_derive::{Deserialize, Serialize}; -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct S { x: u32, } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] +#[derive( + Debug, + PartialEq, + Eq, + Clone, + Copy, + DeriveEncode, + DeriveDecode, + DeriveDecodeWithMemTracking, + DeriveCompactAs, +)] struct SSkip { #[codec(skip)] s1: u32, @@ -19,46 +30,81 @@ struct SSkip { s2: u32, } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct Sc { #[codec(compact)] x: u32, } -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] -struct Sh { +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] +struct Sh +where + ::Type: DecodeWithMemTracking, +{ #[codec(encoded_as = "::Type")] x: T, } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] +#[derive( + Debug, + PartialEq, + Eq, + Clone, + Copy, + DeriveEncode, + DeriveDecode, + DeriveDecodeWithMemTracking, + DeriveCompactAs, +)] struct U(u32); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] +#[derive( + Debug, + PartialEq, + Eq, + Clone, + Copy, + DeriveEncode, + DeriveDecode, + DeriveDecodeWithMemTracking, + DeriveCompactAs, +)] struct U2 { a: u64, } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Debug, PartialEq, Eq, Clone, Copy, DeriveEncode, DeriveDecode, DeriveCompactAs)] +#[derive( + Debug, + PartialEq, + Eq, + Clone, + Copy, + DeriveEncode, + DeriveDecode, + DeriveDecodeWithMemTracking, + DeriveCompactAs, +)] struct USkip(#[codec(skip)] u32, u32, #[codec(skip)] u32); -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct Uc(#[codec(compact)] u32); -#[derive(Debug, PartialEq, Clone, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, Clone, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct Ucas(#[codec(compact)] U); -#[derive(Debug, PartialEq, Clone, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, Clone, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct USkipcas(#[codec(compact)] USkip); -#[derive(Debug, PartialEq, Clone, DeriveEncode, DeriveDecode)] +#[derive(Debug, PartialEq, Clone, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct SSkipcas(#[codec(compact)] SSkip); -#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode)] -struct Uh(#[codec(encoded_as = "::Type")] T); +#[derive(Debug, PartialEq, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] +struct Uh(#[codec(encoded_as = "::Type")] T) +where + ::Type: DecodeWithMemTracking; #[test] fn test_encoding() { diff --git a/tests/skip.rs b/tests/skip.rs index 20f37311..16ccbce9 100644 --- a/tests/skip.rs +++ b/tests/skip.rs @@ -1,5 +1,8 @@ use parity_scale_codec::{Decode, Encode}; -use parity_scale_codec_derive::{Decode as DeriveDecode, Encode as DeriveEncode}; +use parity_scale_codec_derive::{ + Decode as DeriveDecode, DecodeWithMemTracking as DeriveDecodeWithMemTracking, + Encode as DeriveEncode, +}; #[test] fn enum_struct_test() { @@ -9,8 +12,11 @@ fn enum_struct_test() { #[derive(PartialEq, Debug)] struct UncodecUndefaultType; - use parity_scale_codec_derive::{Decode as DeriveDecode, Encode as DeriveEncode}; - #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode)] + use parity_scale_codec_derive::{ + Decode as DeriveDecode, DecodeWithMemTracking as DeriveDecodeWithMemTracking, + Encode as DeriveEncode, + }; + #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] enum Enum { #[codec(skip)] A(S), @@ -22,14 +28,14 @@ fn enum_struct_test() { C(#[codec(skip)] T, u32), } - #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode)] + #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct StructNamed { #[codec(skip)] a: T, b: u32, } - #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode)] + #[derive(PartialEq, Debug, DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] struct StructUnnamed(#[codec(skip)] T, u32); let ea: Enum = Enum::A(UncodecUndefaultType); @@ -56,7 +62,7 @@ fn skip_enum_struct_inner_variant() { // Make sure the skipping does not generates a warning. #![deny(warnings)] - #[derive(DeriveEncode, DeriveDecode)] + #[derive(DeriveEncode, DeriveDecode, DeriveDecodeWithMemTracking)] enum Enum { Data { some_named: u32, diff --git a/tests/type_inference.rs b/tests/type_inference.rs index dc91d7f5..9ef665d6 100644 --- a/tests/type_inference.rs +++ b/tests/type_inference.rs @@ -15,17 +15,19 @@ //! Test for type inference issue in decode. use parity_scale_codec::Decode; -use parity_scale_codec_derive::Decode as DeriveDecode; +use parity_scale_codec_derive::{ + Decode as DeriveDecode, DecodeWithMemTracking as DeriveDecodeWithMemTracking, +}; pub trait Trait { type Value; type AccountId: Decode; } -#[derive(DeriveDecode)] +#[derive(DeriveDecode, DeriveDecodeWithMemTracking)] pub enum A { _C((T::AccountId, T::AccountId), Vec<(T::Value, T::Value)>), } -#[derive(DeriveDecode)] +#[derive(DeriveDecode, DeriveDecodeWithMemTracking)] pub struct B((T::AccountId, T::AccountId), #[allow(dead_code)] Vec<(T::Value, T::Value)>); From a530799488c2aa914c1e8d93e2d357c11f63cb0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 20:30:53 +0200 Subject: [PATCH 272/286] Bump trybuild from 1.0.99 to 1.0.100 (#635) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.99 to 1.0.100. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.99...1.0.100) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ffea3f0..f666f8a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1033,9 +1033,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8" +checksum = "8923cde76a6329058a86f04d033f0945a2c6df8b94093512e4ab188b3e3a8950" dependencies = [ "glob", "serde", diff --git a/Cargo.toml b/Cargo.toml index b65d333a..fbc1dfae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.5.0" -trybuild = "1.0.99" +trybuild = "1.0.100" paste = "1" rustversion = "1" From 5011274b25da85dad7ae0a2e55a0c33829fcb094 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 20:52:09 +0200 Subject: [PATCH 273/286] Bump rustversion from 1.0.17 to 1.0.18 (#634) Bumps [rustversion](https://github.com/dtolnay/rustversion) from 1.0.17 to 1.0.18. - [Release notes](https://github.com/dtolnay/rustversion/releases) - [Commits](https://github.com/dtolnay/rustversion/compare/1.0.17...1.0.18) --- updated-dependencies: - dependency-name: rustversion dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f666f8a9..60db4ece 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -837,9 +837,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rusty-fork" From d2a986a8740193186481fa0d3f84c81ab2d25cdf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:16:21 +0200 Subject: [PATCH 274/286] Bump proc-macro2 from 1.0.87 to 1.0.88 (#636) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.87 to 1.0.88. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.87...1.0.88) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60db4ece..533274c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -657,9 +657,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index ab437cab..d8af3a19 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.37" -proc-macro2 = "1.0.87" +proc-macro2 = "1.0.88" proc-macro-crate = "3.1.0" [dev-dependencies] From b34477a50f2431fcfde8728dae5bb08fc30872c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 18:59:15 +0200 Subject: [PATCH 275/286] Bump trybuild from 1.0.100 to 1.0.101 (#637) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.100 to 1.0.101. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.100...1.0.101) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 11 +++++++++-- Cargo.toml | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 533274c8..ff5efb86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -948,6 +948,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "target-triple" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a4d50cdb458045afc8131fd91b64904da29548bcb63c7236e0844936c13078" + [[package]] name = "tempfile" version = "3.5.0" @@ -1033,14 +1039,15 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.100" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8923cde76a6329058a86f04d033f0945a2c6df8b94093512e4ab188b3e3a8950" +checksum = "8dcd332a5496c026f1e14b7f3d2b7bd98e509660c04239c58b0ba38a12daded4" dependencies = [ "glob", "serde", "serde_derive", "serde_json", + "target-triple", "termcolor", "toml", ] diff --git a/Cargo.toml b/Cargo.toml index fbc1dfae..c9580929 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ serde_derive = { version = "1.0" } parity-scale-codec-derive = { path = "derive", default-features = false } quickcheck = "1.0" proptest = "1.5.0" -trybuild = "1.0.100" +trybuild = "1.0.101" paste = "1" rustversion = "1" From 234c7c761560cbbbcdda956bdd4dcdc3f5d78313 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 22:10:04 +0200 Subject: [PATCH 276/286] Bump bytes from 1.7.2 to 1.8.0 (#638) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.7.2 to 1.8.0. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.7.2...v1.8.0) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff5efb86..d03f5bdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,9 +102,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cast" From 34e7e709a72e164d2e04579de6d2e2f985849b1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 22:13:25 +0200 Subject: [PATCH 277/286] Bump serde from 1.0.210 to 1.0.211 (#639) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.210 to 1.0.211. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.210...v1.0.211) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 16 ++++++++-------- Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d03f5bdf..9a4307a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,7 +270,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.82", ] [[package]] @@ -882,22 +882,22 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "1ac55e59090389fb9f0dd9e0f3c09615afed1d19094284d0b200441f13550793" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "54be4f245ce16bc58d57ef2716271d0d4519e0f6defa147f6e081005bcb278ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.82", ] [[package]] @@ -933,9 +933,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index c9580929..635c52e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.210", default-features = false, optional = true } +serde = { version = "1.0.211", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = ["alloc"], optional = true } bytes = { version = "1", default-features = false, optional = true } From 348027f38df3c3bd32fb4de511dfa8e0bfd2f7f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:05:54 +0200 Subject: [PATCH 278/286] Bump serde from 1.0.211 to 1.0.213 (#644) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.211 to 1.0.213. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.211...v1.0.213) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a4307a2..c5a18ffd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -882,18 +882,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.211" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac55e59090389fb9f0dd9e0f3c09615afed1d19094284d0b200441f13550793" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.211" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be4f245ce16bc58d57ef2716271d0d4519e0f6defa147f6e081005bcb278ff" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 635c52e0..4b8490cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.211", default-features = false, optional = true } +serde = { version = "1.0.213", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = ["alloc"], optional = true } bytes = { version = "1", default-features = false, optional = true } From c8afea4f7759209da4bdce3a2d273d9ff7d3806c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:12:18 +0200 Subject: [PATCH 279/286] Bump proc-macro2 from 1.0.88 to 1.0.89 (#642) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.88 to 1.0.89. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.88...1.0.89) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5a18ffd..7c2013cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -657,9 +657,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index d8af3a19..b18dcb5b 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true [dependencies] syn = { version = "1.0.98", features = ["full", "visit"] } quote = "1.0.37" -proc-macro2 = "1.0.88" +proc-macro2 = "1.0.89" proc-macro-crate = "3.1.0" [dev-dependencies] From 438eca0ad4c7e3b734be7d4731fac1b9cdb2ac6d Mon Sep 17 00:00:00 2001 From: James Wilson Date: Thu, 24 Oct 2024 09:31:12 +0100 Subject: [PATCH 280/286] chore(deps): Update to syn 2 (#640) * Update to syn 2 * fmt and clippy --- Cargo.lock | 2 +- derive/Cargo.toml | 2 +- derive/src/utils.rs | 170 ++++++++++++++++++++------------------------ src/mem_tracking.rs | 2 +- 4 files changed, 80 insertions(+), 96 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c2013cb..d0fcee62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -603,7 +603,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.98", + "syn 2.0.82", ] [[package]] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index b18dcb5b..5255b4a3 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/paritytech/parity-scale-codec" proc-macro = true [dependencies] -syn = { version = "1.0.98", features = ["full", "visit"] } +syn = { version = "2", features = ["full", "visit"] } quote = "1.0.37" proc-macro2 = "1.0.89" proc-macro-crate = "3.1.0" diff --git a/derive/src/utils.rs b/derive/src/utils.rs index 9f737afa..735e2348 100644 --- a/derive/src/utils.rs +++ b/derive/src/utils.rs @@ -20,11 +20,11 @@ use std::str::FromStr; use proc_macro2::TokenStream; -use quote::{quote, ToTokens}; +use quote::quote; use syn::{ parse::Parse, punctuated::Punctuated, spanned::Spanned, token, Attribute, Data, DataEnum, - DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, MetaNameValue, NestedMeta, - Path, Variant, + DeriveInput, Expr, ExprLit, Field, Fields, FieldsNamed, FieldsUnnamed, Lit, Meta, + MetaNameValue, Path, Variant, }; fn find_meta_item<'a, F, R, I, M>(mut itr: I, mut pred: F) -> Option @@ -34,7 +34,7 @@ where M: Parse, { itr.find_map(|attr| { - attr.path.is_ident("codec").then(|| pred(attr.parse_args().ok()?)).flatten() + attr.path().is_ident("codec").then(|| pred(attr.parse_args().ok()?)).flatten() }) } @@ -43,9 +43,9 @@ where pub fn variant_index(v: &Variant, i: usize) -> TokenStream { // first look for an attribute let index = find_meta_item(v.attrs.iter(), |meta| { - if let NestedMeta::Meta(Meta::NameValue(ref nv)) = meta { + if let Meta::NameValue(ref nv) = meta { if nv.path.is_ident("index") { - if let Lit::Int(ref v) = nv.lit { + if let Expr::Lit(ExprLit { lit: Lit::Int(ref v), .. }) = nv.value { let byte = v .base10_parse::() .expect("Internal error, index attribute must have been checked"); @@ -70,9 +70,9 @@ pub fn variant_index(v: &Variant, i: usize) -> TokenStream { /// `Field`. pub fn get_encoded_as_type(field: &Field) -> Option { find_meta_item(field.attrs.iter(), |meta| { - if let NestedMeta::Meta(Meta::NameValue(ref nv)) = meta { + if let Meta::NameValue(ref nv) = meta { if nv.path.is_ident("encoded_as") { - if let Lit::Str(ref s) = nv.lit { + if let Expr::Lit(ExprLit { lit: Lit::Str(ref s), .. }) = nv.value { return Some( TokenStream::from_str(&s.value()) .expect("Internal error, encoded_as attribute must have been checked"), @@ -89,7 +89,7 @@ pub fn get_encoded_as_type(field: &Field) -> Option { /// return the compact type associated with the field type. pub fn get_compact_type(field: &Field, crate_path: &syn::Path) -> Option { find_meta_item(field.attrs.iter(), |meta| { - if let NestedMeta::Meta(Meta::Path(ref path)) = meta { + if let Meta::Path(ref path) = meta { if path.is_ident("compact") { let field_type = &field.ty; return Some(quote! {<#field_type as #crate_path::HasCompact>::Type}); @@ -108,7 +108,7 @@ pub fn is_compact(field: &Field) -> bool { /// Look for a `#[codec(skip)]` in the given attributes. pub fn should_skip(attrs: &[Attribute]) -> bool { find_meta_item(attrs.iter(), |meta| { - if let NestedMeta::Meta(Meta::Path(ref path)) = meta { + if let Meta::Path(ref path) = meta { if path.is_ident("skip") { return Some(path.span()); } @@ -122,7 +122,7 @@ pub fn should_skip(attrs: &[Attribute]) -> bool { /// Look for a `#[codec(dumb_trait_bound)]`in the given attributes. pub fn has_dumb_trait_bound(attrs: &[Attribute]) -> bool { find_meta_item(attrs.iter(), |meta| { - if let NestedMeta::Meta(Meta::Path(ref path)) = meta { + if let Meta::Path(ref path) = meta { if path.is_ident("dumb_trait_bound") { return Some(()); } @@ -174,7 +174,7 @@ impl From for Path { /// Match `#[codec(crate = ...)]` and return the `...` if it is a `Path`. fn codec_crate_path_inner(attr: &Attribute) -> Option { // match `#[codec ...]` - attr.path + attr.path() .is_ident("codec") .then(|| { // match `#[codec(crate = ...)]` and return the `...` @@ -222,13 +222,13 @@ impl Parse for CustomTraitBound { _paren_token_1: _paren_token, _skip_type_params: content.parse::()?, _paren_token_2: syn::parenthesized!(content in content), - type_names: content.parse_terminated(syn::Ident::parse)?, + type_names: content.parse_terminated(syn::Ident::parse, Token![,])?, }) } else { Ok(Self::SpecifiedBounds { _name, _paren_token, - bounds: content.parse_terminated(syn::WherePredicate::parse)?, + bounds: content.parse_terminated(syn::WherePredicate::parse, Token![,])?, }) } } @@ -339,10 +339,10 @@ pub fn check_attributes(input: &DeriveInput) -> syn::Result<()> { // Check if the attribute is `#[allow(..)]`, `#[deny(..)]`, `#[forbid(..)]` or `#[warn(..)]`. pub fn is_lint_attribute(attr: &Attribute) -> bool { - attr.path.is_ident("allow") || - attr.path.is_ident("deny") || - attr.path.is_ident("forbid") || - attr.path.is_ident("warn") + attr.path().is_ident("allow") || + attr.path().is_ident("deny") || + attr.path().is_ident("forbid") || + attr.path().is_ident("warn") } // Ensure a field is decorated only with the following attributes: @@ -353,31 +353,26 @@ fn check_field_attribute(attr: &Attribute) -> syn::Result<()> { let field_error = "Invalid attribute on field, only `#[codec(skip)]`, `#[codec(compact)]` and \ `#[codec(encoded_as = \"$EncodeAs\")]` are accepted."; - if attr.path.is_ident("codec") { - match attr.parse_meta()? { - Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { - match meta_list.nested.first().expect("Just checked that there is one item; qed") { - NestedMeta::Meta(Meta::Path(path)) - if path.get_ident().map_or(false, |i| i == "skip") => - Ok(()), - - NestedMeta::Meta(Meta::Path(path)) - if path.get_ident().map_or(false, |i| i == "compact") => - Ok(()), - - NestedMeta::Meta(Meta::NameValue(MetaNameValue { - path, - lit: Lit::Str(lit_str), - .. - })) if path.get_ident().map_or(false, |i| i == "encoded_as") => - TokenStream::from_str(&lit_str.value()) - .map(|_| ()) - .map_err(|_e| syn::Error::new(lit_str.span(), "Invalid token stream")), - - elt => Err(syn::Error::new(elt.span(), field_error)), - } - }, - meta => Err(syn::Error::new(meta.span(), field_error)), + if attr.path().is_ident("codec") { + let nested = attr.parse_args_with(Punctuated::::parse_terminated)?; + if nested.len() != 1 { + return Err(syn::Error::new(attr.meta.span(), field_error)); + } + match nested.first().expect("Just checked that there is one item; qed") { + Meta::Path(path) if path.get_ident().map_or(false, |i| i == "skip") => Ok(()), + + Meta::Path(path) if path.get_ident().map_or(false, |i| i == "compact") => Ok(()), + + Meta::NameValue(MetaNameValue { + path, + value: Expr::Lit(ExprLit { lit: Lit::Str(lit_str), .. }), + .. + }) if path.get_ident().map_or(false, |i| i == "encoded_as") => + TokenStream::from_str(&lit_str.value()) + .map(|_| ()) + .map_err(|_e| syn::Error::new(lit_str.span(), "Invalid token stream")), + + elt => Err(syn::Error::new(elt.span(), field_error)), } } else { Ok(()) @@ -391,27 +386,24 @@ fn check_variant_attribute(attr: &Attribute) -> syn::Result<()> { let variant_error = "Invalid attribute on variant, only `#[codec(skip)]` and \ `#[codec(index = $u8)]` are accepted."; - if attr.path.is_ident("codec") { - match attr.parse_meta()? { - Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { - match meta_list.nested.first().expect("Just checked that there is one item; qed") { - NestedMeta::Meta(Meta::Path(path)) - if path.get_ident().map_or(false, |i| i == "skip") => - Ok(()), - - NestedMeta::Meta(Meta::NameValue(MetaNameValue { - path, - lit: Lit::Int(lit_int), - .. - })) if path.get_ident().map_or(false, |i| i == "index") => lit_int - .base10_parse::() - .map(|_| ()) - .map_err(|_| syn::Error::new(lit_int.span(), "Index must be in 0..255")), - - elt => Err(syn::Error::new(elt.span(), variant_error)), - } - }, - meta => Err(syn::Error::new(meta.span(), variant_error)), + if attr.path().is_ident("codec") { + let nested = attr.parse_args_with(Punctuated::::parse_terminated)?; + if nested.len() != 1 { + return Err(syn::Error::new(attr.meta.span(), variant_error)); + } + match nested.first().expect("Just checked that there is one item; qed") { + Meta::Path(path) if path.get_ident().map_or(false, |i| i == "skip") => Ok(()), + + Meta::NameValue(MetaNameValue { + path, + value: Expr::Lit(ExprLit { lit: Lit::Int(lit_int), .. }), + .. + }) if path.get_ident().map_or(false, |i| i == "index") => lit_int + .base10_parse::() + .map(|_| ()) + .map_err(|_| syn::Error::new(lit_int.span(), "Index must be in 0..255")), + + elt => Err(syn::Error::new(elt.span(), variant_error)), } } else { Ok(()) @@ -425,48 +417,40 @@ fn check_top_attribute(attr: &Attribute) -> syn::Result<()> { `#[codec(decode_bound(T: Decode))]`, \ `#[codec(decode_bound_with_mem_tracking_bound(T: DecodeWithMemTracking))]` or \ `#[codec(mel_bound(T: MaxEncodedLen))]` are accepted as top attribute"; - if attr.path.is_ident("codec") && + if attr.path().is_ident("codec") && attr.parse_args::>().is_err() && attr.parse_args::>().is_err() && attr.parse_args::>().is_err() && attr.parse_args::>().is_err() && codec_crate_path_inner(attr).is_none() { - match attr.parse_meta()? { - Meta::List(ref meta_list) if meta_list.nested.len() == 1 => { - match meta_list.nested.first().expect("Just checked that there is one item; qed") { - NestedMeta::Meta(Meta::Path(path)) - if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => - Ok(()), - - elt => Err(syn::Error::new(elt.span(), top_error)), - } - }, - _ => Err(syn::Error::new(attr.span(), top_error)), + let nested = attr.parse_args_with(Punctuated::::parse_terminated)?; + if nested.len() != 1 { + return Err(syn::Error::new(attr.meta.span(), top_error)); } - } else { - Ok(()) - } -} + match nested.first().expect("Just checked that there is one item; qed") { + Meta::Path(path) if path.get_ident().map_or(false, |i| i == "dumb_trait_bound") => + Ok(()), -fn check_repr(attrs: &[syn::Attribute], value: &str) -> bool { - let mut result = false; - for raw_attr in attrs { - let path = raw_attr.path.clone().into_token_stream().to_string(); - if path != "repr" { - continue; + elt => Err(syn::Error::new(elt.span(), top_error)), } - - result = raw_attr.tokens.clone().into_token_stream().to_string() == value; + } else { + Ok(()) } - - result } /// Checks whether the given attributes contain a `#[repr(transparent)]`. pub fn is_transparent(attrs: &[syn::Attribute]) -> bool { - // TODO: When migrating to syn 2 the `"(transparent)"` needs to be changed into `"transparent"`. - check_repr(attrs, "(transparent)") + attrs.iter().any(|attr| { + if !attr.path().is_ident("repr") { + return false; + } + let Ok(nested) = attr.parse_args_with(Punctuated::::parse_terminated) + else { + return false; + }; + nested.iter().any(|n| matches!(n, Meta::Path(p) if p.is_ident("transparent"))) + }) } pub fn try_get_variants(data: &DataEnum) -> Result, syn::Error> { @@ -477,7 +461,7 @@ pub fn try_get_variants(data: &DataEnum) -> Result, syn::Error> { return Err(syn::Error::new( data.variants.span(), "Currently only enums with at most 256 variants are encodable/decodable.", - )) + )); } Ok(data_variants) diff --git a/src/mem_tracking.rs b/src/mem_tracking.rs index 25ec3372..7c76b923 100644 --- a/src/mem_tracking.rs +++ b/src/mem_tracking.rs @@ -70,7 +70,7 @@ impl<'a, I: Input> Input for MemTrackingInput<'a, I> { self.used_mem = self.used_mem.saturating_add(size); if self.used_mem >= self.mem_limit { - return Err(DECODE_OOM_MSG.into()) + return Err(DECODE_OOM_MSG.into()); } Ok(()) From 3093640ba27be1d172cc2b7b501130863913b13d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 21:46:41 +0200 Subject: [PATCH 281/286] Bump syn from 2.0.82 to 2.0.85 (#647) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.82 to 2.0.85. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/2.0.82...2.0.85) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0fcee62..e7dc33cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,7 +270,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -603,7 +603,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -897,7 +897,7 @@ checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -933,9 +933,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.82" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", From 91d436ecdf4ef22208c4821914fd14fe8446ea1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:13:54 +0100 Subject: [PATCH 282/286] Bump arbitrary from 1.3.2 to 1.4.0 (#651) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bump arbitrary from 1.3.2 to 1.4.0 Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.3.2 to 1.4.0. - [Changelog](https://github.com/rust-fuzz/arbitrary/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.3.2...v1.4.0) --- updated-dependencies: - dependency-name: arbitrary dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Bump image * Fix tests --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bastian Köcher --- .github/workflows/ci.yml | 2 +- Cargo.lock | 8 ++-- Cargo.toml | 2 +- derive/src/lib.rs | 4 +- fuzzer/Cargo.toml | 2 +- tests/max_encoded_len_ui/crate_str.stderr | 40 +++++++++---------- .../max_encoded_len_ui/incomplete_attr.stderr | 40 +++++++++---------- .../missing_crate_specifier.stderr | 40 +++++++++---------- tests/max_encoded_len_ui/not_encode.stderr | 20 +++++----- 9 files changed, 79 insertions(+), 79 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 471f61fa..b729d394 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: pull_request: env: - IMAGE: paritytech/ci-unified:bullseye-1.79.0 + IMAGE: paritytech/ci-unified:bullseye-1.81.0 concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true diff --git a/Cargo.lock b/Cargo.lock index e7dc33cb..12f52f78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "775a8770d29db3dadcb858482cc240af7b2ffde4ac4de67d1d4955728103f0e2" dependencies = [ "derive_arbitrary", ] @@ -264,9 +264,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "d475dfebcb4854d596b17b09f477616f80f17a550517f2b3615d8c205d5c802b" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 4b8490cc..85ed39a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ bitvec = { version = "1", default-features = false, features = ["alloc"], option bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } generic-array = { version = "0.14.7", optional = true } -arbitrary = { version = "1.3.2", features = ["derive"], optional = true } +arbitrary = { version = "1.4.0", features = ["derive"], optional = true } impl-trait-for-tuples = "0.2.2" [dev-dependencies] diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 2f9ea7d9..8ba6d3de 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -94,8 +94,8 @@ fn wrap_with_dummy_const( /// * if variant has attribute: `#[codec(index = "$n")]` then n /// * else if variant has discriminant (like 3 in `enum T { A = 3 }`) then the discriminant. /// * else its position in the variant set, excluding skipped variants, but including variant with -/// discriminant or attribute. Warning this position does collision with discriminant or attribute -/// index. +/// discriminant or attribute. Warning this position does collision with discriminant or attribute +/// index. /// /// variant attributes: /// * `#[codec(skip)]`: the variant is not encoded. diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 56642e4d..c09ad16e 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -9,5 +9,5 @@ publish = false [dependencies] parity-scale-codec = { path = "..", features = ["derive", "bit-vec", "fuzz"] } honggfuzz = "0.5.56" -arbitrary = { version = "1.3.2", features = ["derive"] } +arbitrary = { version = "1.4.0", features = ["derive"] } bitvec = { version = "1", features = ["alloc"] } diff --git a/tests/max_encoded_len_ui/crate_str.stderr b/tests/max_encoded_len_ui/crate_str.stderr index a90fdb79..c4e4aafe 100644 --- a/tests/max_encoded_len_ui/crate_str.stderr +++ b/tests/max_encoded_len_ui/crate_str.stderr @@ -10,16 +10,16 @@ error[E0277]: the trait bound `Example: Encode` is not satisfied 5 | struct Example; | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` | - = help: the following other types implement trait `Encode`: - () - (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - and $N others + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs @@ -33,16 +33,16 @@ error[E0277]: the trait bound `Example: Encode` is not satisfied 8 | let _ = Example::max_encoded_len(); | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` | - = help: the following other types implement trait `Encode`: - () - (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - and $N others + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> = note: required for `Example` to implement `Encode` note: required by a bound in `max_encoded_len` --> src/max_encoded_len.rs diff --git a/tests/max_encoded_len_ui/incomplete_attr.stderr b/tests/max_encoded_len_ui/incomplete_attr.stderr index 2f17bdbf..782260fd 100644 --- a/tests/max_encoded_len_ui/incomplete_attr.stderr +++ b/tests/max_encoded_len_ui/incomplete_attr.stderr @@ -10,16 +10,16 @@ error[E0277]: the trait bound `Example: Encode` is not satisfied 5 | struct Example; | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` | - = help: the following other types implement trait `Encode`: - () - (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - and $N others + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs @@ -33,16 +33,16 @@ error[E0277]: the trait bound `Example: Encode` is not satisfied 8 | let _ = Example::max_encoded_len(); | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` | - = help: the following other types implement trait `Encode`: - () - (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - and $N others + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> = note: required for `Example` to implement `Encode` note: required by a bound in `max_encoded_len` --> src/max_encoded_len.rs diff --git a/tests/max_encoded_len_ui/missing_crate_specifier.stderr b/tests/max_encoded_len_ui/missing_crate_specifier.stderr index ab5a74aa..3486966a 100644 --- a/tests/max_encoded_len_ui/missing_crate_specifier.stderr +++ b/tests/max_encoded_len_ui/missing_crate_specifier.stderr @@ -10,16 +10,16 @@ error[E0277]: the trait bound `Example: Encode` is not satisfied 5 | struct Example; | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` | - = help: the following other types implement trait `Encode`: - () - (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - and $N others + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> = note: required for `Example` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs @@ -33,16 +33,16 @@ error[E0277]: the trait bound `Example: Encode` is not satisfied 8 | let _ = Example::max_encoded_len(); | ^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `Example`, which is required by `Example: Encode` | - = help: the following other types implement trait `Encode`: - () - (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - and $N others + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> = note: required for `Example` to implement `Encode` note: required by a bound in `max_encoded_len` --> src/max_encoded_len.rs diff --git a/tests/max_encoded_len_ui/not_encode.stderr b/tests/max_encoded_len_ui/not_encode.stderr index cd0695a3..19b175bb 100644 --- a/tests/max_encoded_len_ui/not_encode.stderr +++ b/tests/max_encoded_len_ui/not_encode.stderr @@ -4,16 +4,16 @@ error[E0277]: the trait bound `NotEncode: Encode` is not satisfied 4 | struct NotEncode; | ^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `NotEncode`, which is required by `NotEncode: Encode` | - = help: the following other types implement trait `Encode`: - () - (A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - (G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0) - and $N others + = help: the following other types implement trait `WrapperTypeEncode`: + &T + &mut T + Arc + Box + Cow<'a, T> + Rc + String + Vec + parity_scale_codec::Ref<'a, T, U> = note: required for `NotEncode` to implement `Encode` note: required by a bound in `MaxEncodedLen` --> src/max_encoded_len.rs From c5e402c47b030b3a65d6bda60f65b9dda102505e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 00:02:09 +0100 Subject: [PATCH 283/286] Bump syn from 2.0.85 to 2.0.87 (#650) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.85 to 2.0.87. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/2.0.85...2.0.87) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12f52f78..fbd4d861 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,7 +270,7 @@ checksum = "d475dfebcb4854d596b17b09f477616f80f17a550517f2b3615d8c205d5c802b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -603,7 +603,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -897,7 +897,7 @@ checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -933,9 +933,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", From 63c634ed33fc20a444b9b0897cae0088d0fdb542 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:46:48 +0100 Subject: [PATCH 284/286] Bump arbitrary from 1.4.0 to 1.4.1 (#652) Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.4.0 to 1.4.1. - [Changelog](https://github.com/rust-fuzz/arbitrary/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.4.0...v1.4.1) --- updated-dependencies: - dependency-name: arbitrary dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- fuzzer/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fbd4d861..199ef70a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "arbitrary" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775a8770d29db3dadcb858482cc240af7b2ffde4ac4de67d1d4955728103f0e2" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" dependencies = [ "derive_arbitrary", ] diff --git a/Cargo.toml b/Cargo.toml index 85ed39a1..a573adb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ bitvec = { version = "1", default-features = false, features = ["alloc"], option bytes = { version = "1", default-features = false, optional = true } byte-slice-cast = { version = "1.2.2", default-features = false } generic-array = { version = "0.14.7", optional = true } -arbitrary = { version = "1.4.0", features = ["derive"], optional = true } +arbitrary = { version = "1.4.1", features = ["derive"], optional = true } impl-trait-for-tuples = "0.2.2" [dev-dependencies] diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index c09ad16e..b45ce200 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -9,5 +9,5 @@ publish = false [dependencies] parity-scale-codec = { path = "..", features = ["derive", "bit-vec", "fuzz"] } honggfuzz = "0.5.56" -arbitrary = { version = "1.4.0", features = ["derive"] } +arbitrary = { version = "1.4.1", features = ["derive"] } bitvec = { version = "1", features = ["alloc"] } From 642430ec20700a1bba341638926998944b18f3b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:42:03 +0100 Subject: [PATCH 285/286] Bump serde from 1.0.213 to 1.0.214 (#648) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.213 to 1.0.214. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.213...v1.0.214) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 199ef70a..bf21ae31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -882,18 +882,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a573adb9..d8f013db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.213", default-features = false, optional = true } +serde = { version = "1.0.214", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = ["alloc"], optional = true } bytes = { version = "1", default-features = false, optional = true } From 2ef70dc0ebfa5790c16bd29f0ed8db2d247d9552 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 21:53:14 +0100 Subject: [PATCH 286/286] Bump serde from 1.0.214 to 1.0.215 (#654) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.214 to 1.0.215. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.214...v1.0.215) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf21ae31..8e15ef8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -882,18 +882,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index d8f013db..d55431be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.60.0" [dependencies] arrayvec = { version = "0.7", default-features = false } -serde = { version = "1.0.214", default-features = false, optional = true } +serde = { version = "1.0.215", default-features = false, optional = true } parity-scale-codec-derive = { path = "derive", version = ">= 3.6.8", default-features = false, optional = true } bitvec = { version = "1", default-features = false, features = ["alloc"], optional = true } bytes = { version = "1", default-features = false, optional = true }