From 6b1f814ea733699f28d9c60202ab8645cdd1c058 Mon Sep 17 00:00:00 2001 From: Mica White Date: Mon, 8 Dec 2025 20:13:20 -0500 Subject: First commit --- src/lib.rs | 244 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100755 src/lib.rs (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs new file mode 100755 index 0000000..08bc0b7 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,244 @@ +#![no_std] + +extern crate alloc; + +use alloc::boxed::Box; +use alloc::rc::Rc; +use alloc::sync::Arc; +use core::cmp; +use core::fmt::{self, Debug, Display, Pointer}; +use core::hash::{Hash, Hasher}; +use core::ops::{Deref, DerefMut}; + +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct SuperPin { + pointer: Ptr, +} + +#[macro_export] +macro_rules! superpin { + ($value: expr $(,)?) => { + $crate::SuperPin<&mut _> { pointer: &mut { $value } } + }; +} + +impl Debug for SuperPin { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.pointer, f) + } +} + +impl Display for SuperPin { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.pointer, f) + } +} + +impl Pointer for SuperPin { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Pointer::fmt(&self.pointer, f) + } +} + +impl PartialEq> for SuperPin +where + Ptr::Target: PartialEq, +{ + fn eq(&self, other: &SuperPin) -> bool { + Ptr::Target::eq(self, other) + } + + #[allow(clippy::partialeq_ne_impl)] // We need to copy what the Ptr type does + fn ne(&self, other: &SuperPin) -> bool { + Ptr::Target::ne(self, other) + } +} + +impl> Eq for SuperPin {} + +impl PartialOrd> for SuperPin +where + Ptr::Target: PartialOrd, +{ + fn partial_cmp(&self, other: &SuperPin) -> Option { + Ptr::Target::partial_cmp(self, other) + } + + fn lt(&self, other: &SuperPin) -> bool { + Ptr::Target::lt(self, other) + } + + fn le(&self, other: &SuperPin) -> bool { + Ptr::Target::le(self, other) + } + + fn gt(&self, other: &SuperPin) -> bool { + Ptr::Target::gt(self, other) + } + + fn ge(&self, other: &SuperPin) -> bool { + Ptr::Target::ge(self, other) + } +} + +impl> Ord for SuperPin { + fn cmp(&self, other: &Self) -> cmp::Ordering { + Ptr::Target::cmp(self, other) + } +} + +impl Hash for SuperPin +where + ::Target: Hash, +{ + fn hash(&self, state: &mut H) { + self.pointer.hash(state); + } +} + +impl Deref for SuperPin { + type Target = Ptr::Target; + + fn deref(&self) -> &Self::Target { + &self.pointer + } +} + +impl DerefMut for SuperPin { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.pointer + } +} + +impl From> for SuperPin> { + fn from(value: Box) -> Self { + // safety: It's not possible to move or replace the insides of a + // SuperPin>, so it's safe to pin it directly without + // any additional requirements. + unsafe { Self::new_unchecked(value) } + } +} + +impl SuperPin { + pub fn boxed(x: T) -> SuperPin> { + SuperPin::from(Box::new(x)) + } + + pub fn rc(value: T) -> SuperPin> { + // safety: It's not possible to move anything behind an Rc + unsafe { SuperPin::new_unchecked(Rc::new(value)) } + } + + pub fn arc(value: T) -> SuperPin> { + // safety: It's not possible to move anything behind an Arc + unsafe { SuperPin::new_unchecked(Arc::new(value)) } + } +} + +impl SuperPin { + pub unsafe fn new_unchecked(pointer: Ptr) -> Self { + Self { pointer } + } + + pub fn as_ref(&self) -> SuperPin<&::Target> { + // safety: the pointee cannot move while it is pinned + unsafe { SuperPin::new_unchecked(self.pointer.deref()) } + } + + pub unsafe fn into_inner_unchecked(pin: SuperPin) -> Ptr { + // safety: the caller must ensure that the value is not moved + pin.pointer + } +} + +impl SuperPin { + pub fn as_mut(&mut self) -> SuperPin<&mut ::Target> { + // safety: the pointee cannot move while it is pinned + unsafe { SuperPin::new_unchecked(self.pointer.deref_mut()) } + } + + pub fn set(&mut self, value: ::Target) + where + ::Target: Sized, + { + // safety: the destructor is run and a new valid value of the same type is + // put in its place, so no pinning invariant is violated + *self.pointer.deref_mut() = value; + } +} + +impl<'a, T: ?Sized> SuperPin<&'a T> { + pub unsafe fn map_unchecked(self, func: impl FnOnce(&T) -> &U) -> SuperPin<&'a U> { + let new_pointer = func(self.pointer); + + // safety: the caller is responsible for upholding the invariants of + // SuperPin::new_unchecked + unsafe { SuperPin::new_unchecked(new_pointer) } + } + + pub fn get_ref(self) -> &'a T { + // safety: it is impossible to move out of a shared pointer + self.pointer + } +} + +impl<'a, T: ?Sized> SuperPin<&'a mut T> { + pub fn into_ref(self) -> SuperPin<&'a T> { + // safety: it is impossible to move out of a shared pointer + unsafe { SuperPin::new_unchecked(&*self.pointer) } + } + + pub unsafe fn get_unchecked_mut(self) -> &'a mut T { + // safety: the caller must ensure the value is not moved out of the pointer + self.pointer + } + + pub unsafe fn map_unchecked_mut( + self, + func: impl FnOnce(&mut T) -> &mut U, + ) -> SuperPin<&'a mut U> { + let pointer = &mut *self.pointer; + let new_pointer = func(pointer); + + // safety: the caller must uphold the invariants of SuperPin::new_unchecked + unsafe { SuperPin::new_unchecked(new_pointer) } + } +} + +impl SuperPin<&'static T> { + pub fn static_ref(r: &'static T) -> Self { + // safety: T is borrowed for the 'static lifetime, which never ends + unsafe { SuperPin::new_unchecked(r) } + } +} + +impl SuperPin<&'static mut T> { + pub fn static_mut(r: &'static mut T) -> Self { + // safety: T is borrowed for the 'static lifetime, which never ends + unsafe { SuperPin::new_unchecked(r) } + } +} + +impl<'a, T> SuperPin<&'a Option> { + pub fn as_option_ref(self) -> Option> { + unsafe { + SuperPin::get_ref(self) + .as_ref() + // safety: x has to be pinned, because it comes from self + .map(|x| SuperPin::new_unchecked(x)) + } + } +} + +impl<'a, T> SuperPin<&'a mut Option> { + pub fn as_option_mut(self) -> Option> { + unsafe { + // safety: the value is never moved + SuperPin::get_unchecked_mut(self) + .as_mut() + // safety: x has to be pinned, because it comes from self + .map(|x| SuperPin::new_unchecked(x)) + } + } +} -- cgit v1.2.3