use crate::{Gc, GcWeak};
#[macro_export]
macro_rules! unsize {
($gc:expr => $ty:ty) => {{
let gc = $gc;
unsafe {
$crate::__CoercePtrInternal::__coerce_unchecked(gc, |p: *const _| -> *const $ty { p })
}
}};
}
#[doc(hidden)]
pub unsafe trait __CoercePtrInternal<Dst> {
type FromPtr;
type ToPtr: ?Sized;
unsafe fn __coerce_unchecked<F>(self, coerce: F) -> Dst
where
F: FnOnce(*const Self::FromPtr) -> *const Self::ToPtr;
}
unsafe impl<'gc, T, U: ?Sized> __CoercePtrInternal<Gc<'gc, U>> for Gc<'gc, T> {
type FromPtr = T;
type ToPtr = U;
#[inline(always)]
unsafe fn __coerce_unchecked<F>(self, coerce: F) -> Gc<'gc, U>
where
F: FnOnce(*const T) -> *const U,
{
unsafe { Gc::from_ptr(coerce(Gc::as_ptr(self))) }
}
}
unsafe impl<'gc, T, U: ?Sized> __CoercePtrInternal<GcWeak<'gc, U>> for GcWeak<'gc, T> {
type FromPtr = T;
type ToPtr = U;
#[inline(always)]
unsafe fn __coerce_unchecked<F>(self, coerce: F) -> GcWeak<'gc, U>
where
F: FnOnce(*const T) -> *const U,
{
unsafe {
let inner = self.inner.__coerce_unchecked(coerce);
GcWeak { inner }
}
}
}