expiring_ref 0.7.4

A crate designed to implement a mechanism for owning values, via a destructively-moved equivalent to C++'s xvalues/`T&&`
Documentation
/// Experimental features for this crate.
#[cfg(feature = "unstable_out")]
pub mod out {
	use crate::Own;
	use core::mem::{MaybeUninit, transmute_prefix};
	use core::ptr::NonNull;

	/// For the duration of this value's lifetime, it points to at least partially uninitialized data. However, the location it points to can be considered safely initialized when it is dropped, as dropping without writing to it instantly aborts.
	#[repr(transparent)]
	pub struct Out<'a, T> {
		inner: &'a mut MaybeUninit<T>
	}

	const impl<'a, T> Out<'a, T> {
		fn write(self, val: Own<T>) -> &'a mut T {
			let src: NonNull<T> = unsafe { transmute_prefix(val) };
			let dst = unsafe { NonNull::new_unchecked(self.inner.as_mut_ptr()) };

			unsafe { src.copy_to_nonoverlapping(dst, 1); }
			unsafe { transmute_prefix(self) }
		}

		/// SAFETY: [`self`] must be initialized.
		unsafe fn assume_initialized(self) -> &'a mut T {
			// SAFETY: checks ensured by caller
			unsafe { transmute_prefix(self) }
		}
	}

	impl<'a, T> Drop for Out<'a, T> {
		#[rustc_nounwind]
		fn drop(&mut self) {
			panic!("Out reference was dropped without initialization!")
		}
	}

	#[macro_export]
	macro_rules! let_out {
		(let out $p:pat_param) => {{
			super let __OUT_UNINIT = ::core::mem::MaybeUninit::uninit();
			&mut __OUT_UNINIT
		}};
	}

	pub trait Relocate {
		fn relocate(self: Own<Self>, dst: Out<Self>)
			where
				Self: Sized;
	}

	impl<T> Relocate for T {
		#[inline(always)]
		default fn relocate(self: Own<Self>, dst: Out<Self>) {
			dst.write(self);
		}
	}
}

#[cfg(feature = "unstable_dyn_example")]
/// Proof of concept for an expansion of `dyn Trait` to sorta exist for types with a by-value `self` parameter
pub mod dyn_example {
	use crate::Own;
	use crate::traits::DerefMove;
	use core::marker::PhantomData;
	use core::mem::transmute_prefix;
	use core::ptr::NonNull;

	pub struct Output(usize);

	pub trait X {
		fn do_stuff(self) -> Output;
	}

	struct DynXMeta {
		size: usize,
		do_stuff: unsafe fn(NonNull<()>) -> Output,
	}

	const fn dyn_x_meta<'a, T: X + 'a>() -> &'a DynXMeta {
		&const {
			DynXMeta {
				size: size_of::<T>(),
				do_stuff: unsafe {
					transmute_prefix(do_stuff_through_own_ref::<T> as fn(Own<'a, T>) -> Output)
				}
			}
		}
	}

	fn do_stuff_through_own_ref<T: X>(this: Own<T>) -> Output {
		this.deref_move().do_stuff()
	}

	pub struct OwnDynXPointee<'a> {
		meta: &'a DynXMeta,
		ptr: NonNull<()>,
		phantom: PhantomData<Own<'a, ()>>
	}

	impl<'a> X for OwnDynXPointee<'a> {
		fn do_stuff(self) -> Output {
			unsafe { (self.meta.do_stuff)(self.ptr) }
		}
	}

	impl<'a> OwnDynXPointee<'a> {
		pub const fn of<T: X>(ptr: Own<'a, T>) -> Self {
			Self {
				meta: const { dyn_x_meta::<T>() },
				ptr: unsafe { transmute_prefix(ptr) },
				phantom: PhantomData
			}
		}
	}
}

#[cfg(feature = "unstable_project")]
pub mod project {
	use crate::Own;
	use core::field::Field;
	use core::marker::PhantomData;
	use core::mem::{ManuallyDrop, MaybeDangling};
	use core::ptr::NonNull;

	pub struct CellRef<'a, T: ?Sized> {
		ptr: NonNull<T>,
		phantom: PhantomData<(*mut T, fn(&'a ()) -> &'a ())>,
	}

	impl<'a, T> CellRef<'a, T> {}

	/// SAFETY: the field must be in a valid state and have ownership access AND the field must not already be borrowed
	pub unsafe fn project<F: Field>(from: *mut ManuallyDrop<F::Base>, _: MaybeDangling<&mut F::Type>) -> Own<'_, F::Type> {
		let ptr = from as *mut u8;
		unsafe {
			Own::new(&mut *(ptr.wrapping_add(F::OFFSET) as *mut ManuallyDrop<F::Type>))
		}
	}

	#[cfg(test)]
	mod test {
		use crate::macros::own;
		use crate::traits::DerefMove;
		use crate::unstable::project::project;
		use alloc::boxed::Box;
		use core::field::field_of;
		use core::mem::MaybeDangling;

		struct E {
			x: usize,
			y: Box<bool>,
		}

		#[test]
		fn test_projection() {
			let val = own!(E { x: 10, y: Box::new(false) });
			let inner = val.into_inner();

			let ptr = &raw mut *inner;

			let borrow = &mut **inner;

			// Why, you ask? purely to get the borrow checker to properly act like just the one field is being borrowed.
			let x = unsafe { project::<field_of!(E, x)>(ptr, MaybeDangling::new(&mut borrow.x)) };
			let y = unsafe { project::<field_of!(E, y)>(ptr, MaybeDangling::new(&mut borrow.y)) };

			assert!(x.deref_move() == 10);
			assert!(*y.deref_move() == false);
		}
	}

}

#[cfg(feature = "unstable_box_alias")]
pub mod box_alias {
	use alloc::boxed::Box;
	use core::alloc::{AllocError, Allocator, Layout};
	use core::marker::PhantomData;
	use core::mem::ManuallyDrop;
	use core::ptr::NonNull;

	pub type Own<'a, T: ?Sized> = Box<T, PhantomSlot<'a>>;

	pub struct PhantomSlot<'a>(PhantomData<&'a mut ()>);
	impl<'a> PhantomSlot<'a> {
		/// SAFETY: `val` must be in a valid state
		pub unsafe fn own<T: ?Sized>(val: &'a mut ManuallyDrop<T>) -> crate::Own<'a, T> {
			// SAFETY: this literally cant reallocate lmao also its ensured valid by the caller
			unsafe {
				Box::from_raw_in(&raw mut**val, Self(PhantomData))
			}
		}
	}

	unsafe impl<'a> Allocator for PhantomSlot<'a> {
		/// Don't use this. Instead, transmute a value of type [`&'a mut ManuallyDrop<_>`] into a [`Box<_, PhantomSlot<'a>>`].
		fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
			Err(AllocError)
		}
		unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout) {}
	}
}