@@ -661,16 +661,6 @@ impl<T> Rc<T> {
661
661
}
662
662
663
663
impl < T , A : Allocator > Rc < T , A > {
664
- /// Returns a reference to the underlying allocator.
665
- ///
666
- /// Note: this is an associated function, which means that you have
667
- /// to call it as `Rc::allocator(&r)` instead of `r.allocator()`. This
668
- /// is so that there is no conflict with a method on the inner type.
669
- #[ inline]
670
- #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
671
- pub fn allocator ( this : & Self ) -> & A {
672
- & this. alloc
673
- }
674
664
/// Constructs a new `Rc` in the provided allocator.
675
665
///
676
666
/// # Examples
@@ -1127,12 +1117,9 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> {
1127
1117
/// ```
1128
1118
#[ unstable( feature = "new_uninit" , issue = "63291" ) ]
1129
1119
#[ inline]
1130
- pub unsafe fn assume_init ( self ) -> Rc < T , A >
1131
- where
1132
- A : Clone ,
1133
- {
1134
- let md_self = mem:: ManuallyDrop :: new ( self ) ;
1135
- unsafe { Rc :: from_inner_in ( md_self. ptr . cast ( ) , md_self. alloc . clone ( ) ) }
1120
+ pub unsafe fn assume_init ( self ) -> Rc < T , A > {
1121
+ let ( ptr, alloc) = Self :: into_raw_with_allocator ( self ) ;
1122
+ unsafe { Rc :: from_raw_in ( ptr. cast ( ) , alloc) }
1136
1123
}
1137
1124
}
1138
1125
@@ -1171,12 +1158,9 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> {
1171
1158
/// ```
1172
1159
#[ unstable( feature = "new_uninit" , issue = "63291" ) ]
1173
1160
#[ inline]
1174
- pub unsafe fn assume_init ( self ) -> Rc < [ T ] , A >
1175
- where
1176
- A : Clone ,
1177
- {
1178
- let md_self = mem:: ManuallyDrop :: new ( self ) ;
1179
- unsafe { Rc :: from_ptr_in ( md_self. ptr . as_ptr ( ) as _ , md_self. alloc . clone ( ) ) }
1161
+ pub unsafe fn assume_init ( self ) -> Rc < [ T ] , A > {
1162
+ let ( ptr, alloc) = Self :: into_raw_with_allocator ( self ) ;
1163
+ unsafe { Rc :: from_raw_in ( ptr as * const [ T ] , alloc) }
1180
1164
}
1181
1165
}
1182
1166
@@ -1315,6 +1299,17 @@ impl<T: ?Sized> Rc<T> {
1315
1299
}
1316
1300
1317
1301
impl < T : ?Sized , A : Allocator > Rc < T , A > {
1302
+ /// Returns a reference to the underlying allocator.
1303
+ ///
1304
+ /// Note: this is an associated function, which means that you have
1305
+ /// to call it as `Rc::allocator(&r)` instead of `r.allocator()`. This
1306
+ /// is so that there is no conflict with a method on the inner type.
1307
+ #[ inline]
1308
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1309
+ pub fn allocator ( this : & Self ) -> & A {
1310
+ & this. alloc
1311
+ }
1312
+
1318
1313
/// Consumes the `Rc`, returning the wrapped pointer.
1319
1314
///
1320
1315
/// To avoid a memory leak the pointer must be converted back to an `Rc` using
@@ -1337,6 +1332,33 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
1337
1332
ptr
1338
1333
}
1339
1334
1335
+ /// Consumes the `Rc`, returning the wrapped pointer and allocator.
1336
+ ///
1337
+ /// To avoid a memory leak the pointer must be converted back to an `Rc` using
1338
+ /// [`Rc::from_raw_in`].
1339
+ ///
1340
+ /// # Examples
1341
+ ///
1342
+ /// ```
1343
+ /// #![feature(allocator_api)]
1344
+ /// use std::rc::Rc;
1345
+ /// use std::alloc::System;
1346
+ ///
1347
+ /// let x = Rc::new_in("hello".to_owned(), System);
1348
+ /// let (ptr, alloc) = Rc::into_raw_with_allocator(x);
1349
+ /// assert_eq!(unsafe { &*ptr }, "hello");
1350
+ /// let x = unsafe { Rc::from_raw_in(ptr, alloc) };
1351
+ /// assert_eq!(&*x, "hello");
1352
+ /// ```
1353
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1354
+ pub fn into_raw_with_allocator ( this : Self ) -> ( * const T , A ) {
1355
+ let this = mem:: ManuallyDrop :: new ( this) ;
1356
+ let ptr = Self :: as_ptr ( & this) ;
1357
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1358
+ let alloc = unsafe { ptr:: read ( Self :: allocator ( & this) ) } ;
1359
+ ( ptr, alloc)
1360
+ }
1361
+
1340
1362
/// Provides a raw pointer to the data.
1341
1363
///
1342
1364
/// The counts are not affected in any way and the `Rc` is not consumed. The pointer is valid
@@ -1790,7 +1812,9 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
1790
1812
// reference to the allocation.
1791
1813
unsafe { & mut this. ptr . as_mut ( ) . value }
1792
1814
}
1815
+ }
1793
1816
1817
+ impl < T : Clone , A : Allocator > Rc < T , A > {
1794
1818
/// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the
1795
1819
/// clone.
1796
1820
///
@@ -1826,7 +1850,7 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
1826
1850
}
1827
1851
}
1828
1852
1829
- impl < A : Allocator + Clone > Rc < dyn Any , A > {
1853
+ impl < A : Allocator > Rc < dyn Any , A > {
1830
1854
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
1831
1855
///
1832
1856
/// # Examples
@@ -1849,12 +1873,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
1849
1873
#[ stable( feature = "rc_downcast" , since = "1.29.0" ) ]
1850
1874
pub fn downcast < T : Any > ( self ) -> Result < Rc < T , A > , Self > {
1851
1875
if ( * self ) . is :: < T > ( ) {
1852
- unsafe {
1853
- let ptr = self . ptr . cast :: < RcBox < T > > ( ) ;
1854
- let alloc = self . alloc . clone ( ) ;
1855
- forget ( self ) ;
1856
- Ok ( Rc :: from_inner_in ( ptr, alloc) )
1857
- }
1876
+ let this = mem:: ManuallyDrop :: new ( self ) ;
1877
+ let ptr = this. ptr . cast :: < RcBox < T > > ( ) ;
1878
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1879
+ let alloc = unsafe { ptr:: read ( & this. alloc ) } ;
1880
+ unsafe { Ok ( Rc :: from_inner_in ( ptr, alloc) ) }
1858
1881
} else {
1859
1882
Err ( self )
1860
1883
}
@@ -1889,12 +1912,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
1889
1912
#[ inline]
1890
1913
#[ unstable( feature = "downcast_unchecked" , issue = "90850" ) ]
1891
1914
pub unsafe fn downcast_unchecked < T : Any > ( self ) -> Rc < T , A > {
1892
- unsafe {
1893
- let ptr = self . ptr . cast :: < RcBox < T > > ( ) ;
1894
- let alloc = self . alloc . clone ( ) ;
1895
- mem:: forget ( self ) ;
1896
- Rc :: from_inner_in ( ptr, alloc)
1897
- }
1915
+ let this = mem:: ManuallyDrop :: new ( self ) ;
1916
+ let ptr = this. ptr . cast :: < RcBox < T > > ( ) ;
1917
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1918
+ let alloc = unsafe { ptr:: read ( & this. alloc ) } ;
1919
+ unsafe { Rc :: from_inner_in ( ptr, alloc) }
1898
1920
}
1899
1921
}
1900
1922
@@ -2639,12 +2661,13 @@ impl From<Rc<str>> for Rc<[u8]> {
2639
2661
}
2640
2662
2641
2663
#[ stable( feature = "boxed_slice_try_from" , since = "1.43.0" ) ]
2642
- impl < T , const N : usize > TryFrom < Rc < [ T ] > > for Rc < [ T ; N ] > {
2643
- type Error = Rc < [ T ] > ;
2664
+ impl < T , A : Allocator , const N : usize > TryFrom < Rc < [ T ] , A > > for Rc < [ T ; N ] , A > {
2665
+ type Error = Rc < [ T ] , A > ;
2644
2666
2645
- fn try_from ( boxed_slice : Rc < [ T ] > ) -> Result < Self , Self :: Error > {
2667
+ fn try_from ( boxed_slice : Rc < [ T ] , A > ) -> Result < Self , Self :: Error > {
2646
2668
if boxed_slice. len ( ) == N {
2647
- Ok ( unsafe { Rc :: from_raw ( Rc :: into_raw ( boxed_slice) as * mut [ T ; N ] ) } )
2669
+ let ( ptr, alloc) = Rc :: into_raw_with_allocator ( boxed_slice) ;
2670
+ Ok ( unsafe { Rc :: from_raw_in ( ptr as * mut [ T ; N ] , alloc) } )
2648
2671
} else {
2649
2672
Err ( boxed_slice)
2650
2673
}
@@ -2897,6 +2920,13 @@ impl<T: ?Sized> Weak<T> {
2897
2920
}
2898
2921
2899
2922
impl < T : ?Sized , A : Allocator > Weak < T , A > {
2923
+ /// Returns a reference to the underlying allocator.
2924
+ #[ inline]
2925
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
2926
+ pub fn allocator ( & self ) -> & A {
2927
+ & self . alloc
2928
+ }
2929
+
2900
2930
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
2901
2931
///
2902
2932
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
@@ -2974,42 +3004,42 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
2974
3004
result
2975
3005
}
2976
3006
2977
- /// Consumes the `Weak<T>` and turns it into a raw pointer .
3007
+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator .
2978
3008
///
2979
3009
/// This converts the weak pointer into a raw pointer, while still preserving the ownership of
2980
3010
/// one weak reference (the weak count is not modified by this operation). It can be turned
2981
- /// back into the `Weak<T>` with [`from_raw `].
3011
+ /// back into the `Weak<T>` with [`from_raw_in `].
2982
3012
///
2983
3013
/// The same restrictions of accessing the target of the pointer as with
2984
3014
/// [`as_ptr`] apply.
2985
3015
///
2986
3016
/// # Examples
2987
3017
///
2988
3018
/// ```
3019
+ /// #![feature(allocator_api)]
2989
3020
/// use std::rc::{Rc, Weak};
3021
+ /// use std::alloc::System;
2990
3022
///
2991
- /// let strong = Rc::new ("hello".to_owned());
3023
+ /// let strong = Rc::new_in ("hello".to_owned(), System );
2992
3024
/// let weak = Rc::downgrade(&strong);
2993
- /// let raw = weak.into_raw ();
3025
+ /// let ( raw, alloc) = weak.into_raw_with_allocator ();
2994
3026
///
2995
3027
/// assert_eq!(1, Rc::weak_count(&strong));
2996
3028
/// assert_eq!("hello", unsafe { &*raw });
2997
3029
///
2998
- /// drop(unsafe { Weak::from_raw (raw) });
3030
+ /// drop(unsafe { Weak::from_raw_in (raw, alloc ) });
2999
3031
/// assert_eq!(0, Rc::weak_count(&strong));
3000
3032
/// ```
3001
3033
///
3002
- /// [`from_raw `]: Weak::from_raw
3034
+ /// [`from_raw_in `]: Weak::from_raw_in
3003
3035
/// [`as_ptr`]: Weak::as_ptr
3004
3036
#[ inline]
3005
3037
#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
3006
- pub fn into_raw_and_alloc ( self ) -> ( * const T , A )
3007
- where
3008
- A : Clone ,
3009
- {
3010
- let result = self . as_ptr ( ) ;
3011
- let alloc = self . alloc . clone ( ) ;
3012
- mem:: forget ( self ) ;
3038
+ pub fn into_raw_with_allocator ( self ) -> ( * const T , A ) {
3039
+ let this = mem:: ManuallyDrop :: new ( self ) ;
3040
+ let result = this. as_ptr ( ) ;
3041
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
3042
+ let alloc = unsafe { ptr:: read ( this. allocator ( ) ) } ;
3013
3043
( result, alloc)
3014
3044
}
3015
3045
0 commit comments