| 
253 | 253 | use crate::cmp::Ordering;  | 
254 | 254 | use crate::fmt::{self, Debug, Display};  | 
255 | 255 | use crate::marker::{PhantomData, Unsize};  | 
256 |  | -use crate::mem;  | 
257 |  | -use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};  | 
 | 256 | +use crate::mem::{self, ManuallyDrop};  | 
 | 257 | +use crate::ops::{self, CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};  | 
258 | 258 | use crate::panic::const_panic;  | 
259 | 259 | use crate::pin::PinCoerceUnsized;  | 
260 | 260 | use crate::ptr::{self, NonNull};  | 
 | 261 | +use crate::range;  | 
261 | 262 | 
 
  | 
262 | 263 | mod lazy;  | 
263 | 264 | mod once;  | 
@@ -713,6 +714,93 @@ impl<T, const N: usize> Cell<[T; N]> {  | 
713 | 714 |     }  | 
714 | 715 | }  | 
715 | 716 | 
 
  | 
 | 717 | +/// Types for which cloning `Cell<Self>` is sound.  | 
 | 718 | +///  | 
 | 719 | +/// # Safety  | 
 | 720 | +///  | 
 | 721 | +/// Implementing this trait for a type is sound if and only if the following code is sound for T =  | 
 | 722 | +/// that type.  | 
 | 723 | +///  | 
 | 724 | +/// ```  | 
 | 725 | +/// #![feature(cell_get_cloned)]  | 
 | 726 | +/// # use std::cell::{CloneFromCell, Cell};  | 
 | 727 | +/// fn clone_from_cell<T: CloneFromCell>(cell: &Cell<T>) -> T {  | 
 | 728 | +///     unsafe { T::clone(&*cell.as_ptr()) }  | 
 | 729 | +/// }  | 
 | 730 | +/// ```  | 
 | 731 | +///  | 
 | 732 | +/// Importantly, you can't just implement `CloneFromCell` for any arbitrary `Copy` type, e.g. the  | 
 | 733 | +/// following is unsound:  | 
 | 734 | +///  | 
 | 735 | +/// ```rust  | 
 | 736 | +/// #![feature(cell_get_cloned)]  | 
 | 737 | +/// # use std::cell::Cell;  | 
 | 738 | +///  | 
 | 739 | +/// #[derive(Copy, Debug)]  | 
 | 740 | +/// pub struct Bad<'a>(Option<&'a Cell<Bad<'a>>>, u8);  | 
 | 741 | +///  | 
 | 742 | +/// impl Clone for Bad<'_> {  | 
 | 743 | +///     fn clone(&self) -> Self {  | 
 | 744 | +///         let a: &u8 = &self.1;  | 
 | 745 | +///         // when self.0 points to self, we write to self.1 while we have a live `&u8` pointing to  | 
 | 746 | +///         // it -- this is UB  | 
 | 747 | +///         self.0.unwrap().set(Self(None, 1));  | 
 | 748 | +///         dbg!((a, self));  | 
 | 749 | +///         Self(None, 0)  | 
 | 750 | +///     }  | 
 | 751 | +/// }  | 
 | 752 | +///  | 
 | 753 | +/// // this is not sound  | 
 | 754 | +/// // unsafe impl CloneFromCell for Bad<'_> {}  | 
 | 755 | +/// ```  | 
 | 756 | +#[unstable(feature = "cell_get_cloned", issue = "145329")]  | 
 | 757 | +// Allow potential overlapping implementations in user code  | 
 | 758 | +#[marker]  | 
 | 759 | +pub unsafe trait CloneFromCell: Clone {}  | 
 | 760 | + | 
 | 761 | +// `CloneFromCell` can be implemented for types that don't have indirection and which don't access  | 
 | 762 | +// `Cell`s in their `Clone` implementation. A commonly-used subset is covered here.  | 
 | 763 | +#[unstable(feature = "cell_get_cloned", issue = "145329")]  | 
 | 764 | +unsafe impl<T: CloneFromCell, const N: usize> CloneFromCell for [T; N] {}  | 
 | 765 | +#[unstable(feature = "cell_get_cloned", issue = "145329")]  | 
 | 766 | +unsafe impl<T: CloneFromCell> CloneFromCell for Option<T> {}  | 
 | 767 | +#[unstable(feature = "cell_get_cloned", issue = "145329")]  | 
 | 768 | +unsafe impl<T: CloneFromCell, E: CloneFromCell> CloneFromCell for Result<T, E> {}  | 
 | 769 | +#[unstable(feature = "cell_get_cloned", issue = "145329")]  | 
 | 770 | +unsafe impl<T: ?Sized> CloneFromCell for PhantomData<T> {}  | 
 | 771 | +#[unstable(feature = "cell_get_cloned", issue = "145329")]  | 
 | 772 | +unsafe impl<T: CloneFromCell> CloneFromCell for ManuallyDrop<T> {}  | 
 | 773 | +#[unstable(feature = "cell_get_cloned", issue = "145329")]  | 
 | 774 | +unsafe impl<T: CloneFromCell> CloneFromCell for ops::Range<T> {}  | 
 | 775 | +#[unstable(feature = "cell_get_cloned", issue = "145329")]  | 
 | 776 | +unsafe impl<T: CloneFromCell> CloneFromCell for range::Range<T> {}  | 
 | 777 | + | 
 | 778 | +#[unstable(feature = "cell_get_cloned", issue = "145329")]  | 
 | 779 | +impl<T: CloneFromCell> Cell<T> {  | 
 | 780 | +    /// Get a clone of the `Cell` that contains a copy of the original value.  | 
 | 781 | +    ///  | 
 | 782 | +    /// This allows a cheaply `Clone`-able type like an `Rc` to be stored in a `Cell`, exposing the  | 
 | 783 | +    /// cheaper `clone()` method.  | 
 | 784 | +    ///  | 
 | 785 | +    /// # Examples  | 
 | 786 | +    ///  | 
 | 787 | +    /// ```  | 
 | 788 | +    /// #![feature(cell_get_cloned)]  | 
 | 789 | +    ///  | 
 | 790 | +    /// use core::cell::Cell;  | 
 | 791 | +    /// use std::rc::Rc;  | 
 | 792 | +    ///  | 
 | 793 | +    /// let rc = Rc::new(1usize);  | 
 | 794 | +    /// let c1 = Cell::new(rc);  | 
 | 795 | +    /// let c2 = c1.get_cloned();  | 
 | 796 | +    /// assert_eq!(*c2.into_inner(), 1);  | 
 | 797 | +    /// ```  | 
 | 798 | +    pub fn get_cloned(&self) -> Self {  | 
 | 799 | +        // SAFETY: T is CloneFromCell, which guarantees that this is sound.  | 
 | 800 | +        Cell::new(T::clone(unsafe { &*self.as_ptr() }))  | 
 | 801 | +    }  | 
 | 802 | +}  | 
 | 803 | + | 
716 | 804 | /// A mutable memory location with dynamically checked borrow rules  | 
717 | 805 | ///  | 
718 | 806 | /// See the [module-level documentation](self) for more.  | 
 | 
0 commit comments