expiring_ref 0.9.0

A crate designed to implement a mechanism for owning values, via a destructively-moved equivalent to C++'s xvalues/`T&&`
Documentation
#![no_std]
#![allow(internal_features)] // only using one for macros
// The Great Wall Of `expiring_ref`
#![feature(allocator_api)]
#![feature(ptr_metadata)]
#![feature(slice_ptr_get)]
#![feature(transmute_prefix)]
#![feature(const_destruct)]
#![feature(const_trait_impl)]
#![feature(const_convert)]
#![feature(arbitrary_self_types)]
#![feature(unsize)]
#![feature(coerce_unsized)]
#![feature(maybe_dangling)]
#![feature(deref_pure_trait)]
#![feature(negative_impls)]
#![feature(const_drop_in_place)]
#![feature(const_heap)]
#![feature(const_iter)]
#![feature(const_manually_drop_take)]
#![feature(decl_macro)]
#![feature(const_slice_make_iter)]
#![feature(sized_type_properties)]
#![feature(impl_restriction)]
#![feature(min_specialization)]
#![feature(fundamental)]
#![feature(const_clone)]
#![feature(trusted_random_access)]
#![feature(allow_internal_unstable)] // this one
#![feature(const_try)]
#![feature(rustc_attrs)]
#![feature(field_projections)]

pub mod iter;
pub mod traits;
pub mod macros;
pub mod unstable;

extern crate alloc;

use crate::traits::{DerefMove, DerefOwn};
#[cfg(feature = "alloc")]
use alloc::{boxed::Box, string::String, vec::Vec};
#[cfg(feature = "alloc")]
use core::{alloc::Allocator, mem::transmute_prefix as transmute};

use core::marker::{Destruct, Unsize};
use core::mem::{ManuallyDrop, MaybeDangling, forget};
use core::ops::{AddAssign, CoerceUnsized, Deref, DerefMut, DerefPure};
use core::panic::UnwindSafe;
use core::ptr::NonNull;

// TODO: Solution for field projections please
/// `&'a own T`, aka an equivalent to C++'s `T&&`
/// More specifically, this value represents an owned reference which has its contents dropped when it itself is dropped.
#[repr(transparent)]
#[fundamental]
pub struct Own<'a, T: ?Sized + 'a> {
    inner: &'a mut ManuallyDrop<T>
}

impl<'a, 'b: 'a, T: ?Sized + 'b> Own<'a, Own<'b, T>> {
    #[inline]
    pub fn project_deref(this: Self) -> Own<'a, T> {
        // SAFETY: this is not used again
        unsafe { ManuallyDrop::take(Self::into_inner(this)) }
    }
}

const impl<'a, T: ?Sized+ 'a> Deref for Own<'a, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &**self.inner
    }
}

impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Own<'a, U>> for Own<'b, T> {}

const impl<'a, T: ?Sized> Own<'a, T> {
    /// SAFETY: Inner must be non-dangling and undropped (is this unsafe tho?)
    #[inline(always)]
    pub unsafe fn new(inner: &'a mut ManuallyDrop<T>) -> Self {
        Self {
            inner
        }
    }

    /// SAFETY: VERY unsafe, `inner` must be FORGOTTEN and UNUSED AFTER THIS.
    #[inline(always)]
    pub unsafe fn from_mut(inner: &'a mut T) -> Self {
        Self {
            inner: unsafe { transmute(inner) }
        }
    }

    //noinspection RsSelfConvention
    #[inline(always)]
    pub fn into_inner(this: Self) -> &'a mut ManuallyDrop<T> {
        // SAFETY: transparent around it :3
        unsafe { transmute(this) }
    }
}

const impl<'a, T: ?Sized> Drop for Own<'a, T> where T: [const] Destruct {
    fn drop(&mut self) {
        // SAFETY: this is not exposed elsewhere, it is otherwise undroppable
        unsafe { ManuallyDrop::drop(self.inner) }
    }
}

impl<'a, T: ?Sized> !UnwindSafe for Own<'a, T> {}

const impl<T> DerefMove for Own<'_, T> {
    fn deref_move(self) -> Self::Target {
        let mut slot = ManuallyDrop::new(self);

        // SAFETY: for the time of their lifespan, `OwnRef`s point to initialized data
        unsafe { ManuallyDrop::into_inner(NonNull::from_mut(slot.inner).read()) }
    }
}

