diff --git a/crates/sol-types/src/abi/encoder.rs b/crates/sol-types/src/abi/encoder.rs index 23fd77d8d..c802f5798 100644 --- a/crates/sol-types/src/abi/encoder.rs +++ b/crates/sol-types/src/abi/encoder.rs @@ -43,6 +43,12 @@ impl Encoder { } } + /// Return a reference to the encoded words. + #[inline] + pub fn words(&self) -> &[Word] { + &self.buf + } + /// Finish the encoding process, returning the encoded words. /// /// Use `into_bytes` instead to flatten the words into bytes. @@ -53,16 +59,18 @@ impl Encoder { self.buf } + /// Return a reference to the encoded bytes. + #[inline] + pub fn bytes(&self) -> &[u8] { + // SAFETY: `#[repr(transparent)] FixedBytes([u8; N])` + unsafe { &*(self.words() as *const [Word] as *const [[u8; 32]]) }.as_flattened() + } + /// Finish the encoding process, returning the encoded bytes. #[inline] pub fn into_bytes(self) -> Vec { - // TODO: remove once `Vec::into_flattened` is stabilized. - // unsafe { mem::transmute::, Vec<[u8; 32]>>(self.buf) }.into_flattened() - // SAFETY: `#[repr(transparent)] FixedBytes([u8; N])` - crate::impl_core::into_flattened::(unsafe { - mem::transmute::, Vec<[u8; 32]>>(self.buf) - }) + unsafe { mem::transmute::, Vec<[u8; 32]>>(self.finish()) }.into_flattened() } /// Determine the current suffix offset. diff --git a/crates/sol-types/src/impl_core.rs b/crates/sol-types/src/impl_core.rs index 505987d10..4f6e114c2 100644 --- a/crates/sol-types/src/impl_core.rs +++ b/crates/sol-types/src/impl_core.rs @@ -1,16 +1,7 @@ //! Modified implementations of unstable libcore functions. -use alloc::vec::Vec; use core::mem::{self, MaybeUninit}; -trait Ext { - const IS_ZST: bool; -} - -impl Ext for T { - const IS_ZST: bool = mem::size_of::() == 0; -} - /// [`core::array::try_from_fn`] #[inline] pub(crate) fn try_from_fn(mut cb: F) -> Result<[T; N], E> @@ -88,34 +79,3 @@ pub(crate) unsafe fn array_assume_init(array: [MaybeUninit unsafe fn transpose(array: [MaybeUninit; N]) -> MaybeUninit<[T; N]> { mem::transmute_copy::<[MaybeUninit; N], MaybeUninit<[T; N]>>(&mem::ManuallyDrop::new(&array)) } - -// TODO(MSRV-1.80): remove -/// [`Vec::into_flattened`]. -#[inline] -pub(crate) fn into_flattened(vec: Vec<[T; N]>) -> Vec { - let (ptr, len, cap) = into_raw_parts(vec); - let (new_len, new_cap) = if T::IS_ZST { - (len.checked_mul(N).expect("vec len overflow"), usize::MAX) - } else { - // SAFETY: - // - `cap * N` cannot overflow because the allocation is already in - // the address space. - // - Each `[T; N]` has `N` valid elements, so there are `len * N` - // valid elements in the allocation. - unsafe { (len.checked_mul(N).unwrap_unchecked(), cap.checked_mul(N).unwrap_unchecked()) } - }; - // SAFETY: - // - `ptr` was allocated by `self` - // - `ptr` is well-aligned because `[T; N]` has the same alignment as `T`. - // - `new_cap` refers to the same sized allocation as `cap` because - // `new_cap * size_of::()` == `cap * size_of::<[T; N]>()` - // - `len` <= `cap`, so `len * N` <= `cap * N`. - unsafe { Vec::from_raw_parts(ptr.cast(), new_len, new_cap) } -} - -/// [`Vec::into_raw_parts`] -#[inline(always)] -fn into_raw_parts(vec: Vec) -> (*mut T, usize, usize) { - let mut me = mem::ManuallyDrop::new(vec); - (me.as_mut_ptr(), me.len(), me.capacity()) -}