use std::pin::Pin; use std::ptr::NonNull; use crate::alloc::{Allocation, Data, Ptr}; use crate::trace::Trace; pub struct GcPtr { inner: Ptr>, } impl GcPtr { pub(crate) fn new(data: T) -> GcPtr { GcPtr { inner: Allocation::new(data), } } } impl GcPtr { /// Get a reference to the GC'd data /// /// Invariants: GcPtr must not be dangling pub unsafe fn data(&self) -> &T { self.inner.as_ref().data() } /// Tell if this ptr is managed or not /// /// Invariants: GcPtr must not be dangling pub unsafe fn is_unmanaged(&self) -> bool { self.inner.as_ref().is_unmanaged() } /// Free the data behind this GcPtr /// /// Invariants: GcPtr must not be dangling, must not be managed and must not be read again pub unsafe fn deallocate(self) { drop(Box::from_raw(self.inner.as_ptr())) } pub(crate) fn erased(self) -> Ptr> { unsafe { Ptr(NonNull::new_unchecked( self.inner.as_ptr() as *mut Allocation )) } } pub(crate) unsafe fn erased_pinned<'a>(self) -> Pin<&'a Allocation> { Pin::new_unchecked(&*self.erased().as_ptr()) } } unsafe impl Send for GcPtr {} unsafe impl Sync for GcPtr {} unsafe impl Trace for GcPtr { unsafe fn mark(&self) { self.inner.as_ref().mark(); } unsafe fn manage(&self) { super::manage(*self) } unsafe fn finalize(&mut self) {} } impl Clone for GcPtr { fn clone(&self) -> GcPtr { *self } } impl Copy for GcPtr {}