@@ -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
@@ -1293,6 +1277,17 @@ impl<T: ?Sized> Rc<T> {
1293
1277
}
1294
1278
1295
1279
impl < T : ?Sized , A : Allocator > Rc < T , A > {
1280
+ /// Returns a reference to the underlying allocator.
1281
+ ///
1282
+ /// Note: this is an associated function, which means that you have
1283
+ /// to call it as `Rc::allocator(&r)` instead of `r.allocator()`. This
1284
+ /// is so that there is no conflict with a method on the inner type.
1285
+ #[ inline]
1286
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1287
+ pub fn allocator ( this : & Self ) -> & A {
1288
+ & this. alloc
1289
+ }
1290
+
1296
1291
/// Consumes the `Rc`, returning the wrapped pointer.
1297
1292
///
1298
1293
/// To avoid a memory leak the pointer must be converted back to an `Rc` using
@@ -1315,6 +1310,33 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
1315
1310
ptr
1316
1311
}
1317
1312
1313
+ /// Consumes the `Rc`, returning the wrapped pointer and allocator.
1314
+ ///
1315
+ /// To avoid a memory leak the pointer must be converted back to an `Rc` using
1316
+ /// [`Rc::from_raw_in`].
1317
+ ///
1318
+ /// # Examples
1319
+ ///
1320
+ /// ```
1321
+ /// #![feature(allocator_api)]
1322
+ /// use std::rc::Rc;
1323
+ /// use std::alloc::System;
1324
+ ///
1325
+ /// let x = Rc::new_in("hello".to_owned(), System);
1326
+ /// let (ptr, alloc) = Rc::into_raw_with_allocator(x);
1327
+ /// assert_eq!(unsafe { &*ptr }, "hello");
1328
+ /// let x = unsafe { Rc::from_raw_in(ptr, alloc) };
1329
+ /// assert_eq!(&*x, "hello");
1330
+ /// ```
1331
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1332
+ pub fn into_raw_with_allocator ( this : Self ) -> ( * const T , A ) {
1333
+ let this = mem:: ManuallyDrop :: new ( this) ;
1334
+ let ptr = Self :: as_ptr ( & this) ;
1335
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1336
+ let alloc = unsafe { ptr:: read ( Self :: allocator ( & this) ) } ;
1337
+ ( ptr, alloc)
1338
+ }
1339
+
1318
1340
/// Provides a raw pointer to the data.
1319
1341
///
1320
1342
/// The counts are not affected in any way and the `Rc` is not consumed. The pointer is valid
@@ -1742,7 +1764,9 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
1742
1764
// reference to the allocation.
1743
1765
unsafe { & mut this. ptr . as_mut ( ) . value }
1744
1766
}
1767
+ }
1745
1768
1769
+ impl < T : Clone , A : Allocator > Rc < T , A > {
1746
1770
/// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the
1747
1771
/// clone.
1748
1772
///
@@ -1778,7 +1802,7 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
1778
1802
}
1779
1803
}
1780
1804
1781
- impl < A : Allocator + Clone > Rc < dyn Any , A > {
1805
+ impl < A : Allocator > Rc < dyn Any , A > {
1782
1806
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
1783
1807
///
1784
1808
/// # Examples
@@ -1801,12 +1825,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
1801
1825
#[ stable( feature = "rc_downcast" , since = "1.29.0" ) ]
1802
1826
pub fn downcast < T : Any > ( self ) -> Result < Rc < T , A > , Self > {
1803
1827
if ( * self ) . is :: < T > ( ) {
1804
- unsafe {
1805
- let ptr = self . ptr . cast :: < RcBox < T > > ( ) ;
1806
- let alloc = self . alloc . clone ( ) ;
1807
- forget ( self ) ;
1808
- Ok ( Rc :: from_inner_in ( ptr, alloc) )
1809
- }
1828
+ let this = mem:: ManuallyDrop :: new ( self ) ;
1829
+ let ptr = this. ptr . cast :: < RcBox < T > > ( ) ;
1830
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1831
+ let alloc = unsafe { ptr:: read ( & this. alloc ) } ;
1832
+ unsafe { Ok ( Rc :: from_inner_in ( ptr, alloc) ) }
1810
1833
} else {
1811
1834
Err ( self )
1812
1835
}
@@ -1841,12 +1864,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
1841
1864
#[ inline]
1842
1865
#[ unstable( feature = "downcast_unchecked" , issue = "90850" ) ]
1843
1866
pub unsafe fn downcast_unchecked < T : Any > ( self ) -> Rc < T , A > {
1844
- unsafe {
1845
- let ptr = self . ptr . cast :: < RcBox < T > > ( ) ;
1846
- let alloc = self . alloc . clone ( ) ;
1847
- mem:: forget ( self ) ;
1848
- Rc :: from_inner_in ( ptr, alloc)
1849
- }
1867
+ let this = mem:: ManuallyDrop :: new ( self ) ;
1868
+ let ptr = this. ptr . cast :: < RcBox < T > > ( ) ;
1869
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1870
+ let alloc = unsafe { ptr:: read ( & this. alloc ) } ;
1871
+ unsafe { Rc :: from_inner_in ( ptr, alloc) }
1850
1872
}
1851
1873
}
1852
1874
@@ -2591,12 +2613,13 @@ impl From<Rc<str>> for Rc<[u8]> {
2591
2613
}
2592
2614
2593
2615
#[ stable( feature = "boxed_slice_try_from" , since = "1.43.0" ) ]
2594
- impl < T , const N : usize > TryFrom < Rc < [ T ] > > for Rc < [ T ; N ] > {
2595
- type Error = Rc < [ T ] > ;
2616
+ impl < T , A : Allocator , const N : usize > TryFrom < Rc < [ T ] , A > > for Rc < [ T ; N ] , A > {
2617
+ type Error = Rc < [ T ] , A > ;
2596
2618
2597
- fn try_from ( boxed_slice : Rc < [ T ] > ) -> Result < Self , Self :: Error > {
2619
+ fn try_from ( boxed_slice : Rc < [ T ] , A > ) -> Result < Self , Self :: Error > {
2598
2620
if boxed_slice. len ( ) == N {
2599
- Ok ( unsafe { Rc :: from_raw ( Rc :: into_raw ( boxed_slice) as * mut [ T ; N ] ) } )
2621
+ let ( ptr, alloc) = Rc :: into_raw_with_allocator ( boxed_slice) ;
2622
+ Ok ( unsafe { Rc :: from_raw_in ( ptr as * mut [ T ; N ] , alloc) } )
2600
2623
} else {
2601
2624
Err ( boxed_slice)
2602
2625
}
@@ -2849,6 +2872,13 @@ impl<T: ?Sized> Weak<T> {
2849
2872
}
2850
2873
2851
2874
impl < T : ?Sized , A : Allocator > Weak < T , A > {
2875
+ /// Returns a reference to the underlying allocator.
2876
+ #[ inline]
2877
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
2878
+ pub fn allocator ( & self ) -> & A {
2879
+ & self . alloc
2880
+ }
2881
+
2852
2882
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
2853
2883
///
2854
2884
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
@@ -2926,42 +2956,42 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
2926
2956
result
2927
2957
}
2928
2958
2929
- /// Consumes the `Weak<T>` and turns it into a raw pointer .
2959
+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator .
2930
2960
///
2931
2961
/// This converts the weak pointer into a raw pointer, while still preserving the ownership of
2932
2962
/// one weak reference (the weak count is not modified by this operation). It can be turned
2933
- /// back into the `Weak<T>` with [`from_raw `].
2963
+ /// back into the `Weak<T>` with [`from_raw_in `].
2934
2964
///
2935
2965
/// The same restrictions of accessing the target of the pointer as with
2936
2966
/// [`as_ptr`] apply.
2937
2967
///
2938
2968
/// # Examples
2939
2969
///
2940
2970
/// ```
2971
+ /// #![feature(allocator_api)]
2941
2972
/// use std::rc::{Rc, Weak};
2973
+ /// use std::alloc::System;
2942
2974
///
2943
- /// let strong = Rc::new ("hello".to_owned());
2975
+ /// let strong = Rc::new_in ("hello".to_owned(), System );
2944
2976
/// let weak = Rc::downgrade(&strong);
2945
- /// let raw = weak.into_raw ();
2977
+ /// let ( raw, alloc) = weak.into_raw_with_allocator ();
2946
2978
///
2947
2979
/// assert_eq!(1, Rc::weak_count(&strong));
2948
2980
/// assert_eq!("hello", unsafe { &*raw });
2949
2981
///
2950
- /// drop(unsafe { Weak::from_raw (raw) });
2982
+ /// drop(unsafe { Weak::from_raw_in (raw, alloc ) });
2951
2983
/// assert_eq!(0, Rc::weak_count(&strong));
2952
2984
/// ```
2953
2985
///
2954
- /// [`from_raw `]: Weak::from_raw
2986
+ /// [`from_raw_in `]: Weak::from_raw_in
2955
2987
/// [`as_ptr`]: Weak::as_ptr
2956
2988
#[ inline]
2957
2989
#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
2958
- pub fn into_raw_and_alloc ( self ) -> ( * const T , A )
2959
- where
2960
- A : Clone ,
2961
- {
2962
- let result = self . as_ptr ( ) ;
2963
- let alloc = self . alloc . clone ( ) ;
2964
- mem:: forget ( self ) ;
2990
+ pub fn into_raw_with_allocator ( self ) -> ( * const T , A ) {
2991
+ let this = mem:: ManuallyDrop :: new ( self ) ;
2992
+ let result = this. as_ptr ( ) ;
2993
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
2994
+ let alloc = unsafe { ptr:: read ( this. allocator ( ) ) } ;
2965
2995
( result, alloc)
2966
2996
}
2967
2997
0 commit comments