haphazard/pointer.rs
1use alloc::boxed::Box;
2
3/// Trait for types that can be dropped (which is all of them).
4///
5/// This trait exists solely as a workaround for the fact that only types with an explicit `Drop`
6/// implementation implement `Drop`, even though all types _can_ be dropped. We want to store
7/// the equivalent of `Box<dyn Drop>` when objects are retired, but can't do that since not every
8/// type is `Drop`. This trait is effectively the same as `Drop` (every trait implies `Drop`), and
9/// has a blanket implementation for any type, so can be used instead of `dyn Drop`.
10///
11/// See also <https://github.com/rust-lang/rust/issues/86653> and
12/// <https://github.com/rust-lang/rust/pull/86747>.
13pub trait Reclaim {}
14impl<T> Reclaim for T {}
15
16/// A type that can be turned into, and converted from, a raw pointer whose referent is `T`.
17///
18/// # Safety
19///
20/// 1. the `*mut T` returned from `into_raw` must be valid as a `&mut T` when it is returned.
21/// 2. the `*mut T` returned from `into_raw` must remain valid as a `&T` until it is passed to
22/// `from_raw`.
23/// 3. `from_raw` must not return a particular `*mut T` again until the provided `self` is dropped
24/// after an eventual call to `from_raw`.
25pub unsafe trait Pointer<T>
26where
27 Self: Sized + core::ops::Deref<Target = T>,
28{
29 /// Extract the raw pointer referenced by `self`.
30 fn into_raw(self) -> *mut T;
31
32 /// Reconstruct this pointer type from the given `ptr`.
33 ///
34 /// # Safety (for callers)
35 ///
36 /// 1. `ptr` must be a pointer returned by `Self::into_raw`
37 /// 2. `ptr` must be valid to dereference to a `T`
38 /// 3. `ptr` must not have been passed to `from_raw` since it was returned from `into_raw`
39 /// 4. `ptr` must not be aliased
40 #[allow(clippy::missing_safety_doc)]
41 unsafe fn from_raw(ptr: *mut T) -> Self;
42}
43
44unsafe impl<T> Pointer<T> for Box<T> {
45 fn into_raw(self) -> *mut T {
46 Box::into_raw(self)
47 }
48
49 unsafe fn from_raw(ptr: *mut T) -> Self {
50 // Safety: the safety requirements for Box::from_raw are the same as for Pointer::from_raw.
51 unsafe { Box::from_raw(ptr) }
52 }
53}