From 22aaf91cc10c40a31cb403c3e35de4d2f7754eaa Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sun, 9 Oct 2022 17:31:20 +0200 Subject: [PATCH] This is now a safe interface! --- src/backend.rs | 4 ++++ src/lib.rs | 2 +- src/strategy.rs | 18 +++++------------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index 6715340..96e5852 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -54,6 +54,7 @@ mod backend_size_asserts { const _: () = assert_same_size::::Stored>(); } +// SAFETY: We are careful around provenance unsafe impl Backend for usize { type Stored = *mut (); @@ -72,6 +73,7 @@ unsafe impl Backend for usize { #[cfg(target_pointer_width = "64")] /// on 64 bit, we can just treat u64/usize interchangeably, because uintptr_t == size_t in Rust +// SAFETY: We are careful around provenance unsafe impl Backend for u64 { type Stored = *mut (); @@ -90,6 +92,7 @@ unsafe impl Backend for u64 { macro_rules! impl_backend_2_tuple { (impl for $ty:ty { (*mut (), $int:ident), $num:expr }) => { + // SAFETY: We are careful around provenance unsafe impl Backend for $ty { // this one keeps the MSB in the pointer address, and the LSB in the integer @@ -117,6 +120,7 @@ macro_rules! impl_backend_2_tuple { #[cfg_attr(target_pointer_width = "64", allow(unused))] // not required on 64 bit macro_rules! impl_backend_3_tuple { (impl for $ty:ty { (*mut (), $int1:ident, $int2:ident), $num1:expr, $num2:expr }) => { + // SAFETY: We are careful around provenance unsafe impl Backend for $ty { // this one keeps the MSB in the pointer address, ISB in int1 and the LSB in the int2 diff --git a/src/lib.rs b/src/lib.rs index 8190c34..9d691a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ //! // implementation detail of NaN boxing, the sign bit of an f64 //! const SIGN_BIT: u64 = 0x8000000000000000; //! -//! unsafe impl StuffingStrategy for NanBoxStrategy { +//! impl StuffingStrategy for NanBoxStrategy { //! type Other = f64; //! //! fn stuff_other(inner: Self::Other) -> u64 { diff --git a/src/strategy.rs b/src/strategy.rs index 91b6824..59ec713 100644 --- a/src/strategy.rs +++ b/src/strategy.rs @@ -10,15 +10,7 @@ use crate::{Backend, Unstuffed}; /// if possible. /// /// The generic parameter `B` stands for the [`Backend`](`crate::Backend`) used by the strategy. -/// -/// # Safety -/// -/// If [`StuffingStrategy::is_other`] returns true for a value, then -/// [`StuffingStrategy::extract_other`] *must* return a valid `Other` for that same value. -/// -/// For [`StuffingStrategy::stuff_ptr`] and [`StuffingStrategy::extract_ptr`], -/// `ptr == extract_ptr(stuff_ptr(ptr))` *must* hold true. -pub unsafe trait StuffingStrategy { +pub trait StuffingStrategy { /// The type of the other. type Other: Copy; @@ -40,7 +32,7 @@ pub unsafe trait StuffingStrategy { fn stuff_ptr(addr: usize) -> B; } -unsafe impl StuffingStrategy for () +impl StuffingStrategy for () where B: Backend + Default + TryInto, usize: TryInto, @@ -75,7 +67,7 @@ pub(crate) mod test_strategies { macro_rules! impl_usize_max_zst { ($ty:ident) => { // this one lives in usize::MAX - unsafe impl StuffingStrategy for $ty { + impl StuffingStrategy for $ty { type Other = Self; #[allow(clippy::forget_copy)] @@ -96,7 +88,7 @@ pub(crate) mod test_strategies { } } - unsafe impl StuffingStrategy for $ty { + impl StuffingStrategy for $ty { type Other = Self; #[allow(clippy::forget_copy)] @@ -117,7 +109,7 @@ pub(crate) mod test_strategies { } } - unsafe impl StuffingStrategy for $ty { + impl StuffingStrategy for $ty { type Other = Self; #[allow(clippy::forget_copy)]