use core::cell::Cell;
use multitude::Arena;
thread_local! {
static DROPS: Cell<usize> = const { Cell::new(0) };
}
fn bump_drops() {
DROPS.with(|c| c.set(c.get() + 1));
}
struct ZstDrop;
impl Drop for ZstDrop {
fn drop(&mut self) {
bump_drops();
}
}
#[test]
fn each_zst_uninit_arc_assume_init_commits_its_own_placeholder() {
DROPS.with(|c| c.set(0));
{
let arena = Arena::new();
let a1 = arena.alloc_uninit_arc::<ZstDrop>();
let a2 = arena.alloc_uninit_arc::<ZstDrop>();
let a3 = arena.alloc_uninit_arc::<ZstDrop>();
let p1 = a1.as_ptr().cast_mut().cast::<core::mem::MaybeUninit<ZstDrop>>();
let p2 = a2.as_ptr().cast_mut().cast::<core::mem::MaybeUninit<ZstDrop>>();
let p3 = a3.as_ptr().cast_mut().cast::<core::mem::MaybeUninit<ZstDrop>>();
unsafe {
(*p1).write(ZstDrop);
}
unsafe {
(*p2).write(ZstDrop);
}
unsafe {
(*p3).write(ZstDrop);
}
let _i1 = unsafe { a1.assume_init() };
let _i2 = unsafe { a2.assume_init() };
let _i3 = unsafe { a3.assume_init() };
}
assert_eq!(
DROPS.with(Cell::get),
3,
"all three ZstDrop destructors must run; the (value_offset, len) commit lookup must disambiguate via the 1-byte ZST tag",
);
}
struct ZstMarker;
impl Drop for ZstMarker {
fn drop(&mut self) {
bump_drops();
}
}
const CHUNK_BASE_MASK: usize = !(65_536 - 1);
#[test]
fn zst_alloc_arc_never_returns_one_past_chunk_end() {
let arena = multitude::Arena::new();
let mut prev_base: Option<usize> = None;
for _ in 0..512 {
let a = arena.alloc_arc(ZstMarker);
let addr = (&raw const *a) as usize;
let base = addr & CHUNK_BASE_MASK;
let offset = addr - base;
assert!(offset < 65_536, "ZST Arc value pointer must lie strictly inside its 64 KiB tile");
let _ = prev_base;
prev_base = Some(base);
}
}
#[cfg(feature = "dst")]
#[test]
fn dst_box_at_max_normal_alloc_boundary_routes_consistently() {
use core::alloc::Layout;
let arena = multitude::Arena::new();
let layout = Layout::array::<u32>(4094).unwrap();
let init = |fat: *mut [u32]| {
let s = unsafe { &mut *fat };
for (i, v) in s.iter_mut().enumerate() {
*v = u32::try_from(i).expect("4094 fits in u32");
}
};
let b: multitude::Box<[u32]> = unsafe { arena.alloc_dst_box::<[u32]>(layout, 4094_usize, init) };
assert_eq!(b.len(), 4094);
assert_eq!(b[0], 0);
assert_eq!(b[4093], 4093);
}