From ab9ace4a684598c2ea33e905ca249fd6b8b8ca2c Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Wed, 10 Jul 2024 09:55:50 +0200 Subject: [PATCH] More improvements (#169) --- crates/musli-core/src/en/encoder.rs | 3 +- crates/musli-macros/src/internals/apply.rs | 6 +- crates/musli-zerocopy/src/buf/bind.rs | 24 ++- crates/musli-zerocopy/src/buf/buf.rs | 8 +- crates/musli-zerocopy/src/buf/load.rs | 28 +++- crates/musli-zerocopy/src/buf/owned_buf.rs | 69 ++++++-- crates/musli-zerocopy/src/buf/slice_mut.rs | 9 +- crates/musli-zerocopy/src/buf/store_buf.rs | 14 +- crates/musli-zerocopy/src/buf/visit.rs | 6 +- crates/musli-zerocopy/src/endian/endian.rs | 38 ++++- crates/musli-zerocopy/src/endian/mod.rs | 18 +- crates/musli-zerocopy/src/error.rs | 19 --- crates/musli-zerocopy/src/lib.rs | 6 +- crates/musli-zerocopy/src/mem/maybe_uninit.rs | 13 +- crates/musli-zerocopy/src/phf/factory.rs | 16 +- crates/musli-zerocopy/src/phf/generator.rs | 8 +- crates/musli-zerocopy/src/phf/map.rs | 24 ++- crates/musli-zerocopy/src/phf/set.rs | 16 +- crates/musli-zerocopy/src/pointer/coerce.rs | 22 +-- crates/musli-zerocopy/src/pointer/mod.rs | 4 - crates/musli-zerocopy/src/pointer/packable.rs | 46 ------ crates/musli-zerocopy/src/pointer/pointee.rs | 43 ++++- crates/musli-zerocopy/src/pointer/ref.rs | 148 +++++++++-------- crates/musli-zerocopy/src/pointer/size.rs | 9 +- .../musli-zerocopy/src/slice/binary_search.rs | 6 +- crates/musli-zerocopy/src/slice/slice.rs | 47 ++++-- crates/musli-zerocopy/src/swiss/factory.rs | 4 +- crates/musli-zerocopy/src/swiss/map.rs | 40 ++++- crates/musli-zerocopy/src/swiss/set.rs | 12 +- .../src/tests/enum_byte_order.rs | 155 ++++++++---------- crates/musli-zerocopy/src/traits.rs | 94 +++++++---- crates/musli-zerocopy/src/trie/factory.rs | 41 +++-- crates/musli-zerocopy/src/trie/mod.rs | 105 ++++++++---- crates/musli-zerocopy/src/trie/walk.rs | 10 +- crates/musli/src/descriptive/en.rs | 3 +- crates/musli/src/json/en/mod.rs | 3 +- crates/musli/src/storage/en.rs | 3 +- crates/musli/src/value/en.rs | 3 +- crates/musli/src/wire/en.rs | 3 +- 39 files changed, 693 insertions(+), 433 deletions(-) delete mode 100644 crates/musli-zerocopy/src/pointer/packable.rs diff --git a/crates/musli-core/src/en/encoder.rs b/crates/musli-core/src/en/encoder.rs index b7d74c89b..6245e5447 100644 --- a/crates/musli-core/src/en/encoder.rs +++ b/crates/musli-core/src/en/encoder.rs @@ -868,8 +868,7 @@ pub trait Encoder: Sized { vectors: I, ) -> Result::Error> where - I: IntoIterator, - I::Item: AsRef<[u8]>, + I: IntoIterator>, { Err(self.cx().message(expecting::unsupported_type( &expecting::Bytes, diff --git a/crates/musli-macros/src/internals/apply.rs b/crates/musli-macros/src/internals/apply.rs index 8df5d3c49..d857980e5 100644 --- a/crates/musli-macros/src/internals/apply.rs +++ b/crates/musli-macros/src/internals/apply.rs @@ -35,8 +35,7 @@ pub(crate) struct Iter<'a, I, T> { impl<'a, I, T> Iterator for Iter<'a, I, T> where - I: Iterator, - I::Item: Apply, + I: Iterator>, { type Item = IterItem<'a, I::Item, T>; @@ -53,8 +52,7 @@ where /// Apply an iterator of functions to a value. pub(crate) fn iter(iter: I, value: &T) -> Iter<'_, I::IntoIter, T> where - I: IntoIterator, - I::Item: Apply, + I: IntoIterator>, { Iter { iter: iter.into_iter(), diff --git a/crates/musli-zerocopy/src/buf/bind.rs b/crates/musli-zerocopy/src/buf/bind.rs index e35b22df9..bb8795f87 100644 --- a/crates/musli-zerocopy/src/buf/bind.rs +++ b/crates/musli-zerocopy/src/buf/bind.rs @@ -8,23 +8,39 @@ mod sealed { pub trait Sealed {} - impl Sealed for crate::phf::map::MapRef + impl Sealed for crate::phf::map::MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { } - impl Sealed for crate::swiss::map::MapRef + impl Sealed for crate::swiss::map::MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { } - impl Sealed for crate::phf::set::SetRef where T: ZeroCopy {} + impl Sealed for crate::phf::set::SetRef + where + T: ZeroCopy, + E: ByteOrder, + O: Size, + { + } - impl Sealed for crate::swiss::set::SetRef where T: ZeroCopy {} + impl Sealed for crate::swiss::set::SetRef + where + T: ZeroCopy, + E: ByteOrder, + O: Size, + { + } } /// Trait used for binding a reference to a [`Buf`] through [`Buf::bind()`]. diff --git a/crates/musli-zerocopy/src/buf/buf.rs b/crates/musli-zerocopy/src/buf/buf.rs index 8aa448f40..562ab48cf 100644 --- a/crates/musli-zerocopy/src/buf/buf.rs +++ b/crates/musli-zerocopy/src/buf/buf.rs @@ -827,13 +827,11 @@ impl Buf { /// # Ok::<_, musli_zerocopy::Error>(()) /// ``` #[inline] - pub fn swap( - &mut self, - a: Ref, - b: Ref, - ) -> Result<(), Error> + pub fn swap(&mut self, a: Ref, b: Ref) -> Result<(), Error> where T: ZeroCopy, + E: ByteOrder, + O: Size, { let a = a.offset(); let b = b.offset(); diff --git a/crates/musli-zerocopy/src/buf/load.rs b/crates/musli-zerocopy/src/buf/load.rs index 62b772c50..f9fc3421a 100644 --- a/crates/musli-zerocopy/src/buf/load.rs +++ b/crates/musli-zerocopy/src/buf/load.rs @@ -33,9 +33,11 @@ pub trait LoadMut: Load { fn load_mut<'buf>(&self, buf: &'buf mut Buf) -> Result<&'buf mut Self::Target, Error>; } -impl Load for Ref +impl Load for Ref where T: ZeroCopy, + E: ByteOrder, + O: Size, { type Target = T; @@ -45,9 +47,11 @@ where } } -impl Load for Ref<[T], E, O> +impl Load for Ref<[T], E, O> where T: ZeroCopy, + E: ByteOrder, + O: Size, { type Target = [T]; @@ -57,7 +61,11 @@ where } } -impl Load for Ref { +impl Load for Ref +where + E: ByteOrder, + O: Size, +{ type Target = str; #[inline] @@ -66,9 +74,11 @@ impl Load for Ref { } } -impl LoadMut for Ref +impl LoadMut for Ref where T: ZeroCopy, + E: ByteOrder, + O: Size, { #[inline] fn load_mut<'buf>(&self, buf: &'buf mut Buf) -> Result<&'buf mut Self::Target, Error> { @@ -76,9 +86,11 @@ where } } -impl LoadMut for Ref<[T], E, O> +impl LoadMut for Ref<[T], E, O> where T: ZeroCopy, + E: ByteOrder, + O: Size, { #[inline] fn load_mut<'buf>(&self, buf: &'buf mut Buf) -> Result<&'buf mut Self::Target, Error> { @@ -86,7 +98,11 @@ where } } -impl LoadMut for Ref { +impl LoadMut for Ref +where + E: ByteOrder, + O: Size, +{ #[inline] fn load_mut<'buf>(&self, buf: &'buf mut Buf) -> Result<&'buf mut Self::Target, Error> { buf.load_unsized_mut(*self) diff --git a/crates/musli-zerocopy/src/buf/owned_buf.rs b/crates/musli-zerocopy/src/buf/owned_buf.rs index c824b07ba..dd036fc6d 100644 --- a/crates/musli-zerocopy/src/buf/owned_buf.rs +++ b/crates/musli-zerocopy/src/buf/owned_buf.rs @@ -33,7 +33,11 @@ use crate::traits::{UnsizedZeroCopy, ZeroCopy}; /// let mut buf = OwnedBuf::new(); /// buf.store(&Custom { field: 10 }); /// ``` -pub struct OwnedBuf { +pub struct OwnedBuf +where + E: ByteOrder, + O: Size, +{ data: NonNull, /// The initialized length of the buffer. len: usize, @@ -169,7 +173,11 @@ impl OwnedBuf { } } -impl OwnedBuf { +impl OwnedBuf +where + E: ByteOrder, + O: Size, +{ /// Modify the buffer to utilize the specified pointer size when inserting /// references. /// @@ -207,7 +215,10 @@ impl OwnedBuf { /// .with_byte_order::(); /// ``` #[inline] - pub fn with_byte_order(self) -> OwnedBuf { + pub fn with_byte_order(self) -> OwnedBuf + where + U: ByteOrder, + { let this = ManuallyDrop::new(self); OwnedBuf { @@ -539,12 +550,14 @@ impl OwnedBuf { /// # Ok::<_, musli_zerocopy::Error>(()) /// ``` #[inline] - pub fn load_uninit_mut( + pub fn load_uninit_mut( &mut self, reference: Ref, U, I>, ) -> &mut MaybeUninit where T: ZeroCopy, + U: ByteOrder, + I: Size, { let at = reference.offset(); @@ -1125,7 +1138,11 @@ unsafe impl Send for OwnedBuf {} /// unaliased. unsafe impl Sync for OwnedBuf {} -impl Deref for OwnedBuf { +impl Deref for OwnedBuf +where + E: ByteOrder, + O: Size, +{ type Target = Buf; #[inline] @@ -1134,14 +1151,22 @@ impl Deref for OwnedBuf { } } -impl DerefMut for OwnedBuf { +impl DerefMut for OwnedBuf +where + E: ByteOrder, + O: Size, +{ #[inline] fn deref_mut(&mut self) -> &mut Self::Target { Buf::new_mut(self.as_mut_slice()) } } -impl AsRef for OwnedBuf { +impl AsRef for OwnedBuf +where + E: ByteOrder, + O: Size, +{ /// Trivial `AsRef` implementation for `OwnedBuf`. /// /// # Examples @@ -1162,7 +1187,11 @@ impl AsRef for OwnedBuf { } } -impl AsMut for OwnedBuf { +impl AsMut for OwnedBuf +where + E: ByteOrder, + O: Size, +{ /// Trivial `AsMut` implementation for `OwnedBuf`. /// /// # Examples @@ -1184,7 +1213,11 @@ impl AsMut for OwnedBuf { } } -impl Borrow for OwnedBuf { +impl Borrow for OwnedBuf +where + E: ByteOrder, + O: Size, +{ #[inline] fn borrow(&self) -> &Buf { self.as_ref() @@ -1219,7 +1252,11 @@ impl Borrow for OwnedBuf { /// buf.align_in_place(); /// assert!(buf.alignment() >= align_of::()); /// ``` -impl Clone for OwnedBuf { +impl Clone for OwnedBuf +where + E: ByteOrder, + O: Size, +{ fn clone(&self) -> Self { unsafe { let mut new = ManuallyDrop::new(Self::with_capacity_and_custom_alignment( @@ -1235,7 +1272,11 @@ impl Clone for OwnedBuf { } } -impl Drop for OwnedBuf { +impl Drop for OwnedBuf +where + E: ByteOrder, + O: Size, +{ fn drop(&mut self) { unsafe { if self.capacity != 0 { @@ -1263,7 +1304,11 @@ const fn invalid_mut(addr: usize) -> *mut T { unsafe { core::mem::transmute(addr) } } -impl StoreBuf for OwnedBuf { +impl StoreBuf for OwnedBuf +where + E: ByteOrder, + O: Size, +{ type ByteOrder = E; type Size = O; diff --git a/crates/musli-zerocopy/src/buf/slice_mut.rs b/crates/musli-zerocopy/src/buf/slice_mut.rs index 8715bbdcd..9dc27f268 100644 --- a/crates/musli-zerocopy/src/buf/slice_mut.rs +++ b/crates/musli-zerocopy/src/buf/slice_mut.rs @@ -140,7 +140,10 @@ where /// .with_byte_order::(); /// ``` #[inline] - pub fn with_byte_order(self) -> SliceMut<'a, U, O> { + pub fn with_byte_order(self) -> SliceMut<'a, U, O> + where + U: ByteOrder, + { let this = ManuallyDrop::new(self); SliceMut { @@ -436,12 +439,14 @@ where /// # Ok::<_, musli_zerocopy::Error>(()) /// ``` #[inline] - pub fn load_uninit_mut( + pub fn load_uninit_mut( &mut self, reference: Ref, U, I>, ) -> &mut MaybeUninit where T: ZeroCopy, + U: ByteOrder, + I: Size, { let at = reference.offset(); diff --git a/crates/musli-zerocopy/src/buf/store_buf.rs b/crates/musli-zerocopy/src/buf/store_buf.rs index 6f10898a7..372dc8b16 100644 --- a/crates/musli-zerocopy/src/buf/store_buf.rs +++ b/crates/musli-zerocopy/src/buf/store_buf.rs @@ -11,10 +11,20 @@ mod sealed { pub trait Sealed {} - impl<'a, E: ByteOrder, O: Size> Sealed for SliceMut<'a, E, O> {} + impl<'a, E, O> Sealed for SliceMut<'a, E, O> + where + E: ByteOrder, + O: Size, + { + } #[cfg(feature = "alloc")] - impl Sealed for OwnedBuf {} + impl Sealed for OwnedBuf + where + E: ByteOrder, + O: Size, + { + } } /// A buffer that we can store things into. diff --git a/crates/musli-zerocopy/src/buf/visit.rs b/crates/musli-zerocopy/src/buf/visit.rs index 79ae252a1..f3f3b7bd9 100644 --- a/crates/musli-zerocopy/src/buf/visit.rs +++ b/crates/musli-zerocopy/src/buf/visit.rs @@ -36,10 +36,12 @@ impl Visit for &T { } } -impl Visit for Ref +impl Visit for Ref where - T: Pointee, + T: ?Sized + Pointee, Self: Load, + E: ByteOrder, + O: Size, { type Target = as Load>::Target; diff --git a/crates/musli-zerocopy/src/endian/endian.rs b/crates/musli-zerocopy/src/endian/endian.rs index 9c4032729..5fb2ef7f9 100644 --- a/crates/musli-zerocopy/src/endian/endian.rs +++ b/crates/musli-zerocopy/src/endian/endian.rs @@ -50,13 +50,19 @@ use crate::ZeroCopy; #[derive(ZeroCopy)] #[zero_copy(crate, swap_bytes_self, bounds = {T: ZeroCopy})] #[repr(transparent)] -pub struct Endian { +pub struct Endian +where + E: ByteOrder, +{ value: T, #[zero_copy(ignore)] _marker: PhantomData, } -impl Endian { +impl Endian +where + T: ZeroCopy, +{ /// Construct new value wrapper with [`Little`] [`ByteOrder`]. /// /// # Examples @@ -74,7 +80,10 @@ impl Endian { } } -impl Endian { +impl Endian +where + T: ZeroCopy, +{ /// Construct new value wrapper with [`Big`] [`ByteOrder`]. /// /// # Examples @@ -92,7 +101,11 @@ impl Endian { } } -impl Endian { +impl Endian +where + T: ZeroCopy, + E: ByteOrder, +{ /// Construct new value wrapper with the specified [`ByteOrder`]. /// /// # Panics @@ -171,9 +184,10 @@ impl Endian { } } -impl fmt::Debug for Endian +impl fmt::Debug for Endian where - T: fmt::Debug, + T: ZeroCopy + fmt::Debug, + E: ByteOrder, { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -181,9 +195,10 @@ where } } -impl Clone for Endian +impl Clone for Endian where - T: Clone, + T: ZeroCopy + Clone, + E: ByteOrder, { fn clone(&self) -> Self { Self { @@ -193,7 +208,12 @@ where } } -impl Copy for Endian where T: Copy {} +impl Copy for Endian +where + T: ZeroCopy + Copy, + E: ByteOrder, +{ +} /// Any `Endian` implements [`Deref`] for natively wrapped types. /// diff --git a/crates/musli-zerocopy/src/endian/mod.rs b/crates/musli-zerocopy/src/endian/mod.rs index f33b43467..b00028aaf 100644 --- a/crates/musli-zerocopy/src/endian/mod.rs +++ b/crates/musli-zerocopy/src/endian/mod.rs @@ -190,7 +190,10 @@ use crate::ZeroCopy; /// bits64: 0x5060708090a0b0c0, /// }); /// ``` -pub fn from_be(value: T) -> T { +pub fn from_be(value: T) -> T +where + T: ZeroCopy, +{ from_endian::<_, Big>(value) } @@ -230,7 +233,10 @@ pub fn from_be(value: T) -> T { /// }); /// ``` #[inline] -pub fn from_le(value: T) -> T { +pub fn from_le(value: T) -> T +where + T: ZeroCopy, +{ from_endian::<_, Little>(value) } @@ -271,8 +277,12 @@ pub fn from_le(value: T) -> T { /// }); /// ``` #[inline] -pub fn from_endian(value: T) -> T { - value.transpose_bytes::() +pub fn from_endian(value: T) -> T +where + T: ZeroCopy, + E: ByteOrder, +{ + value.swap_bytes::().swap_bytes::() } mod sealed { diff --git a/crates/musli-zerocopy/src/error.rs b/crates/musli-zerocopy/src/error.rs index dca70c7e2..a5c3aeb1b 100644 --- a/crates/musli-zerocopy/src/error.rs +++ b/crates/musli-zerocopy/src/error.rs @@ -145,17 +145,10 @@ impl std::error::Error for Error { #[cfg_attr(test, derive(PartialEq))] #[non_exhaustive] pub(crate) enum ErrorKind { - InvalidOffset { - ty: &'static str, - }, InvalidOffsetRange { offset: Repr, max: Repr, }, - InvalidMetadata { - ty: &'static str, - packed: &'static str, - }, InvalidMetadataRange { metadata: Repr, max: Repr, @@ -233,21 +226,9 @@ pub(crate) enum ErrorKind { impl fmt::Display for ErrorKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - ErrorKind::InvalidOffset { ty } => { - write!( - f, - "Offset `{ty}` cannot be byte-ordered since it would not inhabit valid types", - ) - } ErrorKind::InvalidOffsetRange { offset, max } => { write!(f, "Offset {offset} not in legal range 0-{max}",) } - ErrorKind::InvalidMetadata { ty, packed } => { - write!( - f, - "Metadata `{ty}` once packed as `{packed}` cannot be byte-ordered since it would not inhabit valid types", - ) - } ErrorKind::InvalidMetadataRange { metadata, max } => { write!(f, "Metadata {metadata} not in legal range 0-{max}") } diff --git a/crates/musli-zerocopy/src/lib.rs b/crates/musli-zerocopy/src/lib.rs index c12968e51..b11971617 100644 --- a/crates/musli-zerocopy/src/lib.rs +++ b/crates/musli-zerocopy/src/lib.rs @@ -335,7 +335,11 @@ //! //! #[derive(ZeroCopy)] //! #[repr(C)] -//! struct Archive where E: ByteOrder, O: Size { +//! struct Archive +//! where +//! E: ByteOrder, +//! O: Size +//! { //! string: Ref, //! number: Endian, //! } diff --git a/crates/musli-zerocopy/src/mem/maybe_uninit.rs b/crates/musli-zerocopy/src/mem/maybe_uninit.rs index 80c8d979c..c688bde3f 100644 --- a/crates/musli-zerocopy/src/mem/maybe_uninit.rs +++ b/crates/musli-zerocopy/src/mem/maybe_uninit.rs @@ -4,7 +4,7 @@ use core::ptr::NonNull; use core::slice; use crate::buf; -use crate::pointer::Pointee; +use crate::pointer::{Pointee, Size}; use crate::traits::ZeroCopy; /// A value which might or might not have been initialized. @@ -114,4 +114,15 @@ where T: Pointee, { type Metadata = T::Metadata; + type Stored = T::Stored + where + O: Size; + + #[inline] + fn try_from_metadata(metadata: Self::Metadata) -> Option> + where + O: Size, + { + T::try_from_metadata(metadata) + } } diff --git a/crates/musli-zerocopy/src/phf/factory.rs b/crates/musli-zerocopy/src/phf/factory.rs index bcaf897e5..b8c49775d 100644 --- a/crates/musli-zerocopy/src/phf/factory.rs +++ b/crates/musli-zerocopy/src/phf/factory.rs @@ -134,10 +134,7 @@ pub fn store_set( ) -> Result, Error> where S: ?Sized + StoreBuf, - I: IntoIterator, - I::Item: Visit + ZeroCopy, - ::Target: Hash, - I::IntoIter: ExactSizeIterator, + I: IntoIterator + ZeroCopy, IntoIter: ExactSizeIterator>, { let (key, entries, displacements) = store_raw(buf, entries, |entry| entry)?; Ok(SetRef::new(key, entries, displacements)) @@ -156,11 +153,8 @@ fn store_raw( Error, > where - K: Visit + ZeroCopy, - K::Target: Hash, - I: IntoIterator, - I::Item: ZeroCopy, - I::IntoIter: ExactSizeIterator, + K: Visit + ZeroCopy, + I: IntoIterator, S: ?Sized + StoreBuf, F: Fn(&I::Item) -> &K, { @@ -205,9 +199,7 @@ where fn build_slice(buf: &mut S, entries: I) -> Ref<[I::Item], S::ByteOrder, S::Size> where S: ?Sized + StoreBuf, - I: IntoIterator, - I::Item: ZeroCopy, - I::IntoIter: ExactSizeIterator, + I: IntoIterator, { let offset = buf.next_offset::(); let iter = entries.into_iter(); diff --git a/crates/musli-zerocopy/src/phf/generator.rs b/crates/musli-zerocopy/src/phf/generator.rs index 5576a6021..9a71a00d4 100644 --- a/crates/musli-zerocopy/src/phf/generator.rs +++ b/crates/musli-zerocopy/src/phf/generator.rs @@ -25,7 +25,7 @@ pub(crate) fn displacements_len(len: usize) -> usize { (len + DEFAULT_LAMBDA - 1) / DEFAULT_LAMBDA } -pub(crate) fn generate_hash( +pub(crate) fn generate_hash( buf: &mut Buf, entries: &Ref<[T], E, O>, displacements: &Ref<[Entry], E, O>, @@ -37,6 +37,8 @@ where K::Target: Hash, F: Fn(&T) -> &K, T: ZeroCopy, + E: ByteOrder, + O: Size, { for key in SmallRng::seed_from_u64(FIXED_SEED).sample_iter(Standard) { if let Some(hash) = try_generate_hash(buf, entries, displacements, map, key, &access)? { @@ -56,7 +58,7 @@ where Err(Error::new(ErrorKind::FailedPhf)) } -fn try_generate_hash( +fn try_generate_hash( buf: &mut Buf, entries: &Ref<[T], E, O>, displacements: &Ref<[Entry], E, O>, @@ -69,6 +71,8 @@ where K::Target: Hash, F: ?Sized + Fn(&T) -> &K, T: ZeroCopy, + E: ByteOrder, + O: Size, { let mut hashes = Vec::new(); diff --git a/crates/musli-zerocopy/src/phf/map.rs b/crates/musli-zerocopy/src/phf/map.rs index 1e14b593f..0da05f648 100644 --- a/crates/musli-zerocopy/src/phf/map.rs +++ b/crates/musli-zerocopy/src/phf/map.rs @@ -162,10 +162,12 @@ where } /// Bind a [`MapRef`] into a [`Map`]. -impl Bindable for MapRef +impl Bindable for MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { type Bound<'a> = Map<'a, K, V> where Self: 'a; @@ -213,20 +215,24 @@ where #[derive(Debug, ZeroCopy)] #[repr(C)] #[zero_copy(crate)] -pub struct MapRef +pub struct MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { key: Endian, entries: Ref<[Entry], E, O>, displacements: Ref<[Entry], E, O>, } -impl MapRef +impl MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { #[cfg(feature = "alloc")] pub(crate) fn new( @@ -242,10 +248,12 @@ where } } -impl MapRef +impl MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { /// Get a value from the map. /// @@ -361,19 +369,23 @@ where } } -impl Clone for MapRef +impl Clone for MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { fn clone(&self) -> Self { *self } } -impl Copy for MapRef +impl Copy for MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { } diff --git a/crates/musli-zerocopy/src/phf/set.rs b/crates/musli-zerocopy/src/phf/set.rs index f509119e2..2e2c7e64e 100644 --- a/crates/musli-zerocopy/src/phf/set.rs +++ b/crates/musli-zerocopy/src/phf/set.rs @@ -94,9 +94,11 @@ where } /// Bind a [`SetRef`] into a [`Set`]. -impl Bindable for SetRef +impl Bindable for SetRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { type Bound<'a> = Set<'a, T> where Self: 'a; @@ -141,18 +143,22 @@ where #[derive(Debug, ZeroCopy)] #[repr(C)] #[zero_copy(crate)] -pub struct SetRef +pub struct SetRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { key: Endian, entries: Ref<[T], E, O>, displacements: Ref<[Entry], E, O>, } -impl SetRef +impl SetRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { #[cfg(feature = "alloc")] #[inline] @@ -169,9 +175,11 @@ where } } -impl SetRef +impl SetRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { /// Get a value from the set. /// diff --git a/crates/musli-zerocopy/src/pointer/coerce.rs b/crates/musli-zerocopy/src/pointer/coerce.rs index ec497647d..ae527421f 100644 --- a/crates/musli-zerocopy/src/pointer/coerce.rs +++ b/crates/musli-zerocopy/src/pointer/coerce.rs @@ -1,4 +1,4 @@ -use crate::pointer::{CoerceSlice, Packable, Pointee, Size}; +use crate::pointer::{CoerceSlice, Pointee, Size}; use crate::traits::ZeroCopy; /// A trait indicating that a coercion from `Self` to `U` is correct from a size @@ -7,16 +7,12 @@ pub trait Coerce: Pointee { /// Coerce metadata from `Self` to `U`. /// /// Any overflow will wrap around. - fn coerce_metadata( - metadata: ::Packed, - ) -> ::Packed; + fn coerce_metadata(metadata: Self::Stored) -> U::Stored; /// Try to coerce metadata from `Self` to `U`. /// /// Any overflow will result in `None`. - fn try_coerce_metadata( - metadata: ::Packed, - ) -> Option<::Packed>; + fn try_coerce_metadata(metadata: Self::Stored) -> Option>; } /// Defines a coercion from a slice `[T]` to `[U]`. @@ -186,14 +182,12 @@ where [T]: CoerceSlice<[U]>, { #[inline] - fn coerce_metadata((): ()) -> <<[T] as Pointee>::Metadata as Packable>::Packed { + fn coerce_metadata((): ()) -> O { <[T]>::resize(O::ONE) } #[inline] - fn try_coerce_metadata( - (): (), - ) -> Option<<<[T] as Pointee>::Metadata as Packable>::Packed> { + fn try_coerce_metadata((): ()) -> Option { <[T]>::try_resize(O::ONE) } } @@ -223,15 +217,13 @@ where [T]: CoerceSlice<[U]>, { #[inline] - fn coerce_metadata((): ()) -> <<[T] as Pointee>::Metadata as Packable>::Packed { + fn coerce_metadata((): ()) -> <[T] as Pointee>::Stored { let factor = O::try_from_usize(N).unwrap_or(O::MAX); <[T]>::resize(factor) } #[inline] - fn try_coerce_metadata( - (): (), - ) -> Option<<<[T] as Pointee>::Metadata as Packable>::Packed> { + fn try_coerce_metadata((): ()) -> Option<<[T] as Pointee>::Stored> { let factor = O::try_from_usize(N)?; <[T]>::try_resize(factor) } diff --git a/crates/musli-zerocopy/src/pointer/mod.rs b/crates/musli-zerocopy/src/pointer/mod.rs index 84af179ca..cd558d159 100644 --- a/crates/musli-zerocopy/src/pointer/mod.rs +++ b/crates/musli-zerocopy/src/pointer/mod.rs @@ -30,10 +30,6 @@ mod r#ref; pub use self::pointee::Pointee; mod pointee; -#[doc(inline)] -pub use self::packable::Packable; -mod packable; - pub use self::coerce::Coerce; mod coerce; diff --git a/crates/musli-zerocopy/src/pointer/packable.rs b/crates/musli-zerocopy/src/pointer/packable.rs deleted file mode 100644 index 91f4ef5bd..000000000 --- a/crates/musli-zerocopy/src/pointer/packable.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::pointer::Size; -use crate::traits::ZeroCopy; - -mod sealed { - pub trait Sealed {} - impl Sealed for () {} - impl Sealed for usize {} -} - -/// A type that can inhabit a packed representation. -pub trait Packable: self::sealed::Sealed { - /// The packed representation of the item. - #[doc(hidden)] - type Packed: Copy + ZeroCopy - where - O: Size; - - /// Try to construct packed value from its metadata. - fn try_from_metadata(metadata: Self) -> Option> - where - O: Size; -} - -impl Packable for () { - type Packed = () where O: Size; - - #[inline(always)] - fn try_from_metadata((): ()) -> Option> - where - O: Size, - { - Some(()) - } -} - -impl Packable for usize { - type Packed = O where O: Size; - - #[inline(always)] - fn try_from_metadata(metadata: Self) -> Option> - where - O: Size, - { - O::try_from_usize(metadata) - } -} diff --git a/crates/musli-zerocopy/src/pointer/pointee.rs b/crates/musli-zerocopy/src/pointer/pointee.rs index 93f86b243..62ca24880 100644 --- a/crates/musli-zerocopy/src/pointer/pointee.rs +++ b/crates/musli-zerocopy/src/pointer/pointee.rs @@ -1,7 +1,7 @@ use core::fmt; use crate::error::IntoRepr; -use crate::pointer::Packable; +use crate::pointer::Size; use crate::traits::ZeroCopy; mod sealed { @@ -34,7 +34,19 @@ mod sealed { /// [`Ref`]: crate::Ref pub trait Pointee: self::sealed::Sealed { /// Metadata associated with a pointee. - type Metadata: Copy + fmt::Debug + Packable + IntoRepr; + type Metadata: Copy + fmt::Debug + IntoRepr; + + /// The stored representation of the pointee metadata. + #[doc(hidden)] + type Stored: Copy + ZeroCopy + where + O: Size; + + /// Try to construct packed value from its metadata. + #[doc(hidden)] + fn try_from_metadata(metadata: Self::Metadata) -> Option> + where + O: Size; } impl Pointee for T @@ -42,6 +54,15 @@ where T: ZeroCopy, { type Metadata = (); + type Stored = () where O: Size; + + #[inline(always)] + fn try_from_metadata((): ()) -> Option> + where + O: Size, + { + Some(()) + } } impl Pointee for [T] @@ -49,8 +70,26 @@ where T: ZeroCopy, { type Metadata = usize; + type Stored = O where O: Size; + + #[inline(always)] + fn try_from_metadata(metadata: usize) -> Option + where + O: Size, + { + O::try_from_usize(metadata) + } } impl Pointee for str { type Metadata = usize; + type Stored = O where O: Size; + + #[inline(always)] + fn try_from_metadata(metadata: usize) -> Option + where + O: Size, + { + O::try_from_usize(metadata) + } } diff --git a/crates/musli-zerocopy/src/pointer/ref.rs b/crates/musli-zerocopy/src/pointer/ref.rs index 853ba086b..5d2deff50 100644 --- a/crates/musli-zerocopy/src/pointer/ref.rs +++ b/crates/musli-zerocopy/src/pointer/ref.rs @@ -1,14 +1,14 @@ use core::cmp::Ordering; +use core::fmt; use core::hash::Hash; use core::marker::PhantomData; use core::mem::size_of; -use core::{any, fmt}; use crate::endian::{Big, ByteOrder, Little, Native}; use crate::error::{Error, ErrorKind, IntoRepr}; use crate::mem::MaybeUninit; use crate::pointer::Coerce; -use crate::pointer::{DefaultSize, Packable, Pointee, Size}; +use crate::pointer::{DefaultSize, Pointee, Size}; use crate::ZeroCopy; /// A stored reference to a type `T`. @@ -42,7 +42,7 @@ use crate::ZeroCopy; /// ``` #[derive(ZeroCopy)] #[repr(C)] -#[zero_copy(crate, swap_bytes_self, bounds = {::Packed: ZeroCopy})] +#[zero_copy(crate, swap_bytes_self)] pub struct Ref where T: ?Sized + Pointee, @@ -50,7 +50,7 @@ where O: Size, { offset: O, - metadata: ::Packed, + metadata: T::Stored, #[zero_copy(ignore)] _marker: PhantomData<(E, T)>, } @@ -143,8 +143,8 @@ where #[inline] pub fn to_endian(self) -> Ref { Ref { - offset: self.offset.transpose_bytes::(), - metadata: self.metadata.transpose_bytes::(), + offset: self.offset.swap_bytes::().swap_bytes::(), + metadata: self.metadata.swap_bytes::().swap_bytes::(), _marker: PhantomData, } } @@ -188,23 +188,24 @@ where U: Copy + fmt::Debug, O: TryFrom, { - assert!( - O::CAN_SWAP_BYTES, - "Offset `{}` cannot be byte-ordered since it would not inhabit valid types", - any::type_name::() - ); + const { + assert!( + O::CAN_SWAP_BYTES, + "Offset cannot be byte-ordered since it would not inhabit valid types" + ); + } let Some(offset) = O::try_from(offset).ok() else { panic!("Offset {offset:?} not in legal range 0-{}", O::MAX); }; - let Some(metadata) = ::try_from_metadata(metadata) else { + let Some(metadata) = T::try_from_metadata(metadata) else { panic!("Metadata {metadata:?} not in legal range 0-{}", O::MAX); }; Self { offset: O::swap_bytes::(offset), - metadata: ::Packed::::swap_bytes::(metadata), + metadata: T::Stored::::swap_bytes::(metadata), _marker: PhantomData, } } @@ -213,9 +214,10 @@ where /// /// # Errors /// + /// This will not compile through a constant assertion if the `offset` or + /// `metadata` can't be byte swapped as per [`ZeroCopy::CAN_SWAP_BYTES`]. + /// /// This will error if either: - /// * The `offset` or `metadata` can't be byte swapped as per - /// [`ZeroCopy::CAN_SWAP_BYTES`]. /// * Packed [`offset()`] cannot be constructed from `U` (out of range). /// * Packed [`metadata()`] cannot be constructed from `T::Metadata` (reason /// depends on the exact metadata). @@ -241,17 +243,16 @@ where U: Copy + IntoRepr + fmt::Debug, O: TryFrom, { - if !O::CAN_SWAP_BYTES { - return Err(Error::new(ErrorKind::InvalidOffset { - ty: any::type_name::(), - })); - } - - if !::Packed::::CAN_SWAP_BYTES { - return Err(Error::new(ErrorKind::InvalidMetadata { - ty: any::type_name::(), - packed: any::type_name::<::Packed>(), - })); + const { + assert!( + O::CAN_SWAP_BYTES, + "Offset cannot be byte-ordered since it would not inhabit valid types" + ); + + assert!( + T::Stored::::CAN_SWAP_BYTES, + "Packed offset cannot be byte-ordered since it would not inhabit valid types" + ); } let Some(offset) = O::try_from(offset).ok() else { @@ -261,7 +262,7 @@ where })); }; - let Some(metadata) = ::try_from_metadata(metadata) else { + let Some(metadata) = T::try_from_metadata(metadata) else { return Err(Error::new(ErrorKind::InvalidMetadataRange { metadata: T::Metadata::into_repr(metadata), max: O::into_repr(O::MAX), @@ -270,7 +271,7 @@ where Ok(Self { offset: O::swap_bytes::(offset), - metadata: ::Packed::::swap_bytes::(metadata), + metadata: T::Stored::swap_bytes::(metadata), _marker: PhantomData, }) } @@ -564,24 +565,27 @@ where /// assert_eq!(slice.metadata(), 10); /// ``` #[inline] - pub fn metadata(self) -> ::Packed { + pub fn metadata(self) -> T::Stored { self.metadata } } impl Ref where - T: Pointee, + T: Pointee = ()>, E: ByteOrder, O: Size, { /// Construct a reference at the given offset. /// + /// # Errors + /// + /// This will not compile through a constant assertion if the `offset` or + /// can't be byte swapped as per [`ZeroCopy::CAN_SWAP_BYTES`]. + /// /// # Panics /// - /// This will panic if either: - /// * The `offset` can't be byte swapped as per - /// [`ZeroCopy::CAN_SWAP_BYTES`]. + /// This will panic if: /// * Packed [`offset()`] cannot be constructed from `U` (out of range). /// /// [`offset()`]: Self::offset @@ -594,17 +598,26 @@ where /// let reference = Ref::::new(42); /// assert_eq!(reference.offset(), 42); /// ``` + /// + /// Characters cannot be used as offsets: + /// + /// ```compile_fail + /// use musli_zerocopy::Ref; + /// + /// let reference = Ref::<_, _, char>::new('a'); + /// ``` #[inline] pub fn new(offset: U) -> Self where U: Copy + fmt::Debug, O: TryFrom, { - assert!( - O::CAN_SWAP_BYTES, - "Type `{}` cannot be byte-ordered since it would not inhabit valid types", - any::type_name::() - ); + const { + assert!( + O::CAN_SWAP_BYTES, + "Offset cannot be byte-ordered since it would not inhabit valid types", + ); + } let Some(offset) = O::try_from(offset).ok() else { panic!("Offset {offset:?} not in the legal range 0-{}", O::MAX); @@ -760,7 +773,7 @@ where #[cfg(test)] pub(crate) fn cast(self) -> Ref where - U: ?Sized + Pointee, + U: ?Sized + Pointee = T::Stored>, { Ref { offset: self.offset, @@ -819,8 +832,7 @@ where impl fmt::Debug for Ref where - T: ?Sized + Pointee, - ::Packed: fmt::Debug, + T: ?Sized + Pointee: fmt::Debug>, E: ByteOrder, O: Size + fmt::Debug, { @@ -836,9 +848,11 @@ where } } -impl Clone for Ref +impl Clone for Ref where - T: Pointee, + T: ?Sized + Pointee, + E: ByteOrder, + O: Size, { #[inline] fn clone(&self) -> Self { @@ -846,13 +860,19 @@ where } } -impl Copy for Ref where T: Pointee {} +impl Copy for Ref +where + T: ?Sized + Pointee, + E: ByteOrder, + O: Size, +{ +} -impl PartialEq for Ref +impl PartialEq for Ref where - T: Pointee, - O: PartialEq, - ::Packed: PartialEq, + T: ?Sized + Pointee: PartialEq>, + E: ByteOrder, + O: PartialEq + Size, { #[inline] fn eq(&self, other: &Self) -> bool { @@ -860,19 +880,19 @@ where } } -impl Eq for Ref +impl Eq for Ref where - T: Pointee, - O: Eq, - ::Packed: Eq, + T: ?Sized + Pointee: Eq>, + E: ByteOrder, + O: Eq + Size, { } -impl PartialOrd for Ref +impl PartialOrd for Ref where - T: Pointee, - O: Ord, - ::Packed: PartialOrd, + T: ?Sized + Pointee: PartialOrd>, + E: ByteOrder, + O: Ord + Size, { #[inline] fn partial_cmp(&self, other: &Self) -> Option { @@ -885,11 +905,11 @@ where } } -impl Ord for Ref +impl Ord for Ref where - T: Pointee, - O: Ord, - ::Packed: Ord, + T: ?Sized + Pointee: Ord>, + E: ByteOrder, + O: Ord + Size, { #[inline] fn cmp(&self, other: &Self) -> Ordering { @@ -902,11 +922,11 @@ where } } -impl Hash for Ref +impl Hash for Ref where - T: Pointee, - O: Hash, - ::Packed: Hash, + T: ?Sized + Pointee: Hash>, + E: ByteOrder, + O: Hash + Size, { #[inline] fn hash(&self, state: &mut H) { diff --git a/crates/musli-zerocopy/src/pointer/size.rs b/crates/musli-zerocopy/src/pointer/size.rs index d40ed2f1f..4e789287a 100644 --- a/crates/musli-zerocopy/src/pointer/size.rs +++ b/crates/musli-zerocopy/src/pointer/size.rs @@ -78,7 +78,9 @@ pub trait Size: /// Convert the pointer to a usize. #[doc(hidden)] - fn as_usize(self) -> usize; + fn as_usize(self) -> usize + where + E: ByteOrder; /// Test if the value is zero. #[doc(hidden)] @@ -126,7 +128,10 @@ macro_rules! impl_size { } #[inline] - fn as_usize(self) -> usize { + fn as_usize(self) -> usize + where + E: ByteOrder, + { if self > usize::MAX as $ty { usize::MAX } else { diff --git a/crates/musli-zerocopy/src/slice/binary_search.rs b/crates/musli-zerocopy/src/slice/binary_search.rs index d01392178..555cd09bd 100644 --- a/crates/musli-zerocopy/src/slice/binary_search.rs +++ b/crates/musli-zerocopy/src/slice/binary_search.rs @@ -49,8 +49,7 @@ pub enum BinarySearch { /// ``` pub fn binary_search(buf: &Buf, slice: S, x: &Q) -> Result where - S: Slice, - S::Item: ZeroCopy + Ord, + S: Slice, Q: Visit, { binary_search_by(buf, slice, |value| x.visit(buf, |x| value.cmp(x))) @@ -97,8 +96,7 @@ where /// ``` pub fn binary_search_by(buf: &Buf, slice: S, mut f: F) -> Result where - S: Slice, - S::Item: ZeroCopy, + S: Slice, F: FnMut(&S::Item) -> Result, { // INVARIANTS: diff --git a/crates/musli-zerocopy/src/slice/slice.rs b/crates/musli-zerocopy/src/slice/slice.rs index ccff419e0..13ed338ff 100644 --- a/crates/musli-zerocopy/src/slice/slice.rs +++ b/crates/musli-zerocopy/src/slice/slice.rs @@ -12,9 +12,21 @@ mod sealed { pub trait Sealed {} - impl Sealed for Ref<[T], E, O> where T: ZeroCopy {} + impl Sealed for Ref<[T], E, O> + where + T: ZeroCopy, + E: ByteOrder, + O: Size, + { + } - impl Sealed for Packed<[T], O, L, E> {} + impl Sealed for Packed<[T], O, L, E> + where + O: Size, + L: Size, + E: ByteOrder, + { + } } /// A trait implemented by slice-like types. @@ -38,13 +50,19 @@ pub trait Slice: self::sealed::Sealed + Copy + ZeroCopy + Load(r: Ref<[S::Item]>) -> S where S: Slice, S::Item: ZeroCopy { + /// fn generic(r: Ref<[S::Item]>) -> S + /// where + /// S: Slice, + /// S::Item: ZeroCopy + /// { /// S::from_ref(r) /// } /// ``` - fn from_ref(slice: Ref<[Self::Item], E, O>) -> Self + fn from_ref(slice: Ref<[Self::Item], E, O>) -> Self where - Self::Item: ZeroCopy; + Self::Item: ZeroCopy, + E: ByteOrder, + O: Size; /// Try to construct a slice from a [`Ref<[Self::Item]>`]. /// @@ -59,13 +77,18 @@ pub trait Slice: self::sealed::Sealed + Copy + ZeroCopy + Load(r: Ref<[S::Item]>) -> Result where S: Slice, S::Item: ZeroCopy { + /// fn generic(r: Ref<[S::Item]>) -> Result + /// where + /// S: Slice + /// { /// S::try_from_ref(r) /// } /// ``` - fn try_from_ref(slice: Ref<[Self::Item], E, O>) -> Result + fn try_from_ref(slice: Ref<[Self::Item], E, O>) -> Result where - Self::Item: ZeroCopy; + Self::Item: ZeroCopy, + E: ByteOrder, + O: Size; /// Construct a slice from its `offset` and `len`. /// @@ -274,17 +297,21 @@ where type ItemRef = Ref; #[inline] - fn from_ref(slice: Ref<[T], E, O>) -> Self + fn from_ref(slice: Ref<[T], E, O>) -> Self where T: ZeroCopy, + E: ByteOrder, + O: Size, { Ref::with_metadata(slice.offset(), slice.len()) } #[inline] - fn try_from_ref(slice: Ref<[T], E, O>) -> Result + fn try_from_ref(slice: Ref<[T], E, O>) -> Result where T: ZeroCopy, + E: ByteOrder, + O: Size, { Ref::try_with_metadata(slice.offset(), slice.len()) } diff --git a/crates/musli-zerocopy/src/swiss/factory.rs b/crates/musli-zerocopy/src/swiss/factory.rs index a25c959be..146e773b3 100644 --- a/crates/musli-zerocopy/src/swiss/factory.rs +++ b/crates/musli-zerocopy/src/swiss/factory.rs @@ -104,7 +104,7 @@ const FIXED_SEED: u64 = 1234567890; /// assert_eq!(map.get(&())?, Some(&())); /// # Ok::<_, musli_zerocopy::Error>(()) /// ``` -pub fn store_map( +pub fn store_map( buf: &mut OwnedBuf, entries: I, ) -> Result, Error> @@ -114,6 +114,8 @@ where K::Target: Hash, I: IntoIterator, I::IntoIter: ExactSizeIterator, + E: ByteOrder, + O: Size, { let (key, ctrl, buckets, bucket_mask, len) = store_raw(entries, buf, |buf, (k, v), hasher| { k.visit(buf, |key| key.hash(hasher))?; diff --git a/crates/musli-zerocopy/src/swiss/map.rs b/crates/musli-zerocopy/src/swiss/map.rs index da04d07d0..6a83ae550 100644 --- a/crates/musli-zerocopy/src/swiss/map.rs +++ b/crates/musli-zerocopy/src/swiss/map.rs @@ -183,10 +183,12 @@ where } /// Bind a [`MapRef`] into a [`Map`]. -impl Bindable for MapRef +impl Bindable for MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { type Bound<'a> = Map<'a, K, V> where Self: 'a; @@ -233,19 +235,23 @@ where #[derive(Debug, ZeroCopy)] #[repr(C)] #[zero_copy(crate)] -pub struct MapRef +pub struct MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { key: Endian, table: RawTableRef, E, O>, } -impl MapRef +impl MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { #[cfg(feature = "alloc")] pub(crate) fn new(key: u64, table: RawTableRef, E, O>) -> Self { @@ -376,20 +382,24 @@ where } } -impl Clone for MapRef +impl Clone for MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { fn clone(&self) -> Self { *self } } -impl Copy for MapRef +impl Copy for MapRef where K: ZeroCopy, V: ZeroCopy, + E: ByteOrder, + O: Size, { } @@ -477,9 +487,11 @@ impl<'a, T> RawTable<'a, T> { #[derive(Debug, ZeroCopy)] #[repr(C)] #[zero_copy(crate)] -pub(crate) struct RawTableRef +pub(crate) struct RawTableRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { ctrl: Ref<[u8], E, O>, entries: Ref<[T], E, O>, @@ -487,9 +499,11 @@ where len: Endian, } -impl RawTableRef +impl RawTableRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { #[cfg(feature = "alloc")] #[inline] @@ -589,13 +603,21 @@ where } } -impl Clone for RawTableRef +impl Clone for RawTableRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { fn clone(&self) -> Self { *self } } -impl Copy for RawTableRef where T: ZeroCopy {} +impl Copy for RawTableRef +where + T: ZeroCopy, + E: ByteOrder, + O: Size, +{ +} diff --git a/crates/musli-zerocopy/src/swiss/set.rs b/crates/musli-zerocopy/src/swiss/set.rs index c21703bae..61ba34f3c 100644 --- a/crates/musli-zerocopy/src/swiss/set.rs +++ b/crates/musli-zerocopy/src/swiss/set.rs @@ -96,9 +96,11 @@ where } /// Bind a [`SetRef`] into a [`Set`]. -impl Bindable for SetRef +impl Bindable for SetRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { type Bound<'a> = Set<'a, T> where Self: 'a; @@ -141,17 +143,21 @@ where #[derive(Debug, ZeroCopy)] #[repr(C)] #[zero_copy(crate)] -pub struct SetRef +pub struct SetRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { key: u64, table: RawTableRef, } -impl SetRef +impl SetRef where T: ZeroCopy, + E: ByteOrder, + O: Size, { #[cfg(feature = "alloc")] pub(crate) fn new(key: u64, table: RawTableRef) -> Self { diff --git a/crates/musli-zerocopy/src/tests/enum_byte_order.rs b/crates/musli-zerocopy/src/tests/enum_byte_order.rs index 7b5a489e7..97bbb2041 100644 --- a/crates/musli-zerocopy/src/tests/enum_byte_order.rs +++ b/crates/musli-zerocopy/src/tests/enum_byte_order.rs @@ -1,55 +1,45 @@ use crate::endian::{Big, Little, Other}; -use crate::{Endian, ZeroCopy}; +use crate::{ByteOrder, Endian, ZeroCopy}; #[repr(C)] struct Align([A; 0], T); -#[derive(ZeroCopy, PartialEq, Debug, Clone, Copy)] -#[zero_copy(crate, swap_bytes)] -#[repr(u32)] -enum SomeEnum { - A = 1, - #[zero_copy(swap = A)] - A_ = u32::swap_bytes(1), - B = 2, - #[zero_copy(swap = B)] - B_ = u32::swap_bytes(2), -} - -#[derive(ZeroCopy, Debug, Clone, Copy)] -#[zero_copy(crate)] -#[repr(C)] -struct SomeStructBE { - a: Endian, - b: Endian, -} - #[test] -fn test_from_bytes_be() { - let data: &[u8; 8] = &Align::([], [0, 0, 0, 1, 0, 0, 0, 2]).1; - - let struct_be = SomeStructBE::from_bytes(data).unwrap(); - - assert_eq!(struct_be.a.to_ne(), 1); - assert_eq!(struct_be.b.to_ne(), SomeEnum::B); -} - -#[derive(ZeroCopy, Debug, Clone, Copy)] -#[zero_copy(crate)] -#[repr(C)] -struct SomeStructLE { - a: Endian, - b: Endian, -} - -#[test] -fn test_from_bytes_le() { - let data: &[u8; 8] = &Align::([], [1, 0, 0, 0, 2, 0, 0, 0]).1; - - let struct_be = SomeStructLE::from_bytes(data).unwrap(); - - assert_eq!(struct_be.a.to_ne(), 1); - assert_eq!(struct_be.b.to_ne(), SomeEnum::B); +fn test_byte_order() { + #[derive(ZeroCopy, PartialEq, Debug, Clone, Copy)] + #[zero_copy(crate, swap_bytes)] + #[repr(u32)] + enum SomeEnum { + A = 1, + #[zero_copy(swap = A)] + A_ = u32::swap_bytes(1), + B = 2, + #[zero_copy(swap = B)] + B_ = u32::swap_bytes(2), + } + + #[derive(ZeroCopy, Debug, Clone, Copy)] + #[zero_copy(crate)] + #[repr(C)] + struct SomeStruct + where + T: ByteOrder, + { + a: Endian, + b: Endian, + } + + let data: &[u8; 8] = &Align::, _>([], [0, 0, 0, 1, 0, 0, 0, 2]).1; + let st = SomeStruct::::from_bytes(data).unwrap(); + + assert_eq!(st.a.to_ne(), 1); + assert_eq!(st.b.to_ne(), SomeEnum::B); + + let data: &[u8; 8] = &Align::, _>([], [1, 0, 0, 0, 2, 0, 0, 0]).1; + let st = SomeStruct::::from_bytes(data).unwrap(); + + assert_eq!(st.a.to_ne(), 1); + assert_eq!(st.b.to_ne(), SomeEnum::B); } #[derive(ZeroCopy, PartialEq, Debug, Clone, Copy)] @@ -78,59 +68,54 @@ enum EnumSwapBytesMismatch { const _: () = assert!(!EnumSwapBytesMismatch::CAN_SWAP_BYTES); -#[test] -fn test_enum_unsupported_swap_bytes() {} - -#[derive(ZeroCopy, PartialEq, Debug, Clone, Copy)] -#[zero_copy(crate, swap_bytes)] -#[repr(u32)] -enum FieldEnum { - A { - field: u32, - } = 1, - #[zero_copy(swap = A)] - A_ { - field: u32, - } = u32::swap_bytes(1), - B = 2, - #[zero_copy(swap = B)] - B_ = u32::swap_bytes(2), -} - -const _: () = assert!(FieldEnum::CAN_SWAP_BYTES); - #[test] fn test_field_enum() { + #[derive(ZeroCopy, PartialEq, Debug, Clone, Copy)] + #[zero_copy(crate, swap_bytes)] + #[repr(u32)] + enum FieldEnum { + A { + field: u32, + } = 1, + #[zero_copy(swap = A)] + OtherA { + field: u32, + } = u32::swap_bytes(1), + B = 2, + #[zero_copy(swap = B)] + OtherB = u32::swap_bytes(2), + } + + const _: () = assert!(FieldEnum::CAN_SWAP_BYTES); + let a = FieldEnum::A { field: 42 }; let a_ = a.swap_bytes::(); - - let b = FieldEnum::B; - let b_ = b.swap_bytes::(); - assert_eq!( a_, - FieldEnum::A_ { + FieldEnum::OtherA { field: u32::swap_bytes(42) } ); - assert_eq!(b_, FieldEnum::B_); -} - -#[derive(ZeroCopy, PartialEq, Debug, Clone, Copy)] -#[zero_copy(crate, swap_bytes)] -#[repr(u32)] -enum FieldEnumImplicit { - A { field: u32 } = 1, - A_ { field: u32 } = u32::swap_bytes(1), - B = 2, - B_ = u32::swap_bytes(2), + let b = FieldEnum::B; + let b_ = b.swap_bytes::(); + assert_eq!(b_, FieldEnum::OtherB); } -const _: () = assert!(FieldEnumImplicit::CAN_SWAP_BYTES); - #[test] fn test_field_enum_implicit() { + #[derive(ZeroCopy, PartialEq, Debug, Clone, Copy)] + #[zero_copy(crate, swap_bytes)] + #[repr(u32)] + enum FieldEnumImplicit { + A { field: u32 } = 1, + A_ { field: u32 } = u32::swap_bytes(1), + B = 2, + B_ = u32::swap_bytes(2), + } + + const _: () = assert!(FieldEnumImplicit::CAN_SWAP_BYTES); + let a = FieldEnumImplicit::A { field: 42 }; let a_ = a.swap_bytes::(); diff --git a/crates/musli-zerocopy/src/traits.rs b/crates/musli-zerocopy/src/traits.rs index c691d9b43..bbcc75841 100644 --- a/crates/musli-zerocopy/src/traits.rs +++ b/crates/musli-zerocopy/src/traits.rs @@ -27,7 +27,7 @@ use core::str; use crate::buf::{Buf, Padder, Validator, Visit}; use crate::endian::ByteOrder; use crate::error::{Error, ErrorKind}; -use crate::pointer::{Packable, Pointee, Size}; +use crate::pointer::{Pointee, Size}; mod sealed { use crate::ZeroCopy; @@ -86,11 +86,14 @@ pub unsafe trait UnsizedZeroCopy: self::sealed::Sealed + Pointee { /// Validate the buffer with the given capacity and return the decoded /// metadata. - unsafe fn validate_unsized( + unsafe fn validate_unsized( data: NonNull, len: usize, - metadata: ::Packed, - ) -> Result; + metadata: Self::Stored, + ) -> Result + where + E: ByteOrder, + O: Size; /// Construct a wide pointer from a pointer and its associated metadata. /// @@ -226,7 +229,10 @@ where } #[inline] - fn swap_bytes(self) -> Self { + fn swap_bytes(self) -> Self + where + E: ByteOrder, + { Wrapping(T::swap_bytes::(self.0)) } } @@ -445,11 +451,11 @@ pub unsafe trait ZeroCopy: Sized { /// [`to_bytes_unchecked()`]: Self::to_bytes_unchecked /// [`to_bytes()`]: Self::to_bytes /// [type level documentation]: Self + #[inline] fn initialize_padding(&mut self) { unsafe { - let ptr = NonNull::new_unchecked((self as *mut Self).cast::()); - if Self::PADDED { + let ptr = NonNull::new_unchecked((self as *mut Self).cast::()); let mut padder = Padder::new(ptr); Self::pad(&mut padder); padder.remaining(); @@ -543,8 +549,8 @@ pub unsafe trait ZeroCopy: Sized { /// # Errors /// /// This will ensure that `bytes` is aligned, appropriately sized, and valid - /// to inhabit `&Self`. Anything else will cause an [`Error`] detailing why - /// the conversion failed. + /// to inhabit `&mut Self`. Anything else will cause an [`Error`] detailing + /// why the conversion failed. /// /// # Examples /// @@ -613,13 +619,9 @@ pub unsafe trait ZeroCopy: Sized { /// constant should be advised. /// /// [`CAN_SWAP_BYTES`]: Self::CAN_SWAP_BYTES - fn swap_bytes(self) -> Self; - - /// Transpose a type from one byte order `F` to another `T`. - #[inline] - fn transpose_bytes(self) -> Self { - self.swap_bytes::().swap_bytes::() - } + fn swap_bytes(self) -> Self + where + E: ByteOrder; } unsafe impl UnsizedZeroCopy for str { @@ -640,11 +642,15 @@ unsafe impl UnsizedZeroCopy for str { unsafe fn pad(&self, _: &mut Padder<'_, Self>) {} #[inline] - unsafe fn validate_unsized( + unsafe fn validate_unsized( data: NonNull, len: usize, - metadata: ::Packed, - ) -> Result { + metadata: Self::Stored, + ) -> Result + where + E: ByteOrder, + O: Size, + { let metadata = metadata.as_usize::(); if metadata > len { @@ -697,11 +703,15 @@ where } #[inline] - unsafe fn validate_unsized( + unsafe fn validate_unsized( data: NonNull, len: usize, - metadata: ::Packed, - ) -> Result { + metadata: Self::Stored, + ) -> Result + where + E: ByteOrder, + O: Size, + { let metadata = metadata.as_usize::(); let Some(size) = metadata.checked_mul(size_of::()) else { @@ -786,7 +796,10 @@ macro_rules! impl_number { } #[inline] - fn swap_bytes(self) -> Self { + fn swap_bytes(self) -> Self + where + E: ByteOrder, + { $from_be(self) } } @@ -833,7 +846,10 @@ macro_rules! impl_float { Ok(()) } - fn swap_bytes(self) -> Self { + fn swap_bytes(self) -> Self + where + E: ByteOrder, + { $from_fn(self) } } @@ -879,7 +895,10 @@ unsafe impl ZeroCopy for char { } #[inline] - fn swap_bytes(self) -> Self { + fn swap_bytes(self) -> Self + where + E: ByteOrder, + { self } } @@ -915,7 +934,10 @@ unsafe impl ZeroCopy for bool { } #[inline] - fn swap_bytes(self) -> Self { + fn swap_bytes(self) -> Self + where + E: ByteOrder, + { self } } @@ -984,7 +1006,10 @@ macro_rules! impl_nonzero_number { } #[inline] - fn swap_bytes(self) -> Self { + fn swap_bytes(self) -> Self + where + E: ByteOrder, + { // SAFETY: a value inhabiting zero is byte-order independent. unsafe { ::core::num::$ty::new_unchecked(<$inner as ZeroCopy>::swap_bytes::( @@ -1048,7 +1073,10 @@ macro_rules! impl_nonzero_number { } #[inline] - fn swap_bytes(self) -> Self { + fn swap_bytes(self) -> Self + where + E: ByteOrder, + { // SAFETY: All bit-patterns are habitable, zero we can rely on // byte-order conversion from the inner type. unsafe { @@ -1128,7 +1156,10 @@ macro_rules! impl_zst { } #[inline] - fn swap_bytes(self) -> Self { + fn swap_bytes(self) -> Self + where + E: ByteOrder, + { self } } @@ -1201,7 +1232,10 @@ where } #[inline] - fn swap_bytes(self) -> Self { + fn swap_bytes(self) -> Self + where + E: ByteOrder, + { let mut iter = self.into_iter(); array::from_fn(move |_| T::swap_bytes::(iter.next().unwrap())) } diff --git a/crates/musli-zerocopy/src/trie/factory.rs b/crates/musli-zerocopy/src/trie/factory.rs index 335702b75..d27a2652f 100644 --- a/crates/musli-zerocopy/src/trie/factory.rs +++ b/crates/musli-zerocopy/src/trie/factory.rs @@ -47,7 +47,7 @@ use super::{prefix, DefaultFlavor, Flavor, LinksRef, NodeRef, TrieRef}; /// # Ok::<_, musli_zerocopy::Error>(()) /// ``` #[cfg(feature = "alloc")] -pub fn store( +pub fn store( buf: &mut OwnedBuf, it: I, ) -> Result>, Error> @@ -55,6 +55,8 @@ where I: IntoIterator, T)>, T: ZeroCopy, S: ?Sized + Pointee + Coerce<[u8]>, + E: ByteOrder, + O: Size, { // First step is to construct the trie in-memory. let mut trie = Builder::with_flavor(); @@ -70,7 +72,10 @@ where /// /// This can be used over [`store()`] to provide more control. #[cfg(feature = "alloc")] -pub struct Builder { +pub struct Builder +where + F: Flavor, +{ links: Links, _marker: PhantomData, } @@ -93,7 +98,10 @@ impl Default for Builder { } #[cfg(feature = "alloc")] -impl Builder { +impl Builder +where + F: Flavor, +{ /// Construct a new empty trie builder with a custom [`Flavor`]. pub const fn with_flavor() -> Self { Self { @@ -133,7 +141,7 @@ impl Builder { /// assert_eq!(trie.get(&buf, "working")?, Some(&[4, 5][..])); /// # Ok::<_, musli_zerocopy::Error>(()) /// ``` - pub fn insert( + pub fn insert( &mut self, buf: &Buf, string: Ref, @@ -141,6 +149,8 @@ impl Builder { ) -> Result<(), Error> where S: ?Sized + Pointee + Coerce<[u8]>, + E: ByteOrder, + O: Size, { let mut string = string.coerce::<[u8]>(); let mut current = buf.load(string)?; @@ -240,12 +250,11 @@ impl Builder { /// assert_eq!(trie.get(&buf, "working")?, Some(&[4][..])); /// # Ok::<_, musli_zerocopy::Error>(()) /// ``` - pub fn build( - self, - buf: &mut OwnedBuf, - ) -> Result, Error> + pub fn build(self, buf: &mut OwnedBuf) -> Result, Error> where T: ZeroCopy, + E: ByteOrder, + O: Size, { Ok(TrieRef { links: self.links.into_ref(buf)?, @@ -275,12 +284,12 @@ impl Links { } } - fn into_ref( - self, - buf: &mut OwnedBuf, - ) -> Result, Error> + fn into_ref(self, buf: &mut OwnedBuf) -> Result, Error> where T: ZeroCopy, + E: ByteOrder, + O: Size, + F: Flavor, { let values = F::Values::try_from_ref(buf.store_slice(&self.values))?; @@ -310,12 +319,12 @@ impl Node { } } - fn into_ref( - self, - buf: &mut OwnedBuf, - ) -> Result, Error> + fn into_ref(self, buf: &mut OwnedBuf) -> Result, Error> where T: ZeroCopy, + E: ByteOrder, + O: Size, + F: Flavor, { Ok(NodeRef { string: F::String::try_from_ref(self.string)?, diff --git a/crates/musli-zerocopy/src/trie/mod.rs b/crates/musli-zerocopy/src/trie/mod.rs index 1c9ab2289..2039afdb4 100644 --- a/crates/musli-zerocopy/src/trie/mod.rs +++ b/crates/musli-zerocopy/src/trie/mod.rs @@ -41,10 +41,16 @@ type StackEntry<'buf, T, F> = (LinksRef, usize, &'buf [u8]); /// impl trie::Flavor for PackedTrie { /// // The maximum length of a string slice stored in the trie is `u8::MAX`. /// type String = Packed<[u8], u32, u8>; +/// /// // The max number of values stored in a single node is `u16::MAX`. -/// type Values = Packed<[T], u32, u16> where T: ZeroCopy; +/// type Values = Packed<[T], u32, u16> +/// where +/// T: ZeroCopy; +/// /// // The maximum number of children for a single node is `u8::MAX`. -/// type Children = Packed<[T], u32, u8> where T: ZeroCopy; +/// type Children = Packed<[T], u32, u8> +/// where +/// T: ZeroCopy; /// } /// /// fn populate(buf: &mut OwnedBuf, mut trie: trie::Builder) -> Result, Error> @@ -94,9 +100,16 @@ pub trait Flavor { /// Marker type indicating the default trie [`Flavor`] to use for a given /// [`ByteOrder`] and [`Size`]. -pub struct DefaultFlavor(PhantomData<(E, O)>); +pub struct DefaultFlavor(PhantomData<(E, O)>) +where + E: ByteOrder, + O: Size; -impl Flavor for DefaultFlavor { +impl Flavor for DefaultFlavor +where + E: ByteOrder, + O: Size, +{ type String = Ref<[u8], E, O>; type Values = Ref<[T], E, O> where T: ZeroCopy; type Children = Ref<[T], E, O> where T: ZeroCopy; @@ -106,16 +119,18 @@ impl Flavor for DefaultFlavor { #[derive(ZeroCopy)] #[zero_copy(crate)] #[repr(C)] -pub struct TrieRef +pub struct TrieRef where T: ZeroCopy, + F: Flavor, { links: LinksRef, } -impl TrieRef +impl TrieRef where T: ZeroCopy, + F: Flavor, { /// Debug print the current trie. /// @@ -757,17 +772,19 @@ where /// /// See [`TrieRef::values_in()`]. #[cfg(feature = "alloc")] -pub struct ValuesIn<'a, 'buf, T, F: Flavor> +pub struct ValuesIn<'a, 'buf, T, F> where T: ZeroCopy, + F: Flavor, { iter: Walk<'a, 'buf, T, F, Vec>>, } #[cfg(feature = "alloc")] -impl<'a, 'buf, T, F: Flavor> Iterator for ValuesIn<'a, 'buf, T, F> +impl<'a, 'buf, T, F> Iterator for ValuesIn<'a, 'buf, T, F> where T: ZeroCopy, + F: Flavor, { type Item = Result<&'buf T, Error>; @@ -786,16 +803,18 @@ where /// max iteration depth of `N` /// /// See [`TrieRef::values_in_fixed()`]. -pub struct ValuesInFixed<'a, 'buf, const N: usize, T, F: Flavor> +pub struct ValuesInFixed<'a, 'buf, const N: usize, T, F> where T: ZeroCopy, + F: Flavor, { iter: Walk<'a, 'buf, T, F, ArrayStack, N>>, } -impl<'a, 'buf, const N: usize, T, F: Flavor> Iterator for ValuesInFixed<'a, 'buf, N, T, F> +impl<'a, 'buf, const N: usize, T, F> Iterator for ValuesInFixed<'a, 'buf, N, T, F> where T: ZeroCopy, + F: Flavor, { type Item = Result<&'buf T, Error>; @@ -814,17 +833,19 @@ where /// /// See [`TrieRef::values()`]. #[cfg(feature = "alloc")] -pub struct Values<'buf, T, F: Flavor> +pub struct Values<'buf, T, F> where T: ZeroCopy, + F: Flavor, { iter: Walk<'static, 'buf, T, F, Vec>>, } #[cfg(feature = "alloc")] -impl<'buf, T, F: Flavor> Iterator for Values<'buf, T, F> +impl<'buf, T, F> Iterator for Values<'buf, T, F> where T: ZeroCopy, + F: Flavor, { type Item = Result<&'buf T, Error>; @@ -843,16 +864,18 @@ where /// depth of `N` /// /// See [`TrieRef::values_fixed()`]. -pub struct ValuesFixed<'buf, const N: usize, T, F: Flavor> +pub struct ValuesFixed<'buf, const N: usize, T, F> where T: ZeroCopy, + F: Flavor, { iter: Walk<'static, 'buf, T, F, ArrayStack, N>>, } -impl<'buf, const N: usize, T, F: Flavor> Iterator for ValuesFixed<'buf, N, T, F> +impl<'buf, const N: usize, T, F> Iterator for ValuesFixed<'buf, N, T, F> where T: ZeroCopy, + F: Flavor, { type Item = Result<&'buf T, Error>; @@ -871,17 +894,19 @@ where /// /// See [`TrieRef::iter()`]. #[cfg(feature = "alloc")] -pub struct Iter<'buf, T, F: Flavor> +pub struct Iter<'buf, T, F> where T: ZeroCopy, + F: Flavor, { iter: Walk<'static, 'buf, T, F, Vec>>, } #[cfg(feature = "alloc")] -impl<'buf, T, F: Flavor> Iterator for Iter<'buf, T, F> +impl<'buf, T, F> Iterator for Iter<'buf, T, F> where T: ZeroCopy, + F: Flavor, { type Item = Result<(&'buf [u8], &'buf T), Error>; @@ -895,16 +920,18 @@ where /// depth of `N` /// /// See [`TrieRef::iter_fixed()`]. -pub struct IterFixed<'buf, const N: usize, T, F: Flavor> +pub struct IterFixed<'buf, const N: usize, T, F> where T: ZeroCopy, + F: Flavor, { iter: Walk<'static, 'buf, T, F, ArrayStack, N>>, } -impl<'buf, const N: usize, T, F: Flavor> Iterator for IterFixed<'buf, N, T, F> +impl<'buf, const N: usize, T, F> Iterator for IterFixed<'buf, N, T, F> where T: ZeroCopy, + F: Flavor, { type Item = Result<(&'buf [u8], &'buf T), Error>; @@ -918,17 +945,19 @@ where /// /// See [`TrieRef::iter_in()`]. #[cfg(feature = "alloc")] -pub struct IterIn<'a, 'buf, T, F: Flavor> +pub struct IterIn<'a, 'buf, T, F> where T: ZeroCopy, + F: Flavor, { iter: Walk<'a, 'buf, T, F, Vec>>, } #[cfg(feature = "alloc")] -impl<'a, 'buf, T, F: Flavor> Iterator for IterIn<'a, 'buf, T, F> +impl<'a, 'buf, T, F> Iterator for IterIn<'a, 'buf, T, F> where T: ZeroCopy, + F: Flavor, { type Item = Result<(&'buf [u8], &'buf T), Error>; @@ -942,16 +971,18 @@ where /// fixed max iteration depth of `N` /// /// See [`TrieRef::iter_in_fixed()`]. -pub struct IterInFixed<'a, 'buf, const N: usize, T, F: Flavor> +pub struct IterInFixed<'a, 'buf, const N: usize, T, F> where T: ZeroCopy, + F: Flavor, { iter: Walk<'a, 'buf, T, F, ArrayStack, N>>, } -impl<'a, 'buf, const N: usize, T, F: Flavor> Iterator for IterInFixed<'a, 'buf, N, T, F> +impl<'a, 'buf, const N: usize, T, F> Iterator for IterInFixed<'a, 'buf, N, T, F> where T: ZeroCopy, + F: Flavor, { type Item = Result<(&'buf [u8], &'buf T), Error>; @@ -965,18 +996,20 @@ where /// /// See [`TrieRef::debug()`]. #[cfg(feature = "alloc")] -pub struct Debug<'a, 'buf, T, F: Flavor> +pub struct Debug<'a, 'buf, T, F> where T: ZeroCopy, + F: Flavor, { trie: &'a TrieRef, buf: &'buf Buf, } #[cfg(feature = "alloc")] -impl<'a, 'buf, T, F: Flavor> fmt::Debug for Debug<'a, 'buf, T, F> +impl<'a, 'buf, T, F> fmt::Debug for Debug<'a, 'buf, T, F> where T: fmt::Debug + ZeroCopy, + F: Flavor, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut f = f.debug_map(); @@ -993,17 +1026,19 @@ where /// Debug printing of a trie with a fixed iteration depth of `N`. /// /// See [`TrieRef::debug_fixed()`]. -pub struct DebugFixed<'a, 'buf, const N: usize, T, F: Flavor> +pub struct DebugFixed<'a, 'buf, const N: usize, T, F> where T: ZeroCopy, + F: Flavor, { trie: &'a TrieRef, buf: &'buf Buf, } -impl<'a, 'buf, const N: usize, T, F: Flavor> fmt::Debug for DebugFixed<'a, 'buf, N, T, F> +impl<'a, 'buf, const N: usize, T, F> fmt::Debug for DebugFixed<'a, 'buf, N, T, F> where T: fmt::Debug + ZeroCopy, + F: Flavor, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut f = f.debug_map(); @@ -1017,9 +1052,10 @@ where } } -impl Clone for TrieRef +impl Clone for TrieRef where T: ZeroCopy, + F: Flavor, F::Values: Clone, F::Children>: Clone, { @@ -1029,9 +1065,10 @@ where } } -impl Copy for TrieRef +impl Copy for TrieRef where T: ZeroCopy, + F: Flavor, F::Values: Copy, F::Children>: Copy, { @@ -1040,17 +1077,19 @@ where #[derive(ZeroCopy)] #[zero_copy(crate)] #[repr(C)] -struct LinksRef +struct LinksRef where T: ZeroCopy, + F: Flavor, { values: F::Values, children: F::Children>, } -impl Clone for LinksRef +impl Clone for LinksRef where T: ZeroCopy, + F: Flavor, F::Values: Copy, F::Children>: Copy, { @@ -1060,9 +1099,10 @@ where } } -impl Copy for LinksRef +impl Copy for LinksRef where T: ZeroCopy, + F: Flavor, F::Values: Copy, F::Children>: Copy, { @@ -1071,9 +1111,10 @@ where #[derive(ZeroCopy)] #[zero_copy(crate)] #[repr(C)] -struct NodeRef +struct NodeRef where T: ZeroCopy, + F: Flavor, { string: F::String, links: LinksRef, diff --git a/crates/musli-zerocopy/src/trie/walk.rs b/crates/musli-zerocopy/src/trie/walk.rs index 1f13b0023..2169bba60 100644 --- a/crates/musli-zerocopy/src/trie/walk.rs +++ b/crates/musli-zerocopy/src/trie/walk.rs @@ -8,9 +8,11 @@ use crate::{Buf, Error, Ref, ZeroCopy}; use super::{prefix, Flavor, LinksRef, StackEntry}; -pub(super) struct Walk<'a, 'buf, T, F: Flavor, S: Stack>> +pub(super) struct Walk<'a, 'buf, T, F, S> where T: ZeroCopy, + F: Flavor, + S: Stack>, { // Buffer being walked. buf: &'buf Buf, @@ -21,9 +23,10 @@ where stack: S, } -impl<'a, 'buf, T, F: Flavor, S> Walk<'a, 'buf, T, F, S> +impl<'a, 'buf, T, F, S> Walk<'a, 'buf, T, F, S> where T: ZeroCopy, + F: Flavor, S: Stack>, { pub(super) fn find(buf: &'buf Buf, links: LinksRef, prefix: &'a [u8]) -> Self { @@ -196,9 +199,10 @@ where Ref::try_with_metadata(real_start, real_end - real_start) } -enum WalkState<'a, 'buf, T, F: Flavor> +enum WalkState<'a, 'buf, T, F> where T: ZeroCopy, + F: Flavor, { // Initial state where we need to lookup the specified prefix in the trie. Find(LinksRef, &'a [u8]), diff --git a/crates/musli/src/descriptive/en.rs b/crates/musli/src/descriptive/en.rs index bb853f821..bdb60a954 100644 --- a/crates/musli/src/descriptive/en.rs +++ b/crates/musli/src/descriptive/en.rs @@ -127,8 +127,7 @@ where #[inline] fn encode_bytes_vectored(mut self, len: usize, vectors: I) -> Result where - I: IntoIterator, - I::Item: AsRef<[u8]>, + I: IntoIterator>, { encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), Kind::Bytes, len)?; diff --git a/crates/musli/src/json/en/mod.rs b/crates/musli/src/json/en/mod.rs index 1356caed1..abcb5e552 100644 --- a/crates/musli/src/json/en/mod.rs +++ b/crates/musli/src/json/en/mod.rs @@ -228,8 +228,7 @@ where #[inline] fn encode_bytes_vectored(self, _: usize, vectors: I) -> Result where - I: IntoIterator, - I::Item: AsRef<[u8]>, + I: IntoIterator>, { let mut seq = JsonArrayEncoder::new(self.cx, self.writer)?; diff --git a/crates/musli/src/storage/en.rs b/crates/musli/src/storage/en.rs index 6b81acea9..e96ec7faa 100644 --- a/crates/musli/src/storage/en.rs +++ b/crates/musli/src/storage/en.rs @@ -92,8 +92,7 @@ where #[inline] fn encode_bytes_vectored(mut self, len: usize, vectors: I) -> Result where - I: IntoIterator, - I::Item: AsRef<[u8]>, + I: IntoIterator>, { crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; diff --git a/crates/musli/src/value/en.rs b/crates/musli/src/value/en.rs index 9c15bc8e5..dbf94e8d1 100644 --- a/crates/musli/src/value/en.rs +++ b/crates/musli/src/value/en.rs @@ -240,8 +240,7 @@ where #[inline] fn encode_bytes_vectored(self, len: usize, vectors: I) -> Result where - I: IntoIterator, - I::Item: AsRef<[u8]>, + I: IntoIterator>, { let mut bytes = Vec::with_capacity(len); diff --git a/crates/musli/src/wire/en.rs b/crates/musli/src/wire/en.rs index d8cd9683c..756e04d25 100644 --- a/crates/musli/src/wire/en.rs +++ b/crates/musli/src/wire/en.rs @@ -153,8 +153,7 @@ where #[inline] fn encode_bytes_vectored(mut self, len: usize, vectors: I) -> Result where - I: IntoIterator, - I::Item: AsRef<[u8]>, + I: IntoIterator>, { encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?;