use crate as stabby;
#[rustversion::nightly]
pub trait IConstConstructor<'a, Source>: 'a + Copy + core::marker::Freeze {
const VTABLE: &'a Self;
}
#[rustversion::not(nightly)]
pub trait IConstConstructor<'a, Source>: 'a + Copy {
const VTABLE: &'a Self;
}
pub trait TransitiveDeref<Head, N> {
fn tderef(&self) -> &Head;
}
pub struct H;
pub struct T<T>(T);
#[stabby::stabby]
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct VTable<Head, Tail = VtDrop> {
pub tail: Tail,
pub head: Head,
}
pub trait CompoundVt {
type Vt<T>;
}
impl<'a, T, Head: Copy + 'a, Tail: Copy + 'a> IConstConstructor<'a, T> for VTable<Head, Tail>
where
Head: IConstConstructor<'a, T>,
Tail: IConstConstructor<'a, T>,
{
const VTABLE: &'a VTable<Head, Tail> = &VTable {
head: *Head::VTABLE,
tail: *Tail::VTABLE,
};
}
impl<'a, T> IConstConstructor<'a, T> for () {
const VTABLE: &'a () = &();
}
impl<Head, Tail> TransitiveDeref<Head, H> for VTable<Head, Tail> {
fn tderef(&self) -> &Head {
&self.head
}
}
impl<Head, Tail: TransitiveDeref<Vt, N>, Vt, N> TransitiveDeref<Vt, T<N>> for VTable<Head, Tail> {
fn tderef(&self) -> &Vt {
self.tail.tderef()
}
}
pub trait HasDropVt {
fn drop_vt(&self) -> &VtDrop;
}
impl HasDropVt for VtDrop {
fn drop_vt(&self) -> &VtDrop {
self
}
}
impl<Head, Tail: HasDropVt> HasDropVt for VTable<Head, Tail> {
fn drop_vt(&self) -> &VtDrop {
self.tail.drop_vt()
}
}
impl<T: HasDropVt> HasDropVt for VtSend<T> {
fn drop_vt(&self) -> &VtDrop {
self.0.drop_vt()
}
}
impl<T: HasDropVt> HasDropVt for VtSync<T> {
fn drop_vt(&self) -> &VtDrop {
self.0.drop_vt()
}
}
pub trait HasSendVt {}
impl<T> HasSendVt for VtSend<T> {}
impl<T: HasSendVt> HasSendVt for VtSync<T> {}
impl<Head, Tail: HasSyncVt> HasSendVt for VTable<Head, Tail> {}
pub trait HasSyncVt {}
impl<T> HasSyncVt for VtSync<T> {}
impl<T: HasSyncVt> HasSyncVt for VtSend<T> {}
impl<Head, Tail: HasSyncVt> HasSyncVt for VTable<Head, Tail> {}
#[stabby::stabby]
#[derive(Clone, Copy)]
pub struct VtDrop {
pub drop: crate::StableLike<unsafe extern "C" fn(&mut ()), core::num::NonZeroUsize>,
}
impl PartialEq for VtDrop {
fn eq(&self, other: &Self) -> bool {
core::ptr::eq(
unsafe { self.drop.as_ref_unchecked() } as *const unsafe extern "C" fn(&mut ()),
unsafe { other.drop.as_ref_unchecked() } as *const unsafe extern "C" fn(&mut ()),
)
}
}
impl<'a, T> IConstConstructor<'a, T> for VtDrop {
const VTABLE: &'a VtDrop = &VtDrop {
drop: unsafe {
core::mem::transmute({
unsafe extern "C" fn drop<T>(this: &mut T) {
core::ptr::drop_in_place(this)
}
drop::<T>
} as unsafe extern "C" fn(&mut T))
},
};
}
#[stabby::stabby]
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct VtSend<T>(pub T);
impl CompoundVt for dyn Send {
type Vt<T> = VtSend<T>;
}
impl<Tail: TransitiveDeref<Vt, N>, Vt, N> TransitiveDeref<Vt, N> for VtSend<Tail> {
fn tderef(&self) -> &Vt {
self.0.tderef()
}
}
impl<Head, Tail> From<crate::vtable::VtSend<VTable<Head, Tail>>> for VTable<Head, Tail> {
fn from(value: VtSend<VTable<Head, Tail>>) -> Self {
value.0
}
}
impl<'a, T: Send, Vt: IConstConstructor<'a, T>> IConstConstructor<'a, T> for VtSend<Vt> {
const VTABLE: &'a VtSend<Vt> = &VtSend(*Vt::VTABLE);
}
#[stabby::stabby]
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct VtSync<T>(pub T);
impl CompoundVt for dyn Sync {
type Vt<T> = VtSync<T>;
}
impl<'a, T: Sync, Vt: IConstConstructor<'a, T>> IConstConstructor<'a, T> for VtSync<Vt> {
const VTABLE: &'a VtSync<Vt> = &VtSync(*Vt::VTABLE);
}
impl<Tail: TransitiveDeref<Vt, N>, Vt, N> TransitiveDeref<Vt, N> for VtSync<Tail> {
fn tderef(&self) -> &Vt {
self.0.tderef()
}
}
impl<Head, Tail> From<crate::vtable::VtSync<VtSend<VTable<Head, Tail>>>> for VTable<Head, Tail> {
fn from(value: VtSync<VtSend<VTable<Head, Tail>>>) -> Self {
value.0 .0
}
}
impl<Head, Tail> From<crate::vtable::VtSync<VtSend<VTable<Head, Tail>>>>
for VtSend<VTable<Head, Tail>>
{
fn from(value: VtSync<VtSend<VTable<Head, Tail>>>) -> Self {
value.0
}
}
impl<Head, Tail> From<crate::vtable::VtSync<VTable<Head, Tail>>> for VTable<Head, Tail> {
fn from(value: VtSync<VTable<Head, Tail>>) -> Self {
value.0
}
}
#[stabby::stabby]
pub trait Any {
extern "C" fn report(&self) -> &'static crate::report::TypeReport;
}
impl<T: crate::IStable> Any for T {
extern "C" fn report(&self) -> &'static crate::report::TypeReport {
Self::REPORT
}
}