@@ -1356,6 +1356,33 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
1356
1356
ptr
1357
1357
}
1358
1358
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
+
1359
1386
/// Provides a raw pointer to the data.
1360
1387
///
1361
1388
/// 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> {
2999
3026
result
3000
3027
}
3001
3028
3002
- /// Consumes the `Weak<T>` and turns it into a raw pointer .
3029
+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator .
3003
3030
///
3004
3031
/// This converts the weak pointer into a raw pointer, while still preserving the ownership of
3005
3032
/// 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 `].
3007
3034
///
3008
3035
/// The same restrictions of accessing the target of the pointer as with
3009
3036
/// [`as_ptr`] apply.
3010
3037
///
3011
3038
/// # Examples
3012
3039
///
3013
3040
/// ```
3041
+ /// #![feature(allocator_api)]
3014
3042
/// use std::rc::{Rc, Weak};
3043
+ /// use std::alloc::System;
3015
3044
///
3016
- /// let strong = Rc::new ("hello".to_owned());
3045
+ /// let strong = Rc::new_in ("hello".to_owned(), System );
3017
3046
/// let weak = Rc::downgrade(&strong);
3018
- /// let raw = weak.into_raw ();
3047
+ /// let ( raw, alloc) = weak.into_raw_with_allocator ();
3019
3048
///
3020
3049
/// assert_eq!(1, Rc::weak_count(&strong));
3021
3050
/// assert_eq!("hello", unsafe { &*raw });
3022
3051
///
3023
- /// drop(unsafe { Weak::from_raw (raw) });
3052
+ /// drop(unsafe { Weak::from_raw_in (raw, alloc ) });
3024
3053
/// assert_eq!(0, Rc::weak_count(&strong));
3025
3054
/// ```
3026
3055
///
3027
- /// [`from_raw `]: Weak::from_raw
3056
+ /// [`from_raw_in `]: Weak::from_raw_in
3028
3057
/// [`as_ptr`]: Weak::as_ptr
3029
3058
#[ inline]
3030
3059
#[ 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 ( ) ) } ;
3035
3065
( result, alloc)
3036
3066
}
3037
3067
0 commit comments