diff --git a/src/murmur3.rs b/src/murmur3.rs index 0f927b8..8bbdbe4 100644 --- a/src/murmur3.rs +++ b/src/murmur3.rs @@ -1,4 +1,5 @@ -use core::{mem, slice}; +use core::slice; +use core::mem::MaybeUninit; use byteorder::{ByteOrder, LE}; @@ -17,7 +18,7 @@ struct State(u32); #[derive(Clone, Copy)] #[repr(align(4))] struct Buffer { - bytes: [u8; 4], + bytes: MaybeUninit<[u8; 4]>, } #[derive(Clone, Copy, PartialEq)] @@ -59,7 +60,7 @@ impl Hasher { // self.buf.bytes[start..start+len].copy_from(buf); for i in 0..len { unsafe { - *self.buf.bytes.get_unchecked_mut(start + i) = *buf.get_unchecked(i); + *self.buf.bytes.assume_init_mut().get_unchecked_mut(start + i) = *buf.get_unchecked(i); } } self.index = Index::from(start + len); @@ -70,7 +71,7 @@ impl Default for Hasher { #[allow(deprecated)] fn default() -> Self { Hasher { - buf: unsafe { mem::uninitialized() }, + buf: Buffer { bytes: MaybeUninit::uninit() }, index: Index::_0, processed: 0, state: State(0), @@ -84,20 +85,26 @@ impl crate::Hasher for Hasher { let mut state = match self.index { Index::_3 => { let mut block = 0; - block ^= u32::from(self.buf.bytes[2]) << 16; - block ^= u32::from(self.buf.bytes[1]) << 8; - block ^= u32::from(self.buf.bytes[0]); + unsafe { + block ^= u32::from(self.buf.bytes.assume_init_ref()[2]) << 16; + block ^= u32::from(self.buf.bytes.assume_init_ref()[1]) << 8; + block ^= u32::from(self.buf.bytes.assume_init_ref()[0]); + } self.state.0 ^ pre_mix(block) } Index::_2 => { let mut block = 0; - block ^= u32::from(self.buf.bytes[1]) << 8; - block ^= u32::from(self.buf.bytes[0]); + unsafe { + block ^= u32::from(self.buf.bytes.assume_init_ref()[1]) << 8; + block ^= u32::from(self.buf.bytes.assume_init_ref()[0]); + } self.state.0 ^ pre_mix(block) } Index::_1 => { let mut block = 0; - block ^= u32::from(self.buf.bytes[0]); + unsafe { + block ^= u32::from(self.buf.bytes.assume_init_ref()[0]); + } self.state.0 ^ pre_mix(block) } Index::_0 => self.state.0, @@ -139,7 +146,7 @@ impl core::hash::Hasher for Hasher { // self.buf.bytes[index..].copy_from_slice(head); for i in 0..4 - index { unsafe { - *self.buf.bytes.get_unchecked_mut(index + i) = *head.get_unchecked(i); + *self.buf.bytes.assume_init_mut().get_unchecked_mut(index + i) = *head.get_unchecked(i); } } @@ -184,8 +191,8 @@ const C2: u32 = 0x1b873593; const R1: u32 = 15; impl State { - fn process_block(&mut self, block: &[u8; 4]) { - self.0 ^= pre_mix(LE::read_u32(block)); + fn process_block(&mut self, block: &MaybeUninit<[u8; 4]>) { + self.0 ^= pre_mix(LE::read_u32(unsafe { block.assume_init_ref() })); self.0 = self.0.rotate_left(13); self.0 = 5u32.wrapping_mul(self.0).wrapping_add(0xe6546b64); }