@@ -1311,6 +1311,33 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
1311
1311
ptr
1312
1312
}
1313
1313
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
+
1314
1341
/// Provides a raw pointer to the data.
1315
1342
///
1316
1343
/// 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> {
2917
2944
result
2918
2945
}
2919
2946
2920
- /// Consumes the `Weak<T>` and turns it into a raw pointer .
2947
+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator .
2921
2948
///
2922
2949
/// This converts the weak pointer into a raw pointer, while still preserving the ownership of
2923
2950
/// 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 `].
2925
2952
///
2926
2953
/// The same restrictions of accessing the target of the pointer as with
2927
2954
/// [`as_ptr`] apply.
2928
2955
///
2929
2956
/// # Examples
2930
2957
///
2931
2958
/// ```
2959
+ /// #![feature(allocator_api)]
2932
2960
/// use std::rc::{Rc, Weak};
2961
+ /// use std::alloc::System;
2933
2962
///
2934
- /// let strong = Rc::new ("hello".to_owned());
2963
+ /// let strong = Rc::new_in ("hello".to_owned(), System );
2935
2964
/// let weak = Rc::downgrade(&strong);
2936
- /// let raw = weak.into_raw ();
2965
+ /// let ( raw, alloc) = weak.into_raw_with_allocator ();
2937
2966
///
2938
2967
/// assert_eq!(1, Rc::weak_count(&strong));
2939
2968
/// assert_eq!("hello", unsafe { &*raw });
2940
2969
///
2941
- /// drop(unsafe { Weak::from_raw (raw) });
2970
+ /// drop(unsafe { Weak::from_raw_in (raw, alloc ) });
2942
2971
/// assert_eq!(0, Rc::weak_count(&strong));
2943
2972
/// ```
2944
2973
///
2945
- /// [`from_raw `]: Weak::from_raw
2974
+ /// [`from_raw_in `]: Weak::from_raw_in
2946
2975
/// [`as_ptr`]: Weak::as_ptr
2947
2976
#[ inline]
2948
2977
#[ 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 ( ) ) } ;
2956
2983
( result, alloc)
2957
2984
}
2958
2985
0 commit comments