#![no_std] use alloc::sync::Arc; use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull}; extern crate alloc; /// BorrowedArc is a wrapper around `Arc` that allows us to create an `Arc` from a raw pointer /// that was created by `Arc::into_raw` when we are confident about that the original `Arc` /// would be still valid during the whold lifetime of `BorrowedArc`. /// /// # Example /// /// ```should_run /// use pointers::BorrowedArc; /// use alloc::sync::Arc; /// /// let arc = Arc::new(42); /// let ptr = NonNull::new(Arc::into_raw(arc.clone())).unwrap(); /// /// // We know that the original `Arc` is still valid. /// let borrowed_arc = unsafe { BorrowedArc::from_raw(ptr) }; /// /// let arc_reference: &Arc = &borrowed_arc; /// assert_eq!(**arc_reference, 42); /// ``` pub struct BorrowedArc<'a, T: ?Sized> { arc: ManuallyDrop>, _phantom: PhantomData<&'a ()>, } impl<'a, T: ?Sized> BorrowedArc<'a, T> { /// # Safety /// If `ptr` is not a valid pointer to an `Arc`, this will lead to undefined behavior. /// /// If the `Arc` is dropped while `BorrowedArc` is still in use, this will lead /// to undefined behavior. pub unsafe fn from_raw(ptr: NonNull) -> Self { Self { arc: ManuallyDrop::new(unsafe { Arc::from_raw(ptr.as_ptr()) }), _phantom: PhantomData, } } pub fn new(ptr: &'a Arc) -> Self { Self { arc: ManuallyDrop::new(unsafe { core::mem::transmute_copy(ptr) }), _phantom: PhantomData, } } pub fn borrow(&self) -> &'a T { let reference: &T = &self.arc; let ptr = reference as *const T; // SAFETY: `ptr` is a valid pointer to `T` because `reference` is a valid reference to `T`. // `ptr` is also guaranteed to be valid for the lifetime `'lt` because it is derived from // `self.arc` which is guaranteed to be valid for the lifetime `'lt`. unsafe { ptr.as_ref().unwrap() } } } impl<'a, T: ?Sized> Deref for BorrowedArc<'a, T> { type Target = Arc; fn deref(&self) -> &Self::Target { &self.arc } } impl<'a, T: ?Sized> AsRef> for BorrowedArc<'a, T> { fn as_ref(&self) -> &Arc { &self.arc } }