Panic safety: OwnedAlloc::drop_in_place double-frees on a panicking element Drop

OwnedAlloc::drop_in_place has a panic-safety unsoundness. It destroys the contained value with drop_in_place, then commits the ownership transfer with mem::forget(self) — which lives inside into_raw. T::drop is user-controlled and can panic; if it does, into_raw is never reached, the forget is skipped, and the still-live OwnedAlloc is dropped during unwinding. Its Drop runs drop_in_place on the same T a second time and then deallocs. For a T that owns an allocation, that's a double-free (CWE-415) reachable from safe Rust.

src/owned.rs:

pub fn drop_in_place(self) -> UninitAlloc<T> {
    unsafe {
        self.nnptr.as_ptr().drop_in_place();      // T::drop() may panic
        UninitAlloc::from_raw(self.into_raw())    // mem::forget skipped on panic
    }
}

The destructor also reads the already-destroyed value through Layout::for_value(self.nnptr.as_ref()) before deallocating.

MaybeUninitAlloc::drop_in_place delegates here, so both public APIs are affected. OwnedAlloc::new with a T whose Drop panics is enough — no particular element type beyond one that owns a heap allocation, so the second free is observable. With a String field followed by a one-shot panicking Drop, the PoC reports attempting double-free under AddressSanitizer.

Suggested fix: take the marker before destroying, the way init and init_in_place in this crate already do.

let raw = self.into_raw();      // mem::forget, cannot panic
raw.as_ptr().drop_in_place();
UninitAlloc::from_raw(raw)

A panicking Drop then leaks the allocation rather than freeing it twice.

Confirmed on 0.2.0.