diff --git a/components/datetime/src/fields/ule.rs b/components/datetime/src/fields/ule.rs index 064e432ac1f..41185894852 100644 --- a/components/datetime/src/fields/ule.rs +++ b/components/datetime/src/fields/ule.rs @@ -47,12 +47,12 @@ impl AsULE for fields::Field { type ULE = FieldULE; #[inline] - fn as_unaligned(&self) -> Self::ULE { + fn as_unaligned(self) -> Self::ULE { FieldULE([self.symbol.idx(), self.length.idx()]) } #[inline] - fn from_unaligned(unaligned: &Self::ULE) -> Self { + fn from_unaligned(unaligned: Self::ULE) -> Self { let value = unaligned.0; let symbol = fields::FieldSymbol::from_idx(value[0]).unwrap(); let length = fields::FieldLength::from_idx(value[1]).unwrap(); @@ -119,7 +119,7 @@ mod test { for (ref_field, ref_bytes) in samples { let ule = ref_field.as_unaligned(); assert_eq!(ULE::as_byte_slice(&[ule]), *ref_bytes); - let field = Field::from_unaligned(&ule); + let field = Field::from_unaligned(ule); assert_eq!(field, *ref_field); } } diff --git a/components/datetime/src/pattern/item/ule.rs b/components/datetime/src/pattern/item/ule.rs index 25ecfdc022f..3c329e4aeae 100644 --- a/components/datetime/src/pattern/item/ule.rs +++ b/components/datetime/src/pattern/item/ule.rs @@ -107,13 +107,13 @@ impl AsULE for PatternItem { type ULE = PatternItemULE; #[inline] - fn as_unaligned(&self) -> Self::ULE { + fn as_unaligned(self) -> Self::ULE { match self { Self::Field(field) => { PatternItemULE([0b1000_0000, field.symbol.idx(), field.length.idx()]) } Self::Literal(ch) => { - let u = *ch as u32; + let u = ch as u32; let bytes = u.to_be_bytes(); PatternItemULE([bytes[1], bytes[2], bytes[3]]) } @@ -121,7 +121,7 @@ impl AsULE for PatternItem { } #[inline] - fn from_unaligned(unaligned: &Self::ULE) -> Self { + fn from_unaligned(unaligned: Self::ULE) -> Self { let value = unaligned.0; match PatternItemULE::determine_field_from_u8(value[0]) { false => { @@ -238,11 +238,11 @@ impl AsULE for GenericPatternItem { type ULE = GenericPatternItemULE; #[inline] - fn as_unaligned(&self) -> Self::ULE { + fn as_unaligned(self) -> Self::ULE { match self { - Self::Placeholder(idx) => GenericPatternItemULE([0b1000_0000, 0x00, *idx]), + Self::Placeholder(idx) => GenericPatternItemULE([0b1000_0000, 0x00, idx]), Self::Literal(ch) => { - let u = *ch as u32; + let u = ch as u32; let bytes = u.to_be_bytes(); GenericPatternItemULE([bytes[1], bytes[2], bytes[3]]) } @@ -250,7 +250,7 @@ impl AsULE for GenericPatternItem { } #[inline] - fn from_unaligned(unaligned: &Self::ULE) -> Self { + fn from_unaligned(unaligned: Self::ULE) -> Self { let value = unaligned.0; match GenericPatternItemULE::determine_field_from_u8(value[0]) { false => { @@ -305,7 +305,7 @@ mod test { for (ref_pattern, ref_bytes) in samples { let ule = ref_pattern.as_unaligned(); assert_eq!(ULE::as_byte_slice(&[ule]), *ref_bytes); - let pattern = PatternItem::from_unaligned(&ule); + let pattern = PatternItem::from_unaligned(ule); assert_eq!(pattern, *ref_pattern); } } @@ -361,7 +361,7 @@ mod test { for (ref_pattern, ref_bytes) in samples { let ule = ref_pattern.as_unaligned(); assert_eq!(ULE::as_byte_slice(&[ule]), *ref_bytes); - let pattern = GenericPatternItem::from_unaligned(&ule); + let pattern = GenericPatternItem::from_unaligned(ule); assert_eq!(pattern, *ref_pattern); } } diff --git a/components/properties/src/ule.rs b/components/properties/src/ule.rs index 73057d7b0e6..170dd41f6f8 100644 --- a/components/properties/src/ule.rs +++ b/components/properties/src/ule.rs @@ -16,13 +16,13 @@ impl AsULE for GeneralSubcategory { type ULE = GeneralSubcategoryULE; #[inline] - fn as_unaligned(&self) -> Self::ULE { - let u = *self as u8; + fn as_unaligned(self) -> Self::ULE { + let u = self as u8; GeneralSubcategoryULE(u) } #[inline] - fn from_unaligned(unaligned: &Self::ULE) -> Self { + fn from_unaligned(unaligned: Self::ULE) -> Self { // Safe because the contents of GeneralSubcategoryULE are required to be valid. unsafe { Self::from_unchecked(unaligned.0) } } @@ -50,12 +50,12 @@ impl AsULE for Script { type ULE = PlainOldULE<2>; #[inline] - fn as_unaligned(&self) -> Self::ULE { + fn as_unaligned(self) -> Self::ULE { PlainOldULE(self.0.to_le_bytes()) } #[inline] - fn from_unaligned(unaligned: &Self::ULE) -> Self { + fn from_unaligned(unaligned: Self::ULE) -> Self { Script(u16::from_le_bytes(unaligned.0)) } } diff --git a/utils/uniset/src/builder.rs b/utils/uniset/src/builder.rs index f58fa5cdc05..97b96e5de10 100644 --- a/utils/uniset/src/builder.rs +++ b/utils/uniset/src/builder.rs @@ -172,8 +172,8 @@ impl UnicodeSetBuilder { .chunks(2) .for_each(|pair| { self.add( - AsULE::from_unaligned(&pair[0]), - AsULE::from_unaligned(&pair[1]), + AsULE::from_unaligned(pair[0]), + AsULE::from_unaligned(pair[1]), ) }); } @@ -246,8 +246,8 @@ impl UnicodeSetBuilder { .chunks(2) .for_each(|pair| { self.remove( - AsULE::from_unaligned(&pair[0]), - AsULE::from_unaligned(&pair[1]), + AsULE::from_unaligned(pair[0]), + AsULE::from_unaligned(pair[1]), ) }); } @@ -311,8 +311,8 @@ impl UnicodeSetBuilder { pub fn retain_set(&mut self, set: &UnicodeSet) { let mut prev = 0; for pair in set.as_inversion_list().as_slice().chunks(2) { - let range_start = AsULE::from_unaligned(&pair[0]); - let range_limit = AsULE::from_unaligned(&pair[1]); + let range_start = AsULE::from_unaligned(pair[0]); + let range_limit = AsULE::from_unaligned(pair[1]); self.remove(prev, range_start); prev = range_limit; } @@ -449,7 +449,8 @@ impl UnicodeSetBuilder { .as_inversion_list() .as_slice() .iter() - .map(|cp| ::from_unaligned(cp)); + .copied() + .map(::from_unaligned); self.complement_list(inv_list_iter_owned); } diff --git a/utils/uniset/src/uniset.rs b/utils/uniset/src/uniset.rs index da39a4a0b97..35f56c72f90 100644 --- a/utils/uniset/src/uniset.rs +++ b/utils/uniset/src/uniset.rs @@ -101,8 +101,8 @@ impl<'data> UnicodeSet<'data> { .as_slice() .chunks(2) .map(|end_points| { - ::from_unaligned(&end_points[1]) - - ::from_unaligned(&end_points[0]) + ::from_unaligned(end_points[1]) + - ::from_unaligned(end_points[0]) }) .sum::() as usize; Ok(Self { inv_list, size }) @@ -264,7 +264,7 @@ impl<'data> UnicodeSet<'data> { self.inv_list .as_slice() .chunks(2) - .flat_map(|pair| (AsULE::from_unaligned(&pair[0])..AsULE::from_unaligned(&pair[1]))) + .flat_map(|pair| (AsULE::from_unaligned(pair[0])..AsULE::from_unaligned(pair[1]))) .filter_map(char::from_u32) } @@ -288,8 +288,8 @@ impl<'data> UnicodeSet<'data> { /// ``` pub fn iter_ranges(&self) -> impl ExactSizeIterator> + '_ { self.inv_list.as_slice().chunks(2).map(|pair| { - let range_start: u32 = AsULE::from_unaligned(&pair[0]); - let range_limit: u32 = AsULE::from_unaligned(&pair[1]); + let range_start: u32 = AsULE::from_unaligned(pair[0]); + let range_limit: u32 = AsULE::from_unaligned(pair[1]); RangeInclusive::new(range_start, range_limit - 1) }) } diff --git a/utils/uniset/src/utils.rs b/utils/uniset/src/utils.rs index 00b795c54cc..2f09c12514d 100644 --- a/utils/uniset/src/utils.rs +++ b/utils/uniset/src/utils.rs @@ -16,11 +16,10 @@ pub fn is_valid_zv(inv_list_zv: &ZeroVec<'_, u32>) -> bool { slice.is_empty() || (slice.len() % 2 == 0 && slice.windows(2).all(|chunk| { - ::from_unaligned(&chunk[0]) - < ::from_unaligned(&chunk[1]) + ::from_unaligned(chunk[0]) < ::from_unaligned(chunk[1]) }) && slice.last().map_or(false, |e| { - ::from_unaligned(e) <= ((char::MAX as u32) + 1) + ::from_unaligned(*e) <= ((char::MAX as u32) + 1) })) } diff --git a/utils/zerovec/src/map/kv.rs b/utils/zerovec/src/map/kv.rs index 1b642d30963..f214641bda3 100644 --- a/utils/zerovec/src/map/kv.rs +++ b/utils/zerovec/src/map/kv.rs @@ -72,12 +72,12 @@ macro_rules! impl_sized_kv { #[inline] fn cmp_get(&self, g: &Self::GetType) -> Ordering { - self.cmp(&$ty::from_unaligned(g)) + self.cmp(&$ty::from_unaligned(*g)) } #[inline] fn with_ser(g: &Self::GetType, f: impl FnOnce(&Self) -> R) -> R { - f(&Self::from_unaligned(g)) + f(&Self::from_unaligned(*g)) } #[inline] diff --git a/utils/zerovec/src/map/vecs.rs b/utils/zerovec/src/map/vecs.rs index e7df76536ac..0706ac0ae5b 100644 --- a/utils/zerovec/src/map/vecs.rs +++ b/utils/zerovec/src/map/vecs.rs @@ -69,11 +69,11 @@ where self.to_mut().insert(index, value.as_unaligned()) } fn remove(&mut self, index: usize) -> T { - T::from_unaligned(&self.to_mut().remove(index)) + T::from_unaligned(self.to_mut().remove(index)) } fn replace(&mut self, index: usize, value: &T) -> T { let vec = self.to_mut(); - T::from_unaligned(&mem::replace(&mut vec[index], value.as_unaligned())) + T::from_unaligned(mem::replace(&mut vec[index], value.as_unaligned())) } fn push(&mut self, value: &T) { self.to_mut().push(value.as_unaligned()) @@ -96,7 +96,7 @@ where fn is_ascending(&self) -> bool { self.as_slice() .windows(2) - .all(|w| T::from_unaligned(&w[1]).cmp(&T::from_unaligned(&w[0])) == Ordering::Greater) + .all(|w| T::from_unaligned(w[1]).cmp(&T::from_unaligned(w[0])) == Ordering::Greater) } } diff --git a/utils/zerovec/src/ule/chars.rs b/utils/zerovec/src/ule/chars.rs index 273dd094e79..6401a9b57bc 100644 --- a/utils/zerovec/src/ule/chars.rs +++ b/utils/zerovec/src/ule/chars.rs @@ -23,7 +23,7 @@ use core::convert::TryFrom; /// let c1 = '𑄃'; /// let ule = c1.as_unaligned(); /// assert_eq!(CharULE::as_byte_slice(&[ule]), &[0x03, 0x11, 0x01, 0x00]); -/// let c2 = char::from_unaligned(&ule); +/// let c2 = char::from_unaligned(ule); /// assert_eq!(c1, c2); /// ``` /// @@ -66,13 +66,13 @@ impl AsULE for char { type ULE = CharULE; #[inline] - fn as_unaligned(&self) -> Self::ULE { - let u = u32::from(*self); + fn as_unaligned(self) -> Self::ULE { + let u = u32::from(self); CharULE(u.to_le_bytes()) } #[inline] - fn from_unaligned(unaligned: &Self::ULE) -> Self { + fn from_unaligned(unaligned: Self::ULE) -> Self { let u = u32::from_le_bytes(unaligned.0); // Safe because the bytes of CharULE are defined to represent a valid Unicode code point. // TODO: Use char::from_u32_unchecked() when stabilized @@ -92,13 +92,17 @@ mod test { fn test_parse() { // 1-byte, 2-byte, 3-byte, and 4-byte character in UTF-8 (not as relevant in UTF-32) let chars = ['w', 'ω', '文', '𑄃']; - let char_ules: Vec = chars.iter().map(char::as_unaligned).collect(); + let char_ules: Vec = chars.iter().copied().map(char::as_unaligned).collect(); let char_bytes: &[u8] = CharULE::as_byte_slice(&char_ules); // Check parsing let parsed_ules: &[CharULE] = CharULE::parse_byte_slice(char_bytes).unwrap(); assert_eq!(char_ules, parsed_ules); - let parsed_chars: Vec = parsed_ules.iter().map(char::from_unaligned).collect(); + let parsed_chars: Vec = parsed_ules + .iter() + .copied() + .map(char::from_unaligned) + .collect(); assert_eq!(&chars, parsed_chars.as_slice()); // Check EqULE @@ -110,7 +114,11 @@ mod test { // Compare to u32 let u32s: Vec = chars.iter().copied().map(u32::from).collect(); - let u32_ules: Vec> = u32s.iter().map(::as_unaligned).collect(); + let u32_ules: Vec> = u32s + .iter() + .copied() + .map(::as_unaligned) + .collect(); let u32_bytes: &[u8] = PlainOldULE::<4>::as_byte_slice(&u32_ules); assert_eq!(char_bytes, u32_bytes); @@ -125,14 +133,22 @@ mod test { fn test_failures() { // 119 and 120 are valid, but not 0xD800 (high surrogate) let u32s = [119, 0xD800, 120]; - let u32_ules: Vec> = u32s.iter().map(::as_unaligned).collect(); + let u32_ules: Vec> = u32s + .iter() + .copied() + .map(::as_unaligned) + .collect(); let u32_bytes: &[u8] = PlainOldULE::<4>::as_byte_slice(&u32_ules); let parsed_ules_result = CharULE::parse_byte_slice(u32_bytes); assert!(matches!(parsed_ules_result, Err(_))); // 0x20FFFF is out of range for a char let u32s = [0x20FFFF]; - let u32_ules: Vec> = u32s.iter().map(::as_unaligned).collect(); + let u32_ules: Vec> = u32s + .iter() + .copied() + .map(::as_unaligned) + .collect(); let u32_bytes: &[u8] = PlainOldULE::<4>::as_byte_slice(&u32_ules); let parsed_ules_result = CharULE::parse_byte_slice(u32_bytes); assert!(matches!(parsed_ules_result, Err(_))); diff --git a/utils/zerovec/src/ule/custom/mod.rs b/utils/zerovec/src/ule/custom/mod.rs index ffcb95f7fa5..93d845b56ce 100644 --- a/utils/zerovec/src/ule/custom/mod.rs +++ b/utils/zerovec/src/ule/custom/mod.rs @@ -81,12 +81,12 @@ //! //! let vzv = VarZeroVec::from(&*foos); //! -//! assert_eq!(char::from_unaligned(&vzv.get(0).unwrap().field1), 'u'); -//! assert_eq!(u32::from_unaligned(&vzv.get(0).unwrap().field2), 983); +//! assert_eq!(char::from_unaligned(vzv.get(0).unwrap().field1), 'u'); +//! assert_eq!(u32::from_unaligned(vzv.get(0).unwrap().field2), 983); //! assert_eq!(&vzv.get(0).unwrap().field3, ZeroVec::clone_from_slice(&[1212,2309,500,7000]).as_slice()); //! -//! assert_eq!(char::from_unaligned(&vzv.get(1).unwrap().field1), 'l'); -//! assert_eq!(u32::from_unaligned(&vzv.get(1).unwrap().field2), 1010); +//! assert_eq!(char::from_unaligned(vzv.get(1).unwrap().field1), 'l'); +//! assert_eq!(u32::from_unaligned(vzv.get(1).unwrap().field2), 1010); //! assert_eq!(&vzv.get(1).unwrap().field3, ZeroVec::clone_from_slice(&[1932, 0, 8888, 91237]).as_slice()); //! } //! ``` diff --git a/utils/zerovec/src/ule/mod.rs b/utils/zerovec/src/ule/mod.rs index bc3bb21e1d8..e0de24386c4 100644 --- a/utils/zerovec/src/ule/mod.rs +++ b/utils/zerovec/src/ule/mod.rs @@ -8,12 +8,14 @@ mod chars; pub mod custom; mod error; +mod pair; mod plain; mod string; mod vec; pub use chars::CharULE; pub use error::ULEError; +pub use pair::{PairULE, PairULEError}; pub use plain::PlainOldULE; use alloc::alloc::Layout; @@ -56,7 +58,7 @@ use core::{fmt, mem, slice}; pub unsafe trait ULE where Self: Sized, - Self: 'static, + Self: Copy + 'static, { /// The error that occurs if a byte array is not valid for this ULE. type Error: fmt::Display; @@ -136,7 +138,7 @@ where } /// A trait for any type that has a 1:1 mapping with an unaligned little-endian (ULE) type. -pub trait AsULE { +pub trait AsULE: Copy { /// The ULE type corresponding to `Self`. /// /// Types having infallible conversions from all bit values (Plain Old Data) can use @@ -150,7 +152,7 @@ pub trait AsULE { /// This function may involve byte order swapping (native-endian to little-endian). /// /// For best performance, mark your implementation of this function `#[inline]`. - fn as_unaligned(&self) -> Self::ULE; + fn as_unaligned(self) -> Self::ULE; /// Converts from `&Self::ULE` to `Self`. /// @@ -163,7 +165,7 @@ pub trait AsULE { /// This function is infallible because bit validation should have occurred when `Self::ULE` /// was first constructed. An implementation may therefore involve an `unsafe{}` block, like /// `from_bytes_unchecked()`. - fn from_unaligned(unaligned: &Self::ULE) -> Self; + fn from_unaligned(unaligned: Self::ULE) -> Self; } /// An [`EqULE`] type is one whose byte sequence equals the byte sequence of its ULE type on diff --git a/utils/zerovec/src/ule/pair.rs b/utils/zerovec/src/ule/pair.rs new file mode 100644 index 00000000000..4872c9f7185 --- /dev/null +++ b/utils/zerovec/src/ule/pair.rs @@ -0,0 +1,78 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +use super::*; +use core::fmt; +use core::mem; + +/// We do not have guarantees for the layouts of tuples, so we must define a custom +/// ULE type for pairs. This could potentially be generalized for larger tuples if necessary +#[repr(packed)] +pub struct PairULE(pub A, pub B); + +unsafe impl ULE for PairULE { + type Error = PairULEError; + + fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + let a_len = mem::size_of::(); + let b_len = mem::size_of::(); + if bytes.len() != a_len + b_len { + return Err(PairULEError::IncorrectLength(a_len + b_len, bytes.len())); + } + A::validate_byte_slice(&bytes[..a_len]).map_err(PairULEError::First)?; + B::validate_byte_slice(&bytes[a_len..]).map_err(PairULEError::Second)?; + Ok(()) + } +} + +impl AsULE for (A, B) { + type ULE = PairULE; + + #[inline] + fn as_unaligned(self) -> Self::ULE { + PairULE(self.0.as_unaligned(), self.1.as_unaligned()) + } + + #[inline] + fn from_unaligned(unaligned: Self::ULE) -> Self { + ( + A::from_unaligned(unaligned.0), + B::from_unaligned(unaligned.1), + ) + } +} + +#[derive(Clone, Debug)] +pub enum PairULEError { + First(E), + Second(F), + IncorrectLength(/* expected */ usize, /* found */ usize), +} + +impl fmt::Display for PairULEError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match *self { + PairULEError::First(ref e) => e.fmt(f), + PairULEError::Second(ref e) => e.fmt(f), + PairULEError::IncorrectLength(expected, found) => write!( + f, + "Incorrect length for PairULE: expected {} found {}", + expected, found + ), + } + } +} + +// We need manual impls since `#[derive()]` is disallowed on packed types +impl Clone for PairULE { + fn clone(&self) -> Self { + // copy to the stack to avoid hitting a future incompat error + // https://github.com/rust-lang/rust/issues/82523#issuecomment-947900712 + let zero = self.0; + let one = self.1; + PairULE(zero, one) + } +} + +impl Copy for PairULE {} diff --git a/utils/zerovec/src/ule/plain.rs b/utils/zerovec/src/ule/plain.rs index cabe59f44c1..b5e6e1d46e6 100644 --- a/utils/zerovec/src/ule/plain.rs +++ b/utils/zerovec/src/ule/plain.rs @@ -68,11 +68,11 @@ macro_rules! impl_byte_slice_type { impl AsULE for $type { type ULE = PlainOldULE<$size>; #[inline] - fn as_unaligned(&self) -> Self::ULE { + fn as_unaligned(self) -> Self::ULE { PlainOldULE(self.to_le_bytes()) } #[inline] - fn from_unaligned(unaligned: &Self::ULE) -> Self { + fn from_unaligned(unaligned: Self::ULE) -> Self { <$type>::from_le_bytes(unaligned.0) } } @@ -122,12 +122,12 @@ unsafe impl ULE for u8 { impl AsULE for u8 { type ULE = Self; #[inline] - fn as_unaligned(&self) -> Self::ULE { - *self + fn as_unaligned(self) -> Self::ULE { + self } #[inline] - fn from_unaligned(unaligned: &Self::ULE) -> Self { - *unaligned + fn from_unaligned(unaligned: Self::ULE) -> Self { + unaligned } } diff --git a/utils/zerovec/src/varzerovec/components.rs b/utils/zerovec/src/varzerovec/components.rs index 21b7ca128d3..f6a11254130 100644 --- a/utils/zerovec/src/varzerovec/components.rs +++ b/utils/zerovec/src/varzerovec/components.rs @@ -12,7 +12,7 @@ use core::marker::PhantomData; use core::{iter, mem}; fn usizeify(x: PlainOldULE<4>) -> usize { - u32::from_unaligned(&x) as usize + u32::from_unaligned(x) as usize } /// A logical representation of the backing `&[u8]` buffer. @@ -67,7 +67,8 @@ impl<'a, T: VarULE + ?Sized> SliceComponents<'a, T> { let len_ule = PlainOldULE::<4>::parse_byte_slice(len_bytes) .map_err(|_| VarZeroVecError::FormatError)?; - let len = u32::from_unaligned(len_ule.get(0).ok_or(VarZeroVecError::FormatError)?) as usize; + let len = + u32::from_unaligned(*len_ule.get(0).ok_or(VarZeroVecError::FormatError)?) as usize; let indices_bytes = slice .get(4..4 * len + 4) .ok_or(VarZeroVecError::FormatError)?; @@ -111,7 +112,7 @@ impl<'a, T: VarULE + ?Sized> SliceComponents<'a, T> { let len_bytes = slice.get_unchecked(0..4); let len_ule = PlainOldULE::<4>::from_byte_slice_unchecked(len_bytes); - let len = u32::from_unaligned(len_ule.get_unchecked(0)) as usize; + let len = u32::from_unaligned(*len_ule.get_unchecked(0)) as usize; let indices_bytes = slice.get_unchecked(4..4 * len + 4); let indices = PlainOldULE::<4>::from_byte_slice_unchecked(indices_bytes); let things = slice.get_unchecked(4 * len + 4..); @@ -239,6 +240,7 @@ impl<'a, T: VarULE + ?Sized> SliceComponents<'a, T> { let indices = self .indices .iter() + .copied() .map(u32::from_unaligned) .collect::>(); format!("SliceComponents {{ indices: {:?} }}", indices) diff --git a/utils/zerovec/src/varzerovec/owned.rs b/utils/zerovec/src/varzerovec/owned.rs index ec72f1db8e5..bc680b91393 100644 --- a/utils/zerovec/src/varzerovec/owned.rs +++ b/utils/zerovec/src/varzerovec/owned.rs @@ -110,7 +110,7 @@ impl VarZeroVecOwned { let out = if idx == len { self.entire_slice.len() - 4 - (4 * len) } else { - u32::from_unaligned(self.index_data(idx)) as usize + u32::from_unaligned(*self.index_data(idx)) as usize }; debug_assert!(out + 4 + len * 4 <= self.entire_slice.len()); out @@ -177,7 +177,7 @@ impl VarZeroVecOwned { let indices = PlainOldULE::<4>::from_byte_slice_unchecked_mut(&mut self.entire_slice[4..4 + 4 * len]); for idx in &mut indices[starting_index..] { - *idx = (u32::from_unaligned(idx).wrapping_add(amount as u32)).into(); + *idx = (u32::from_unaligned(*idx).wrapping_add(amount as u32)).into(); } } @@ -335,7 +335,7 @@ impl VarZeroVecOwned { } let len = unsafe { u32::from_unaligned( - &PlainOldULE::<4>::from_byte_slice_unchecked(&self.entire_slice[..4])[0], + PlainOldULE::<4>::from_byte_slice_unchecked(&self.entire_slice[..4])[0], ) }; if len == 0 { @@ -358,13 +358,13 @@ impl VarZeroVecOwned { PlainOldULE::<4>::from_byte_slice_unchecked(&self.entire_slice[4..4 + len as usize * 4]) }; for idx in indices { - if u32::from_unaligned(idx) > data_len { + if u32::from_unaligned(*idx) > data_len { // Indices must not point past the data segment. return false; } } for window in indices.windows(2) { - if u32::from_unaligned(&window[0]) > u32::from_unaligned(&window[1]) { + if u32::from_unaligned(window[0]) > u32::from_unaligned(window[1]) { // Indices must be in non-decreasing order. return false; } diff --git a/utils/zerovec/src/zerovec/mod.rs b/utils/zerovec/src/zerovec/mod.rs index 9ab0bc2a676..e9aaa3d8e7a 100644 --- a/utils/zerovec/src/zerovec/mod.rs +++ b/utils/zerovec/src/zerovec/mod.rs @@ -100,11 +100,11 @@ where } } -impl Eq for ZeroVec<'_, T> where T: AsULE + Copy + Eq + ?Sized {} +impl Eq for ZeroVec<'_, T> where T: AsULE + Eq + ?Sized {} impl<'a, 'b, T> PartialEq> for ZeroVec<'a, T> where - T: AsULE + Copy + PartialEq + ?Sized, + T: AsULE + PartialEq + ?Sized, { #[inline] fn eq(&self, other: &ZeroVec<'b, T>) -> bool { @@ -115,7 +115,7 @@ where impl PartialEq<&[T]> for ZeroVec<'_, T> where - T: AsULE + Copy + PartialEq + ?Sized, + T: AsULE + PartialEq + ?Sized, { #[inline] fn eq(&self, other: &&[T]) -> bool { @@ -253,7 +253,7 @@ where /// ``` #[inline] pub fn clone_from_slice(other: &[T]) -> Self { - Self::Owned(other.iter().map(T::as_unaligned).collect()) + Self::Owned(other.iter().copied().map(T::as_unaligned).collect()) } /// Creates a `Vec` from a `ZeroVec`. @@ -270,7 +270,11 @@ where /// ``` #[inline] pub fn to_vec(&self) -> Vec { - self.as_slice().iter().map(T::from_unaligned).collect() + self.as_slice() + .iter() + .copied() + .map(T::from_unaligned) + .collect() } } @@ -329,12 +333,10 @@ where impl ZeroVec<'_, T> where - T: AsULE + Copy + ?Sized, + T: AsULE, { /// Gets the element at the specified index. Returns None if out of range. /// - /// The element is returned by value, so `T` must implement `Copy`. - /// /// # Example /// /// ``` @@ -348,7 +350,7 @@ where /// ``` #[inline] pub fn get(&self, index: usize) -> Option { - self.as_slice().get(index).map(T::from_unaligned) + self.as_slice().get(index).copied().map(T::from_unaligned) } pub(crate) fn get_ule_ref(&self, index: usize) -> Option<&T::ULE> { @@ -357,8 +359,6 @@ where /// Gets the first element. Returns None if empty. /// - /// The element is returned by value, so `T` must implement `Copy`. - /// /// # Example /// /// ``` @@ -371,13 +371,11 @@ where /// ``` #[inline] pub fn first(&self) -> Option { - self.as_slice().first().map(T::from_unaligned) + self.as_slice().first().copied().map(T::from_unaligned) } /// Gets the last element. Returns None if empty. /// - /// The element is returned by value, so `T` must implement `Copy`. - /// /// # Example /// /// ``` @@ -390,13 +388,11 @@ where /// ``` #[inline] pub fn last(&self) -> Option { - self.as_slice().last().map(T::from_unaligned) + self.as_slice().last().copied().map(T::from_unaligned) } /// Gets an iterator over the elements. /// - /// The elements are returned by value, so `T` must implement `Copy`. - /// /// # Example /// /// ``` @@ -414,7 +410,7 @@ where /// ``` #[inline] pub fn iter(&self) -> impl Iterator + '_ { - self.as_slice().iter().map(T::from_unaligned) + self.as_slice().iter().copied().map(T::from_unaligned) } /// Mutates each element according to a given function, meant to be @@ -439,7 +435,7 @@ where #[inline] pub fn for_each_mut(&mut self, mut f: impl FnMut(&mut T)) { self.to_mut().iter_mut().for_each(|item| { - let mut aligned = T::from_unaligned(item); + let mut aligned = T::from_unaligned(*item); f(&mut aligned); *item = aligned.as_unaligned() }); @@ -471,7 +467,7 @@ where mut f: impl FnMut(&mut T) -> Result<(), E>, ) -> Result<(), E> { self.to_mut().iter_mut().try_for_each(|item| { - let mut aligned = T::from_unaligned(item); + let mut aligned = T::from_unaligned(*item); f(&mut aligned)?; *item = aligned.as_unaligned(); Ok(()) @@ -496,7 +492,7 @@ where match self { Self::Owned(vec) => ZeroVec::Owned(vec), Self::Borrowed(_) => { - let vec: Vec = self.iter().map(|ule| T::as_unaligned(&ule)).collect(); + let vec: Vec = self.iter().map(T::as_unaligned).collect(); ZeroVec::Owned(vec) } } @@ -522,7 +518,7 @@ where match self { ZeroVec::Owned(ref mut vec) => vec, ZeroVec::Borrowed(_) => { - let vec: Vec = self.iter().map(|ule| T::as_unaligned(&ule)).collect(); + let vec: Vec = self.iter().map(T::as_unaligned).collect(); let new_self = ZeroVec::Owned(vec); *self = new_self; // recursion is limited since we are guaranteed to hit the Owned branch @@ -555,7 +551,7 @@ where #[inline] pub fn binary_search(&self, x: &T) -> Result { self.as_slice() - .binary_search_by(|probe| T::from_unaligned(probe).cmp(x)) + .binary_search_by(|probe| T::from_unaligned(*probe).cmp(x)) } } diff --git a/utils/zerovec/src/zerovec/serde.rs b/utils/zerovec/src/zerovec/serde.rs index 83c81b9b111..50be52a66c8 100644 --- a/utils/zerovec/src/zerovec/serde.rs +++ b/utils/zerovec/src/zerovec/serde.rs @@ -49,7 +49,7 @@ where Vec::new() }; while let Some(value) = seq.next_element::()? { - vec.push(T::as_unaligned(&value)); + vec.push(T::as_unaligned(value)); } Ok(ZeroVec::Owned(vec)) } @@ -77,7 +77,7 @@ where /// This impl can be made available by enabling the optional `serde` feature of the `zerovec` crate impl Serialize for ZeroVec<'_, T> where - T: Serialize + AsULE + Copy, + T: Serialize + AsULE, { fn serialize(&self, serializer: S) -> Result where