@@ -1311,6 +1311,33 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
13111311 ptr
13121312 }
13131313
1314+ /// Consumes the `Rc`, returning the wrapped pointer and allocator.
1315+ ///
1316+ /// To avoid a memory leak the pointer must be converted back to an `Rc` using
1317+ /// [`Rc::from_raw_in`].
1318+ ///
1319+ /// # Examples
1320+ ///
1321+ /// ```
1322+ /// #![feature(allocator_api)]
1323+ /// use std::rc::Rc;
1324+ /// use std::alloc::System;
1325+ ///
1326+ /// let x = Rc::new_in("hello".to_owned(), System);
1327+ /// let (ptr, alloc) = Rc::into_raw_with_allocator(x);
1328+ /// assert_eq!(unsafe { &*x }, "hello");
1329+ /// let x = unsafe { Rc::from_raw_in(ptr, alloc) };
1330+ /// assert_eq!(&*x, "hello");
1331+ /// ```
1332+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1333+ pub fn into_raw_with_allocator ( this : Self ) -> ( * const T , A ) {
1334+ let this = mem:: ManuallyDrop :: new ( this) ;
1335+ let ptr = Self :: as_ptr ( & this) ;
1336+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1337+ let alloc = unsafe { ptr:: read ( Self :: allocator ( & this) ) } ;
1338+ ( ptr, alloc)
1339+ }
1340+
13141341 /// Provides a raw pointer to the data.
13151342 ///
13161343 /// The counts are not affected in any way and the `Rc` is not consumed. The pointer is valid
@@ -2917,42 +2944,42 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
29172944 result
29182945 }
29192946
2920- /// Consumes the `Weak<T>` and turns it into a raw pointer .
2947+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator .
29212948 ///
29222949 /// This converts the weak pointer into a raw pointer, while still preserving the ownership of
29232950 /// one weak reference (the weak count is not modified by this operation). It can be turned
2924- /// back into the `Weak<T>` with [`from_raw `].
2951+ /// back into the `Weak<T>` with [`from_raw_in `].
29252952 ///
29262953 /// The same restrictions of accessing the target of the pointer as with
29272954 /// [`as_ptr`] apply.
29282955 ///
29292956 /// # Examples
29302957 ///
29312958 /// ```
2959+ /// #![feature(allocator_api)]
29322960 /// use std::rc::{Rc, Weak};
2961+ /// use std::alloc::System;
29332962 ///
2934- /// let strong = Rc::new ("hello".to_owned());
2963+ /// let strong = Rc::new_in ("hello".to_owned(), System );
29352964 /// let weak = Rc::downgrade(&strong);
2936- /// let raw = weak.into_raw ();
2965+ /// let ( raw, alloc) = weak.into_raw_with_allocator ();
29372966 ///
29382967 /// assert_eq!(1, Rc::weak_count(&strong));
29392968 /// assert_eq!("hello", unsafe { &*raw });
29402969 ///
2941- /// drop(unsafe { Weak::from_raw (raw) });
2970+ /// drop(unsafe { Weak::from_raw_in (raw, alloc ) });
29422971 /// assert_eq!(0, Rc::weak_count(&strong));
29432972 /// ```
29442973 ///
2945- /// [`from_raw `]: Weak::from_raw
2974+ /// [`from_raw_in `]: Weak::from_raw_in
29462975 /// [`as_ptr`]: Weak::as_ptr
29472976 #[ inline]
29482977 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
2949- pub fn into_raw_and_alloc ( self ) -> ( * const T , A )
2950- where
2951- A : Clone ,
2952- {
2953- let result = self . as_ptr ( ) ;
2954- let alloc = self . alloc . clone ( ) ;
2955- mem:: forget ( self ) ;
2978+ pub fn into_raw_with_allocator ( self ) -> ( * const T , A ) {
2979+ let this = mem:: ManuallyDrop :: new ( self ) ;
2980+ let result = this. as_ptr ( ) ;
2981+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
2982+ let alloc = unsafe { ptr:: read ( this. allocator ( ) ) } ;
29562983 ( result, alloc)
29572984 }
29582985
0 commit comments