|
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; |
@@ -712,6 +713,78 @@ impl<T, const N: usize> Cell<[T; N]> { |
712 | 713 | } |
713 | 714 | } |
714 | 715 |
|
| 716 | +/// Safety: can call `Self::clone(&*ManuallyDrop::new(ptr::read(ptr_to_self)))` |
| 717 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 718 | +#[marker] |
| 719 | +pub unsafe trait CloneFromCopy: Clone {} |
| 720 | + |
| 721 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 722 | +unsafe impl<T: Copy> CloneFromCopy for T {} |
| 723 | + |
| 724 | +// basically all std types that don't have indirection: |
| 725 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 726 | +unsafe impl<T: CloneFromCopy, const N: usize> CloneFromCopy for [T; N] {} |
| 727 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 728 | +unsafe impl<T: CloneFromCopy> CloneFromCopy for Option<T> {} |
| 729 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 730 | +unsafe impl<T: CloneFromCopy, E: CloneFromCopy> CloneFromCopy for Result<T, E> {} |
| 731 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 732 | +unsafe impl<T: CloneFromCopy> CloneFromCopy for PhantomData<T> {} |
| 733 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 734 | +unsafe impl<T: CloneFromCopy> CloneFromCopy for ManuallyDrop<T> {} |
| 735 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 736 | +unsafe impl<T: CloneFromCopy> CloneFromCopy for ops::Range<T> {} |
| 737 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 738 | +unsafe impl<T: CloneFromCopy> CloneFromCopy for range::Range<T> {} |
| 739 | + |
| 740 | +macro_rules! impl_tuple { |
| 741 | + () => { |
| 742 | + #[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 743 | + unsafe impl CloneFromCopy for () {} |
| 744 | + }; |
| 745 | + ($($name:ident)+) => { |
| 746 | + #[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 747 | + unsafe impl<$($name: CloneFromCopy,)+> CloneFromCopy for ($($name,)+) {} |
| 748 | + } |
| 749 | +} |
| 750 | + |
| 751 | +impl_tuple! {} |
| 752 | +impl_tuple! { T } |
| 753 | +impl_tuple! { T B } |
| 754 | +impl_tuple! { T B C } |
| 755 | +impl_tuple! { T B C D } |
| 756 | +impl_tuple! { T B C D E } |
| 757 | +impl_tuple! { T B C D E F } |
| 758 | +impl_tuple! { T B C D E F G } |
| 759 | +impl_tuple! { T B C D E F G H } |
| 760 | +impl_tuple! { T B C D E F G H I } |
| 761 | +impl_tuple! { T B C D E F G H I J } |
| 762 | +impl_tuple! { T B C D E F G H I J K } |
| 763 | +impl_tuple! { T B C D E F G H I J K L } |
| 764 | + |
| 765 | +#[unstable(feature = "cell_get_cloned", issue = "145329")] |
| 766 | +impl<T: CloneFromCopy> Cell<T> { |
| 767 | + /// Get a clone of the Cell that contains a copy of the original value. |
| 768 | + /// |
| 769 | + /// # Examples |
| 770 | + /// |
| 771 | + /// ``` |
| 772 | + /// #![feature(cell_get_cloned)] |
| 773 | + /// |
| 774 | + /// use core::cell::Cell; |
| 775 | + /// |
| 776 | + /// let o = Some(1usize); |
| 777 | + /// let c1 = Cell::new(o); |
| 778 | + /// let c2 = c1.get_cloned(); |
| 779 | + /// assert_eq!(c2.into_inner(), Some(1)); |
| 780 | + /// ``` |
| 781 | + pub fn get_cloned(&self) -> Self { |
| 782 | + // SAFETY: T is CloneFromCopy, which guarantees that this is sound. |
| 783 | + let copy = ManuallyDrop::new(unsafe { self.as_ptr().read() }); |
| 784 | + Cell::new(T::clone(&*copy)) |
| 785 | + } |
| 786 | +} |
| 787 | + |
715 | 788 | /// A mutable memory location with dynamically checked borrow rules |
716 | 789 | /// |
717 | 790 | /// See the [module-level documentation](self) for more. |
|
0 commit comments