@@ -84,14 +84,46 @@ impl<T> AtomicCell<T> {
8484 ///
8585 /// assert_eq!(v, 7);
8686 /// ```
87- pub fn into_inner ( self ) -> T {
88- let this = ManuallyDrop :: new ( self ) ;
87+ pub const fn into_inner ( self ) -> T {
88+ // HACK: This is equivalent to transmute_copy by value, but available in const
89+ // context even on older rustc (const transmute_copy requires Rust 1.74), and
90+ // can work around "cannot borrow here, since the borrowed element may contain
91+ // interior mutability" error occurs (until const_refs_to_cell stabilized, i.e.,
92+ // Rust 1.83) when using transmute_copy with generic type in const context
93+ // (because this is a by-value transmutation that doesn't create a reference to
94+ // the source value).
95+ /// # Safety
96+ ///
97+ /// This function has the same safety requirements as [`core::mem::transmute_copy`].
98+ ///
99+ /// Since this is a by-value transmutation, it copies the bits from the source value
100+ /// into the destination value, then forgets the original, as with the [`core::mem::transmute`].
101+ #[ inline]
102+ #[ must_use]
103+ const unsafe fn transmute_copy_by_val < Src , Dst > ( src : Src ) -> Dst {
104+ #[ repr( C ) ]
105+ union ConstHack < Src , Dst > {
106+ src : ManuallyDrop < Src > ,
107+ dst : ManuallyDrop < Dst > ,
108+ }
109+ assert ! ( mem:: size_of:: <Src >( ) >= mem:: size_of:: <Dst >( ) ) ; // assertion copied from transmute_copy
110+ // SAFETY: ConstHack is #[repr(C)] union, and the caller must guarantee that
111+ // transmuting Src to Dst is safe.
112+ ManuallyDrop :: into_inner ( unsafe {
113+ ConstHack :: < Src , Dst > {
114+ src : ManuallyDrop :: new ( src) ,
115+ }
116+ . dst
117+ } )
118+ }
119+
89120 // SAFETY:
121+ // - Self is repr(transparent) over `UnsafeCell<MaybeUninit<T>>` and
122+ // `UnsafeCell<MaybeUninit<T>>` and `T` has the same layout.
90123 // - passing `self` by value guarantees that no other threads are concurrently
91124 // accessing the atomic data
92- // - the raw pointer passed in is valid because we got it from an owned value.
93- // - `ManuallyDrop` prevents double dropping `T`
94- unsafe { this. as_ptr ( ) . read ( ) }
125+ // (Equivalent to UnsafeCell::into_inner which is unstable in const context.)
126+ unsafe { transmute_copy_by_val ( self ) }
95127 }
96128
97129 /// Returns `true` if operations on values of this type are lock-free.
0 commit comments