use std::{ptr::NonNull, sync::atomic::AtomicUsize};
use ptr_union::Union8;
#[derive(Debug)]
struct MyBox {
ptr: NonNull<u8>,
}
fn ptr_dangling_at<T>(addr: usize) -> *mut T {
#[cfg(not(has_strict_provenance))]
{
addr as _
}
#[cfg(has_strict_provenance)]
{
std::ptr::without_provenance_mut(addr)
}
}
unsafe impl erasable::ErasablePtr for MyBox {
fn erase(this: Self) -> erasable::ErasedPtr {
this.ptr.cast()
}
unsafe fn unerase(this: erasable::ErasedPtr) -> Self {
Self { ptr: this.cast() }
}
}
static OFFSET: AtomicUsize = AtomicUsize::new(8);
impl MyBox {
fn new() -> Self {
let offset = OFFSET.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
MyBox {
ptr: NonNull::new(ptr_dangling_at(offset)).unwrap(),
}
}
}
impl Clone for MyBox {
fn clone(&self) -> Self {
Self::new()
}
}
type Union = Union8<
MyBox,
NonNull<u8>,
NonNull<u8>,
NonNull<u8>,
NonNull<u8>,
NonNull<u8>,
NonNull<u8>,
NonNull<u8>,
>;
#[test]
#[allow(clippy::redundant_clone)]
#[should_panic = "but the cloned pointer wasn't sufficiently aligned"]
fn test_clone_unaligned() {
let bx = MyBox::new();
let x = Union::new_a(bx).unwrap();
let _y = x.clone();
}