@@ -1489,6 +1489,34 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
14891489 ptr
14901490 }
14911491
1492+ /// Consumes the `Arc`, returning the wrapped pointer and allocator.
1493+ ///
1494+ /// To avoid a memory leak the pointer must be converted back to an `Arc` using
1495+ /// [`Arc::from_raw_in`].
1496+ ///
1497+ /// # Examples
1498+ ///
1499+ /// ```
1500+ /// #![feature(allocator_api)]
1501+ /// use std::sync::Arc;
1502+ /// use std::alloc::System;
1503+ ///
1504+ /// let x = Arc::new_in("hello".to_owned(), System);
1505+ /// let (ptr, alloc) = Arc::into_raw_with_allocator(x);
1506+ /// assert_eq!(unsafe { &*ptr }, "hello");
1507+ /// let x = unsafe { Arc::from_raw_in(ptr, alloc) };
1508+ /// assert_eq!(&*x, "hello");
1509+ /// ```
1510+ #[ must_use = "losing the pointer will leak memory" ]
1511+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1512+ pub fn into_raw_with_allocator ( this : Self ) -> ( * const T , A ) {
1513+ let this = mem:: ManuallyDrop :: new ( this) ;
1514+ let ptr = Self :: as_ptr ( & this) ;
1515+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1516+ let alloc = unsafe { ptr:: read ( Self :: allocator ( & this) ) } ;
1517+ ( ptr, alloc)
1518+ }
1519+
14921520 /// Provides a raw pointer to the data.
14931521 ///
14941522 /// The counts are not affected in any way and the `Arc` is not consumed. The pointer is valid for
@@ -2724,6 +2752,45 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
27242752 result
27252753 }
27262754
2755+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator.
2756+ ///
2757+ /// This converts the weak pointer into a raw pointer, while still preserving the ownership of
2758+ /// one weak reference (the weak count is not modified by this operation). It can be turned
2759+ /// back into the `Weak<T>` with [`from_raw_in`].
2760+ ///
2761+ /// The same restrictions of accessing the target of the pointer as with
2762+ /// [`as_ptr`] apply.
2763+ ///
2764+ /// # Examples
2765+ ///
2766+ /// ```
2767+ /// #![feature(allocator_api)]
2768+ /// use std::sync::{Arc, Weak};
2769+ /// use std::alloc::System;
2770+ ///
2771+ /// let strong = Arc::new_in("hello".to_owned(), System);
2772+ /// let weak = Arc::downgrade(&strong);
2773+ /// let (raw, alloc) = weak.into_raw_with_allocator();
2774+ ///
2775+ /// assert_eq!(1, Arc::weak_count(&strong));
2776+ /// assert_eq!("hello", unsafe { &*raw });
2777+ ///
2778+ /// drop(unsafe { Weak::from_raw_in(raw, alloc) });
2779+ /// assert_eq!(0, Arc::weak_count(&strong));
2780+ /// ```
2781+ ///
2782+ /// [`from_raw_in`]: Weak::from_raw_in
2783+ /// [`as_ptr`]: Weak::as_ptr
2784+ #[ must_use = "losing the pointer will leak memory" ]
2785+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
2786+ pub fn into_raw_with_allocator ( self ) -> ( * const T , A ) {
2787+ let this = mem:: ManuallyDrop :: new ( self ) ;
2788+ let result = this. as_ptr ( ) ;
2789+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
2790+ let alloc = unsafe { ptr:: read ( Self :: allocator ( & this) ) } ;
2791+ ( result, alloc)
2792+ }
2793+
27272794 /// Converts a raw pointer previously created by [`into_raw`] back into `Weak<T>` in the provided
27282795 /// allocator.
27292796 ///
0 commit comments