use std::{
marker::PhantomData,
mem::{self, ManuallyDrop, MaybeUninit},
ptr::{self, NonNull},
result,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Metadata(pub u8);
impl Metadata {
pub const MASK: u8 = 0b00000011;
pub const _0: Metadata = Metadata(0b00000000);
pub const _1: Metadata = Metadata(0b00000001);
pub const _2: Metadata = Metadata(0b00000010);
pub const _3: Metadata = Metadata(0b00000011);
}
cfg_select! {
target_pointer_width = "64" => {
#[repr(C, align(8))]
pub struct Align4PtrCompat<T> {
meta: u8,
store: [u8; 7],
after_store: PhantomData<T>,
}
},
target_pointer_width = "32" => {
#[repr(C, align(4))]
pub struct Align4PtrCompat<T> {
meta: u8,
store: [u8; 3],
after_store: PhantomData<T>,
}
},
}
impl<T> Align4PtrCompat<T> {
pub const fn store_offset() -> Option<isize> {
let target_size = mem::size_of::<T>();
let target_align = mem::align_of::<T>();
let store_offset_start = mem::offset_of!(Self, store);
let store_offset_end = mem::offset_of!(Self, after_store);
let store_size = store_offset_end - store_offset_start;
let max_align_allowed = store_size.next_power_of_two() / 2;
if target_align > max_align_allowed {
return None;
}
let mut offset = store_offset_start;
while offset <= store_offset_end {
if (target_align + offset) % target_align == 0
&& store_offset_end - offset >= target_size
{
return Some((offset - store_offset_start) as isize);
}
offset += 1;
}
None
}
pub fn new(meta: Metadata, value: T) -> result::Result<Self, T> {
let Some(store_offset) = Self::store_offset() else {
return Err(value);
};
let mut this = unsafe {
Self {
meta: meta.0,
store: mem::zeroed(),
after_store: PhantomData,
}
};
unsafe {
let value_mut =
&mut *(this.store.as_mut_ptr().offset(store_offset) as *mut MaybeUninit<T>);
value_mut.write(value);
}
Ok(this)
}
pub fn borrow_value(&self) -> &T {
unsafe {
let store_offset = Self::store_offset().unwrap_unchecked();
&*(self.store.as_ptr().offset(store_offset) as *const T)
}
}
pub fn into_value(self) -> T {
unsafe {
let store_offset = Self::store_offset().unwrap_unchecked();
let mut this = ManuallyDrop::new(self);
let value_mut = this.store.as_mut_ptr().offset(store_offset) as *mut T;
value_mut.read()
}
}
}
impl<T> Drop for Align4PtrCompat<T> {
fn drop(&mut self) {
let store_offset = Self::store_offset()
.expect("store_offset must be checked before creating an Align4PtrCompat");
unsafe {
let value_mut =
&mut *(self.store.as_mut_ptr().offset(store_offset) as *mut ManuallyDrop<T>);
ManuallyDrop::drop(value_mut);
}
}
}
#[derive(Clone, Copy)]
#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))]
#[cfg_attr(target_pointer_width = "64", repr(C, align(8)))]
struct Align4Ptr(
cfg_select! {
target_pointer_width = "64" => [u8; 8],
target_pointer_width = "32" => [u8; 4],
},
);
impl Align4Ptr {
fn from_parts(addr: usize, meta: Metadata) -> Self {
let mut bytes = addr.to_le_bytes();
assert_eq!(bytes[0] & Metadata::MASK, 0);
bytes[0] |= meta.0;
Self(bytes)
}
fn into_parts(self) -> (usize, Metadata) {
let mut bytes = self.0;
let meta = Metadata(bytes[0] & Metadata::MASK);
bytes[0] &= !Metadata::MASK;
let addr = usize::from_le_bytes(bytes);
(addr, meta)
}
}
#[repr(C, align(4))]
pub struct Align4<T: ?Sized>(pub T);
#[repr(C)]
pub struct Align4Own<T> {
ptr: Align4Ptr,
_marker: PhantomData<Align4<T>>,
}
impl<T> Align4Own<T> {
pub fn from_boxed(ptr: Box<Align4<T>>, meta: Metadata) -> Self {
let addr = Box::into_raw(ptr).expose_provenance();
Self {
ptr: Align4Ptr::from_parts(addr, meta),
_marker: PhantomData,
}
}
pub fn into_raw(self) -> *mut Align4<T> {
let this = ManuallyDrop::new(self);
ptr::with_exposed_provenance_mut(this.ptr.into_parts().0)
}
pub unsafe fn into_boxed(self) -> Box<Align4<T>> {
unsafe { Box::from_raw(self.into_raw()) }
}
pub unsafe fn cast<U>(self) -> Align4Own<U> {
let (_, meta) = self.ptr.into_parts();
Align4Own::from_boxed(
unsafe { Box::from_raw(self.into_raw().cast::<Align4<U>>()) },
meta,
)
}
pub fn borrow(&self) -> Ref<'_, T> {
let (addr, _) = self.ptr.into_parts();
let ptr: *mut Align4<T> = ptr::with_exposed_provenance_mut(addr);
let ptr = ptr.cast::<T>();
Ref {
ptr: unsafe { NonNull::new_unchecked(ptr) },
_marker: PhantomData,
}
}
pub fn borrow_mut(&self) -> Mut<'_, T> {
let (addr, _) = self.ptr.into_parts();
let ptr: *mut Align4<T> = ptr::with_exposed_provenance_mut(addr);
let ptr = ptr.cast::<T>();
Mut {
ptr: unsafe { NonNull::new_unchecked(ptr) },
_marker: PhantomData,
}
}
}
impl<T> Drop for Align4Own<T> {
fn drop(&mut self) {
unsafe {
let _ = Box::from_raw(Self::into_raw(Self {
ptr: self.ptr,
_marker: PhantomData,
}));
}
}
}
#[derive(Clone, Copy)]
#[repr(C, align(4))]
pub struct Align4Ref<'a, T> {
ptr: Align4Ptr,
_marker: PhantomData<&'a Align4<T>>,
}
impl<'a, T> Align4Ref<'a, T> {
pub fn new(static_ref: &'a Align4<T>, meta: Metadata) -> Align4Ref<'a, T> {
Self {
ptr: Align4Ptr::from_parts((&raw const *static_ref).expose_provenance(), meta),
_marker: PhantomData,
}
}
pub fn borrow(&self) -> Ref<'_, T> {
let (addr, _) = self.ptr.into_parts();
let ptr: *const Align4<T> = ptr::with_exposed_provenance(addr);
let ptr = ptr.cast::<T>();
Ref {
ptr: unsafe { NonNull::new_unchecked(ptr.cast_mut()) },
_marker: PhantomData,
}
}
}
#[derive(Clone, Copy)]
pub struct Ref<'a, T> {
ptr: NonNull<T>,
_marker: PhantomData<&'a Align4<T>>,
}
impl<'a, T> Ref<'a, T> {
pub unsafe fn cast<U>(self) -> Ref<'a, U> {
Ref {
ptr: self.ptr.cast::<U>(),
_marker: PhantomData,
}
}
pub unsafe fn project<F>(self, f: fn(*const T) -> *const F) -> Ref<'a, F> {
Ref {
ptr: unsafe { NonNull::new_unchecked(f(self.ptr.as_ptr()).cast_mut()) },
_marker: PhantomData,
}
}
pub fn deref(&self) -> &'a T {
unsafe { self.ptr.as_ref() }
}
}
impl<'a, T> Ref<'a, T>
where
T: Copy,
{
pub fn copied(&self) -> T {
unsafe { self.ptr.read() }
}
}
pub struct Mut<'a, T> {
ptr: NonNull<T>,
_marker: PhantomData<&'a mut Align4<T>>,
}
impl<'a, T> Mut<'a, T> {
pub unsafe fn cast<U>(self) -> Mut<'a, U> {
Mut {
ptr: self.ptr.cast::<U>(),
_marker: PhantomData,
}
}
pub unsafe fn project<F>(self, f: fn(*mut T) -> *mut F) -> Mut<'a, F> {
Mut {
ptr: unsafe { NonNull::new_unchecked(f(self.ptr.as_ptr())) },
_marker: PhantomData,
}
}
pub fn deref_mut(&mut self) -> &'a mut T {
unsafe { self.ptr.as_mut() }
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::mem;
#[test]
fn align4_ptr_round_trip() {
let addr = 0xDEAD_BEE0usize; for meta in [Metadata::_0, Metadata::_1, Metadata::_2, Metadata::_3] {
let ptr = Align4Ptr::from_parts(addr, meta);
let (restored_addr, restored_meta) = ptr.into_parts();
assert_eq!(restored_addr, addr);
assert_eq!(restored_meta, meta);
}
}
#[test]
#[should_panic]
fn align4_ptr_panics_on_unaligned() {
let addr = 0xDEAD_BEEFusize; Align4Ptr::from_parts(addr, Metadata::_0);
}
#[test]
fn align4_own_boxed_round_trip() {
let value = Box::new(Align4(42u32));
let owned = Align4Own::from_boxed(value, Metadata::_1);
let restored = unsafe { owned.into_boxed() };
assert_eq!(restored.0, 42);
}
#[test]
fn align4_own_cast_preserves_data() {
let value = Box::new(Align4(0xABCD_EF01u32));
let owned = Align4Own::from_boxed(value, Metadata::_2);
let casted = unsafe { owned.cast::<[u8; 4]>() };
let restored = unsafe { casted.into_boxed() };
assert_eq!(restored.0, [0x01, 0xEF, 0xCD, 0xAB]); }
#[test]
fn ref_deref_valid() {
let value = Box::new(Align4(99u64));
let owned = Align4Own::from_boxed(value, Metadata::_0);
let r = owned.borrow();
assert_eq!(*r.deref(), 99);
}
#[test]
fn ref_project_field() {
#[repr(C)]
struct Pair {
x: u32,
y: u32,
}
let value = Box::new(Align4(Pair { x: 10, y: 20 }));
let owned = Align4Own::from_boxed(value, Metadata::_0);
let r = owned.borrow();
let y_ref = unsafe { r.project(|p| &raw const (*p).y) };
assert_eq!(*y_ref.deref(), 20);
}
#[test]
fn align4_guarantees_alignment() {
assert!(mem::align_of::<Align4<u8>>() >= 4);
assert!(mem::align_of::<Align4<u64>>() >= 4);
}
#[test]
fn align4_ptr_compat_max_u8_array() {
const N: usize = if cfg!(target_pointer_width = "64") {
7
} else {
3
};
let Ok(v) = Align4PtrCompat::<[u8; N]>::new(Metadata::_0, [0xAB; N]) else {
panic!("max u8 array should fit");
};
assert_eq!(v.borrow_value(), &[0xAB; N]);
}
#[test]
fn align4_ptr_compat_u8_array_one_too_many() {
const N: usize = if cfg!(target_pointer_width = "64") {
8
} else {
4
};
assert!(Align4PtrCompat::<[u8; N]>::store_offset().is_none());
}
#[test]
fn align4_ptr_compat_u16_store_offset() {
assert!(Align4PtrCompat::<u16>::store_offset().is_some());
}
#[test]
fn align4_ptr_compat_u32_store_offset() {
if cfg!(target_pointer_width = "64") {
assert!(Align4PtrCompat::<u32>::store_offset().is_some());
} else {
assert!(Align4PtrCompat::<u32>::store_offset().is_none());
}
}
#[test]
fn align4_ptr_compat_u64_is_oversized() {
assert!(Align4PtrCompat::<u64>::store_offset().is_none());
}
#[test]
fn align4_ptr_compat_new_preserves_meta() {
let Ok(v) = Align4PtrCompat::<[u8; 1]>::new(Metadata::_3, [0x42]) else {
panic!("[u8; 1] should fit");
};
assert_eq!(*v.borrow_value(), [0x42]);
}
#[test]
fn align4_ptr_compat_new_returns_err_for_oversized() {
const N: usize = if cfg!(target_pointer_width = "64") {
8
} else {
4
};
let value = [0x42u8; N];
let result = Align4PtrCompat::<[u8; N]>::new(Metadata::_0, value);
assert!(result.is_err());
}
}