I was writing a StackBox
that references a variable allocated on a memory-mapped stack and implemented Drop
trait so that StackBox
can be used as a reference.
Since I can guarantee that if StackBox
is ever created by my code, then the memory-mapped stack must not be modified, I decided to add pin
method that returns Pin<&T>
.
However I found it weird that Pin::new_unchecked(&self)
worked but Pin::new_unchecked(&self).as_ref()
doesn't work.
Here's the full code of StackBox
:
pub struct StackBox<'a, T> {
ptr: *mut T,
phantom: PhantomData<&'a T>,
}
impl<'a, T> StackBox<'a, T> {
fn new(ptr: *mut T) -> StackBox<'a, T> {
StackBox {
ptr,
phantom: PhantomData
}
}
/// Why does this compile?
/// Pin::new_unchecked(&self).as_ref() doesn't work here
pub fn pin(&self) -> Pin<&T> {
unsafe { Pin::new_unchecked(&self) }
}
}
impl<'a, T> Drop for StackBox<'a, T> {
fn drop(&mut self) {
unsafe {
self.ptr.drop_in_place();
}
}
}
impl<'a, T> Deref for StackBox<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { & *self.ptr }
}
}
impl<'a, T> DerefMut for StackBox<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.ptr }
}
}