diff --git a/src/lib.rs b/src/lib.rs index 462ec46c..c7441e33 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ not(debug_assertions), deny(missing_docs, clippy::missing_docs_in_private_items) )] +#![cfg_attr(miri, feature(strict_provenance))] #![deny(unconditional_recursion)] #![allow( clippy::declare_interior_mutable_const, diff --git a/src/ptr/span.rs b/src/ptr/span.rs index a6be1756..c216a57e 100644 --- a/src/ptr/span.rs +++ b/src/ptr/span.rs @@ -273,10 +273,17 @@ where /// [`::new`]: Self::new #[cfg(feature = "alloc")] pub(crate) unsafe fn set_address(&mut self, addr: Address) { - let mut addr_value = addr.to_const() as usize; - addr_value &= Self::PTR_ADDR_MASK; - addr_value |= self.ptr.as_ptr() as usize & Self::PTR_HEAD_MASK; - self.ptr = NonNull::new_unchecked(addr_value as *mut ()) + let map = |mut addr_value| { + addr_value &= Self::PTR_ADDR_MASK; + addr_value |= self.ptr.as_ptr() as usize & Self::PTR_HEAD_MASK; + addr_value + }; + + #[cfg(miri)] + let new_addr = addr.to_const().map_addr(map).cast::<()>().cast_mut(); + #[cfg(not(miri))] + let new_addr = map(addr.to_const() as usize) as *mut (); + self.ptr = NonNull::new_unchecked(new_addr); } /// Gets the starting bit index of the referent region. @@ -313,11 +320,19 @@ where #[cfg(feature = "alloc")] pub(crate) unsafe fn set_head(&mut self, head: BitIdx) { let head = head.into_inner() as usize; - let mut ptr = self.ptr.as_ptr() as usize; + let map = |mut ptr_value| { + ptr_value &= Self::PTR_ADDR_MASK; + ptr_value |= head >> Self::LEN_HEAD_BITS; + ptr_value + }; + + let ptr = self.ptr.as_ptr(); - ptr &= Self::PTR_ADDR_MASK; - ptr |= head >> Self::LEN_HEAD_BITS; - self.ptr = NonNull::new_unchecked(ptr as *mut ()); + #[cfg(miri)] + let new_ptr = ptr.map_addr(map); + #[cfg(not(miri))] + let new_ptr = map(ptr as usize) as *mut (); + self.ptr = NonNull::new_unchecked(new_ptr); self.len &= !Self::LEN_HEAD_MASK; self.len |= head & Self::LEN_HEAD_MASK; diff --git a/src/ptr/tests.rs b/src/ptr/tests.rs index b6fb79cf..ef720e19 100644 --- a/src/ptr/tests.rs +++ b/src/ptr/tests.rs @@ -23,13 +23,14 @@ fn free_functions() { let one = BitPtr::::from_slice_mut(&mut a[..]); let two = one.wrapping_add(8); - let three = BitPtr::::from_mut(&mut b); - let four = three.wrapping_add(8); unsafe { bv_ptr::copy(two.to_const(), one, 8); } assert_eq!(a[0], !0); + + let one = BitPtr::::from_slice_mut(&mut a[..]); + let three = BitPtr::::from_mut(&mut b); unsafe { bv_ptr::copy(three.to_const(), one, 8); } @@ -43,6 +44,8 @@ fn free_functions() { assert_eq!(a[1], 0); assert_eq!(b, !0); + let three = BitPtr::::from_mut(&mut b); + let four = three.wrapping_add(8); unsafe { bv_ptr::write_bits(four, false, 8); } diff --git a/src/slice.rs b/src/slice.rs index f73efc49..7d1037bc 100644 --- a/src/slice.rs +++ b/src/slice.rs @@ -3,6 +3,7 @@ #[cfg(feature = "alloc")] use alloc::vec::Vec; use core::{ + cell::UnsafeCell, marker::PhantomData, ops::RangeBounds, }; @@ -82,7 +83,7 @@ where /// /// See `ptr::span` for more information on the encoding scheme used in /// references to `BitSlice`. - _mem: [()], + _mem: [UnsafeCell<()>], } /// Constructors. diff --git a/src/slice/traits.rs b/src/slice/traits.rs index 7fcd3a3f..210fb6e4 100644 --- a/src/slice/traits.rs +++ b/src/slice/traits.rs @@ -20,6 +20,7 @@ use core::{ Hash, Hasher, }, + panic::RefUnwindSafe, str, }; @@ -541,6 +542,13 @@ where } } +impl RefUnwindSafe for BitSlice +where + T: BitStore + RefUnwindSafe, + O: BitOrder, +{ +} + #[doc = include_str!("../../doc/slice/threadsafe.md")] unsafe impl Send for BitSlice where