// SAFETY: `forget_contents` does not drop the `T` instance
const unsafe impl<T: ?Sized> DerefOwn for Own<'_, T> {
    unsafe fn deref_own(self: &mut ManuallyDrop<Self>) -> Own<'_, Self::Target> {
        // SAFETY: caller ensures `self` does not drop its inner value after this
        unsafe { (&raw const **self).read() }
    }

    fn forget_contents(this: MaybeDangling<Self>) {
        forget(this)
    }
}

const impl<'a, T: ?Sized> DerefMut for Own<'a, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut **self.inner
    }
}

// SAFETY: `DerefMut` called upon `OwnRef` performs no mutation, only mutable borrowing
unsafe impl<T: ?Sized> DerefPure for Own<'_, T> {}

//noinspection RsSuperTraitIsNotImplemented
impl<T: ?Sized> !Copy for Own<'_, T> {}

#[cfg(feature = "alloc")]
// TODO: remove the where clause if/when Box's Drop impl becomes const
const unsafe impl<T: ?Sized, A: [const] Allocator> DerefOwn for Box<T, A> where Box<ManuallyDrop<T>, A>: [const] Destruct {

    unsafe fn deref_own(self: &mut ManuallyDrop<Self>) -> Own<'_, Self::Target> {
        // SAFETY: `self` is inhabited as is ensured by the caller, and ManuallyDrop<T> is transparent around T
        unsafe { Own::new(transmute(&mut ***self)) }
    }

    fn forget_contents(this: MaybeDangling<Self>)  {
        // SAFETY: `MaybeDangling` is transparent around `T`, as is `ManuallyDrop`
        drop(unsafe { transmute::<_, Box<ManuallyDrop<T>, A>>(this) })
    }
}

#[cfg(feature = "alloc")]
const impl<T> DerefMove for Box<T> where Box<T>: [const] Destruct {
    fn deref_move(self) -> Self::Target {
        *self
    }
}

#[cfg(feature = "alloc")]
// TODO: remove the where clause if/when Box's Drop impl becomes const
const unsafe impl<T, A: [const] Allocator> DerefOwn for Vec<T, A> where Vec<ManuallyDrop<T>, A>: [const] Destruct {
    unsafe fn deref_own(self: &mut ManuallyDrop<Self>) -> Own<'_, Self::Target> {
        // SAFETY: `self` is inhabited as is ensured by the caller, and ManuallyDrop<T> is transparent around T
        unsafe { Own::new(transmute(&mut ***self)) }
    }

    fn forget_contents(this: MaybeDangling<Self>) {
        // SAFETY: MaybeDangling<T> is transparent around T, as is ManuallyDrop<T>
        drop(unsafe { transmute::<_, Vec<ManuallyDrop<T>, A>>(this) });
    }
}

#[cfg(feature = "alloc")]
// TODO: Make const once String has const methods
unsafe impl DerefOwn for String {
    unsafe fn deref_own(self: &mut ManuallyDrop<Self>) -> Own<'_, Self::Target> {
        // SAFETY: `self` is inhabited as is ensured by the caller, and ManuallyDrop<T> is transparent around T
        unsafe { Own::new(transmute(&mut ***self)) }
    }

    fn forget_contents(this: MaybeDangling<Self>) {
        // SAFETY: MaybeDangling<T> is transparent around T, as is ManuallyDrop<T>
        drop(unsafe { transmute::<_, Vec<ManuallyDrop<u8>>>(this.into_inner().into_bytes()) });
    }
}

pub struct DerefOwnGuard<T: DerefOwn>(ManuallyDrop<T>);
const impl<T: [const] DerefOwn> DerefOwnGuard<T> {
    pub fn new(inner: T) -> Self {
        Self(ManuallyDrop::new(inner))
    }

    pub fn make_own_ref(&mut self) -> Own<'_, <T as Deref>::Target> {
        // SAFETY: via raii ForgetContents will forget the contents of the container
        unsafe { self.0.deref_own() }
    }
}

const impl<T: [const] DerefOwn> Drop for DerefOwnGuard<T> {
    fn drop(&mut self) {
        // SAFETY:
        unsafe { DerefOwn::forget_contents_in_place(&mut self.0) }
    }
}