@@ -1356,6 +1356,33 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
13561356 ptr
13571357 }
13581358
1359+ /// Consumes the `Rc`, returning the wrapped pointer and allocator.
1360+ ///
1361+ /// To avoid a memory leak the pointer must be converted back to an `Rc` using
1362+ /// [`Rc::from_raw_in`].
1363+ ///
1364+ /// # Examples
1365+ ///
1366+ /// ```
1367+ /// #![feature(allocator_api)]
1368+ /// use std::rc::Rc;
1369+ /// use std::alloc::System;
1370+ ///
1371+ /// let x = Rc::new_in("hello".to_owned(), System);
1372+ /// let (ptr, alloc) = Rc::into_raw_with_allocator(x);
1373+ /// assert_eq!(unsafe { &*ptr }, "hello");
1374+ /// let x = unsafe { Rc::from_raw_in(ptr, alloc) };
1375+ /// assert_eq!(&*x, "hello");
1376+ /// ```
1377+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1378+ pub fn into_raw_with_allocator ( this : Self ) -> ( * const T , A ) {
1379+ let this = mem:: ManuallyDrop :: new ( this) ;
1380+ let ptr = Self :: as_ptr ( & this) ;
1381+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1382+ let alloc = unsafe { ptr:: read ( Self :: allocator ( & this) ) } ;
1383+ ( ptr, alloc)
1384+ }
1385+
13591386 /// Provides a raw pointer to the data.
13601387 ///
13611388 /// The counts are not affected in any way and the `Rc` is not consumed. The pointer is valid
@@ -2999,39 +3026,42 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
29993026 result
30003027 }
30013028
3002- /// Consumes the `Weak<T>` and turns it into a raw pointer .
3029+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator .
30033030 ///
30043031 /// This converts the weak pointer into a raw pointer, while still preserving the ownership of
30053032 /// one weak reference (the weak count is not modified by this operation). It can be turned
3006- /// back into the `Weak<T>` with [`from_raw `].
3033+ /// back into the `Weak<T>` with [`from_raw_in `].
30073034 ///
30083035 /// The same restrictions of accessing the target of the pointer as with
30093036 /// [`as_ptr`] apply.
30103037 ///
30113038 /// # Examples
30123039 ///
30133040 /// ```
3041+ /// #![feature(allocator_api)]
30143042 /// use std::rc::{Rc, Weak};
3043+ /// use std::alloc::System;
30153044 ///
3016- /// let strong = Rc::new ("hello".to_owned());
3045+ /// let strong = Rc::new_in ("hello".to_owned(), System );
30173046 /// let weak = Rc::downgrade(&strong);
3018- /// let raw = weak.into_raw ();
3047+ /// let ( raw, alloc) = weak.into_raw_with_allocator ();
30193048 ///
30203049 /// assert_eq!(1, Rc::weak_count(&strong));
30213050 /// assert_eq!("hello", unsafe { &*raw });
30223051 ///
3023- /// drop(unsafe { Weak::from_raw (raw) });
3052+ /// drop(unsafe { Weak::from_raw_in (raw, alloc ) });
30243053 /// assert_eq!(0, Rc::weak_count(&strong));
30253054 /// ```
30263055 ///
3027- /// [`from_raw `]: Weak::from_raw
3056+ /// [`from_raw_in `]: Weak::from_raw_in
30283057 /// [`as_ptr`]: Weak::as_ptr
30293058 #[ inline]
30303059 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
3031- pub fn into_raw_and_alloc ( self ) -> ( * const T , A ) {
3032- let rc = mem:: ManuallyDrop :: new ( self ) ;
3033- let result = rc. as_ptr ( ) ;
3034- let alloc = unsafe { ptr:: read ( & rc. alloc ) } ;
3060+ pub fn into_raw_with_allocator ( self ) -> ( * const T , A ) {
3061+ let this = mem:: ManuallyDrop :: new ( self ) ;
3062+ let result = this. as_ptr ( ) ;
3063+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
3064+ let alloc = unsafe { ptr:: read ( this. allocator ( ) ) } ;
30353065 ( result, alloc)
30363066 }
30373067
0 commit comments