Overview
Welcome to TotallySafe, the Rust library that lets you boldly go where no safe code has gone
before-—all without a single unsafe block!
Features
- Arbitrary lifetimes: Get references with any lifetime you like. Who's to say what's 'correct'?
- Multiple Mutable References & Aliasing: Why settle for one mutable reference when you can have an array of them?
- Type Transmutation: Convert any type into any other type. After all, types are just labels.
- Fearless Copy: Byte-wise copy your objects without the need to implement
CloneandCopy.
Usage
Add totally_safe to your Cargo.toml:
[dependencies] totally_safe = "0.1.1"
Bring the trait into scope:
use totally_safe::TotallySafe; fn main() { let mut value = Box::new(100); let copied = value.copy(); // malloc: Double free of object }
API Documentation
Here's a closer look at what TotallySafe offers.
Feel free to copy this into your project!
pub trait TotallySafe { fn alias_mut<'x, 'any>(&'x mut self) -> &'any mut Self { (((|inc, _| inc) as for<'a, 'b> fn(&'b mut Self, &'a &'b ()) -> &'a mut Self) as for<'a, 'b> fn(&'x mut Self, &'a &'b ()) -> &'a mut Self)(self, &&()) } fn alias_mut_array<'x, 'any, const N: usize>(&'x mut self) -> [&'any mut Self; N] { core::array::from_fn(|_| self.alias_mut()) } fn transmute_into<B>(self) -> B where Self: Sized, { let mut data = Err::<Result<Self, u8>, Result<B, u8>>(Err(84)); let result_b = data.alias_mut().as_mut().err().unwrap(); *data.alias_mut() = Ok(Ok(self)); core::mem::replace(result_b, Err(83)).ok().unwrap() } fn copy_raw(&self) -> Self where Self: Sized, { let mut destination = core::mem::MaybeUninit::<Self>::uninit(); for offset in 0..core::mem::size_of::<Self>() { *destination .as_mut_ptr() .cast::<core::mem::MaybeUninit<u8>>() .wrapping_add(offset) .transmute_into::<&mut core::mem::MaybeUninit<u8>>() = *core::ptr::from_ref(self) .cast::<core::mem::MaybeUninit<u8>>() .wrapping_add(offset) .transmute_into::<&core::mem::MaybeUninit<u8>>() } destination.transmute_into::<Self>() } } impl<T: ?Sized> TotallySafe for T {}
Old trait with docs
pub trait TotallySafe { /// Returns a reference to `self` with an arbitrary lifetime. /// /// This method allows you to obtain a reference to `self` that is bound /// to any given lifetime. It can be useful when you need to coerce /// a reference to have a different lifetime in certain contexts. /// /// # Example /// /// ```rust /// let instance = MyType::new(); /// let any_lifetime_ref: &MyType = instance.as_ref_alias(); /// // `any_lifetime_ref` now has an arbitrary lifetime. /// ``` fn as_ref_alias<'x, 'any>(&'x self) -> &'any Self { (((|inc, _| inc) as for<'a, 'b> fn(&'b Self, &'a &'b ()) -> &'a Self) as for<'a, 'b> fn(&'x Self, &'a &'b ()) -> &'a Self)(self, &&()) } /// Returns a mutable reference to `self` with an arbitrary lifetime. /// /// This method allows you to obtain a mutable reference to `self` that is bound /// to any given lifetime. It's useful when you need to coerce /// a mutable reference to have a different lifetime in certain situations. /// /// # Example /// /// ```rust /// let mut instance = MyType::new(); /// let any_lifetime_mut_ref: &mut MyType = instance.as_mut_alias(); /// // `any_lifetime_mut_ref` now has an arbitrary lifetime. /// ``` fn as_mut_alias<'x, 'any>(&'x mut self) -> &'any mut Self { (((|inc, _| inc) as for<'a, 'b> fn(&'b mut Self, &'a &'b ()) -> &'a mut Self) as for<'a, 'b> fn(&'x mut Self, &'a &'b ()) -> &'a mut Self)(self, &&()) } /// Returns an array of mutable references to `self`. /// /// This method allows you to obtain an array of `N` mutable references to `self`. /// It's perfect for those times when one mutable reference just isn't enough! /// Now you can be in multiple places at once (well, sort of). /// /// # Example /// /// ```rust /// fn mutate(q: &mut MyType, w: &mut MyType) { *q = w.copy() } /// /// let mut instance = MyType::new(); /// let [a, b] = instance.as_mut_alias_array(); /// /// mutate(a, b); /// /// ``` fn as_mut_alias_array<'x, 'any, const N: usize>(&'x mut self) -> [&'any mut Self; N] { core::array::from_fn(|_| self.as_mut_alias()) } /// Converts `self` into an instance of type `B`. /// /// This method consumes `self` and transforms it into a value of type `B`. /// It's particularly useful when you need to change the type of an object /// while retaining the underlying data in a compatible form. /// /// # Example /// /// ```rust /// let instance = MyType::new(); /// let other_instance: OtherType = instance.transmute_into(); /// // `other_instance` is now of type `OtherType`. /// ``` fn transmute_into<B>(self) -> B where Self: Sized, { let mut data = Err::<Result<Self, u8>, Result<B, u8>>(Err(0)); let result_b = data.as_mut_alias().as_mut().err().unwrap(); *data.as_mut_alias() = Ok(Ok(self)); core::mem::replace(result_b, Err(0)).ok().unwrap() } /// Creates a copy of `self` by duplicating its raw bytes. /// /// This method generates a new instance of `Self` by performing a byte-wise copy /// of the original object. It's particularly useful when you need to create a /// duplicate of an object without relying on the `Clone` trait, or when dealing /// with types that do not implement `Clone`. /// /// # Example /// /// ```rust /// let mut instance = MyType::new(); /// let copy = instance.copy_raw(); /// // `copy` is now a duplicate of `instance`. /// ``` fn copy_raw(&self) -> Self where Self: Sized, { let mut destination = core::mem::MaybeUninit::<Self>::uninit(); for offset in 0..core::mem::size_of::<Self>() { *destination .as_mut_ptr() .cast::<core::mem::MaybeUninit<u8>>() .wrapping_add(offset) .transmute_into::<&mut core::mem::MaybeUninit<u8>>() = *core::ptr::from_ref(self) .cast::<core::mem::MaybeUninit<u8>>() .wrapping_add(offset) .transmute_into::<&core::mem::MaybeUninit<u8>>() } destination.transmute_into::<Self>() } fn copy(&mut self) -> Self where Self: Sized, { let mut destination = core::mem::MaybeUninit::<Self>::uninit(); core::ptr::slice_from_raw_parts_mut( destination .as_mut_ptr() .cast::<core::mem::MaybeUninit<u8>>(), core::mem::size_of::<Self>(), ) .transmute_into::<&'static mut [core::mem::MaybeUninit<u8>]>() .copy_from_slice( core::ptr::slice_from_raw_parts( core::ptr::from_ref(self).cast::<core::mem::MaybeUninit<u8>>(), core::mem::size_of::<Self>(), ) .transmute_into::<&'static [core::mem::MaybeUninit<u8>]>(), ); *destination .as_mut_ptr() .cast::<Self>() .transmute_into::<Box<Self>>() } } impl<T: ?Sized> TotallySafe for T {}
License
You may use this library freely at your own risk, with no warranty, express or implied, and the authors are not liable for any damage or unintended consequences.