@@ -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
@@ -1145,12 +1135,9 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> {
1145
1135
/// ```
1146
1136
#[ unstable( feature = "new_uninit" , issue = "63291" ) ]
1147
1137
#[ inline]
1148
- pub unsafe fn assume_init ( self ) -> Rc < T , A >
1149
- where
1150
- A : Clone ,
1151
- {
1152
- let md_self = mem:: ManuallyDrop :: new ( self ) ;
1153
- unsafe { Rc :: from_inner_in ( md_self. ptr . cast ( ) , md_self. alloc . clone ( ) ) }
1138
+ pub unsafe fn assume_init ( self ) -> Rc < T , A > {
1139
+ let ( ptr, alloc) = Self :: into_raw_with_allocator ( self ) ;
1140
+ unsafe { Rc :: from_raw_in ( ptr. cast ( ) , alloc) }
1154
1141
}
1155
1142
}
1156
1143
@@ -1189,12 +1176,9 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> {
1189
1176
/// ```
1190
1177
#[ unstable( feature = "new_uninit" , issue = "63291" ) ]
1191
1178
#[ inline]
1192
- pub unsafe fn assume_init ( self ) -> Rc < [ T ] , A >
1193
- where
1194
- A : Clone ,
1195
- {
1196
- let md_self = mem:: ManuallyDrop :: new ( self ) ;
1197
- unsafe { Rc :: from_ptr_in ( md_self. ptr . as_ptr ( ) as _ , md_self. alloc . clone ( ) ) }
1179
+ pub unsafe fn assume_init ( self ) -> Rc < [ T ] , A > {
1180
+ let ( ptr, alloc) = Self :: into_raw_with_allocator ( self ) ;
1181
+ unsafe { Rc :: from_raw_in ( ptr as * const [ T ] , alloc) }
1198
1182
}
1199
1183
}
1200
1184
@@ -1333,6 +1317,17 @@ impl<T: ?Sized> Rc<T> {
1333
1317
}
1334
1318
1335
1319
impl < T : ?Sized , A : Allocator > Rc < T , A > {
1320
+ /// Returns a reference to the underlying allocator.
1321
+ ///
1322
+ /// Note: this is an associated function, which means that you have
1323
+ /// to call it as `Rc::allocator(&r)` instead of `r.allocator()`. This
1324
+ /// is so that there is no conflict with a method on the inner type.
1325
+ #[ inline]
1326
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1327
+ pub fn allocator ( this : & Self ) -> & A {
1328
+ & this. alloc
1329
+ }
1330
+
1336
1331
/// Consumes the `Rc`, returning the wrapped pointer.
1337
1332
///
1338
1333
/// To avoid a memory leak the pointer must be converted back to an `Rc` using
@@ -1356,6 +1351,33 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
1356
1351
ptr
1357
1352
}
1358
1353
1354
+ /// Consumes the `Rc`, returning the wrapped pointer and allocator.
1355
+ ///
1356
+ /// To avoid a memory leak the pointer must be converted back to an `Rc` using
1357
+ /// [`Rc::from_raw_in`].
1358
+ ///
1359
+ /// # Examples
1360
+ ///
1361
+ /// ```
1362
+ /// #![feature(allocator_api)]
1363
+ /// use std::rc::Rc;
1364
+ /// use std::alloc::System;
1365
+ ///
1366
+ /// let x = Rc::new_in("hello".to_owned(), System);
1367
+ /// let (ptr, alloc) = Rc::into_raw_with_allocator(x);
1368
+ /// assert_eq!(unsafe { &*ptr }, "hello");
1369
+ /// let x = unsafe { Rc::from_raw_in(ptr, alloc) };
1370
+ /// assert_eq!(&*x, "hello");
1371
+ /// ```
1372
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1373
+ pub fn into_raw_with_allocator ( this : Self ) -> ( * const T , A ) {
1374
+ let this = mem:: ManuallyDrop :: new ( this) ;
1375
+ let ptr = Self :: as_ptr ( & this) ;
1376
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1377
+ let alloc = unsafe { ptr:: read ( Self :: allocator ( & this) ) } ;
1378
+ ( ptr, alloc)
1379
+ }
1380
+
1359
1381
/// Provides a raw pointer to the data.
1360
1382
///
1361
1383
/// The counts are not affected in any way and the `Rc` is not consumed. The pointer is valid
@@ -1809,7 +1831,9 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
1809
1831
// reference to the allocation.
1810
1832
unsafe { & mut this. ptr . as_mut ( ) . value }
1811
1833
}
1834
+ }
1812
1835
1836
+ impl < T : Clone , A : Allocator > Rc < T , A > {
1813
1837
/// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the
1814
1838
/// clone.
1815
1839
///
@@ -1845,7 +1869,7 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
1845
1869
}
1846
1870
}
1847
1871
1848
- impl < A : Allocator + Clone > Rc < dyn Any , A > {
1872
+ impl < A : Allocator > Rc < dyn Any , A > {
1849
1873
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
1850
1874
///
1851
1875
/// # Examples
@@ -1868,12 +1892,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
1868
1892
#[ stable( feature = "rc_downcast" , since = "1.29.0" ) ]
1869
1893
pub fn downcast < T : Any > ( self ) -> Result < Rc < T , A > , Self > {
1870
1894
if ( * self ) . is :: < T > ( ) {
1871
- unsafe {
1872
- let ptr = self . ptr . cast :: < RcBox < T > > ( ) ;
1873
- let alloc = self . alloc . clone ( ) ;
1874
- forget ( self ) ;
1875
- Ok ( Rc :: from_inner_in ( ptr, alloc) )
1876
- }
1895
+ let this = mem:: ManuallyDrop :: new ( self ) ;
1896
+ let ptr = this. ptr . cast :: < RcBox < T > > ( ) ;
1897
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1898
+ let alloc = unsafe { ptr:: read ( & this. alloc ) } ;
1899
+ unsafe { Ok ( Rc :: from_inner_in ( ptr, alloc) ) }
1877
1900
} else {
1878
1901
Err ( self )
1879
1902
}
@@ -1908,12 +1931,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
1908
1931
#[ inline]
1909
1932
#[ unstable( feature = "downcast_unchecked" , issue = "90850" ) ]
1910
1933
pub unsafe fn downcast_unchecked < T : Any > ( self ) -> Rc < T , A > {
1911
- unsafe {
1912
- let ptr = self . ptr . cast :: < RcBox < T > > ( ) ;
1913
- let alloc = self . alloc . clone ( ) ;
1914
- mem:: forget ( self ) ;
1915
- Rc :: from_inner_in ( ptr, alloc)
1916
- }
1934
+ let this = mem:: ManuallyDrop :: new ( self ) ;
1935
+ let ptr = this. ptr . cast :: < RcBox < T > > ( ) ;
1936
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1937
+ let alloc = unsafe { ptr:: read ( & this. alloc ) } ;
1938
+ unsafe { Rc :: from_inner_in ( ptr, alloc) }
1917
1939
}
1918
1940
}
1919
1941
@@ -2661,12 +2683,13 @@ impl From<Rc<str>> for Rc<[u8]> {
2661
2683
}
2662
2684
2663
2685
#[ stable( feature = "boxed_slice_try_from" , since = "1.43.0" ) ]
2664
- impl < T , const N : usize > TryFrom < Rc < [ T ] > > for Rc < [ T ; N ] > {
2665
- type Error = Rc < [ T ] > ;
2686
+ impl < T , A : Allocator , const N : usize > TryFrom < Rc < [ T ] , A > > for Rc < [ T ; N ] , A > {
2687
+ type Error = Rc < [ T ] , A > ;
2666
2688
2667
- fn try_from ( boxed_slice : Rc < [ T ] > ) -> Result < Self , Self :: Error > {
2689
+ fn try_from ( boxed_slice : Rc < [ T ] , A > ) -> Result < Self , Self :: Error > {
2668
2690
if boxed_slice. len ( ) == N {
2669
- Ok ( unsafe { Rc :: from_raw ( Rc :: into_raw ( boxed_slice) as * mut [ T ; N ] ) } )
2691
+ let ( ptr, alloc) = Rc :: into_raw_with_allocator ( boxed_slice) ;
2692
+ Ok ( unsafe { Rc :: from_raw_in ( ptr as * mut [ T ; N ] , alloc) } )
2670
2693
} else {
2671
2694
Err ( boxed_slice)
2672
2695
}
@@ -2923,6 +2946,13 @@ impl<T: ?Sized> Weak<T> {
2923
2946
}
2924
2947
2925
2948
impl < T : ?Sized , A : Allocator > Weak < T , A > {
2949
+ /// Returns a reference to the underlying allocator.
2950
+ #[ inline]
2951
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
2952
+ pub fn allocator ( & self ) -> & A {
2953
+ & self . alloc
2954
+ }
2955
+
2926
2956
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
2927
2957
///
2928
2958
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
@@ -3000,39 +3030,42 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
3000
3030
result
3001
3031
}
3002
3032
3003
- /// Consumes the `Weak<T>` and turns it into a raw pointer .
3033
+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator .
3004
3034
///
3005
3035
/// This converts the weak pointer into a raw pointer, while still preserving the ownership of
3006
3036
/// one weak reference (the weak count is not modified by this operation). It can be turned
3007
- /// back into the `Weak<T>` with [`from_raw `].
3037
+ /// back into the `Weak<T>` with [`from_raw_in `].
3008
3038
///
3009
3039
/// The same restrictions of accessing the target of the pointer as with
3010
3040
/// [`as_ptr`] apply.
3011
3041
///
3012
3042
/// # Examples
3013
3043
///
3014
3044
/// ```
3045
+ /// #![feature(allocator_api)]
3015
3046
/// use std::rc::{Rc, Weak};
3047
+ /// use std::alloc::System;
3016
3048
///
3017
- /// let strong = Rc::new ("hello".to_owned());
3049
+ /// let strong = Rc::new_in ("hello".to_owned(), System );
3018
3050
/// let weak = Rc::downgrade(&strong);
3019
- /// let raw = weak.into_raw ();
3051
+ /// let ( raw, alloc) = weak.into_raw_with_allocator ();
3020
3052
///
3021
3053
/// assert_eq!(1, Rc::weak_count(&strong));
3022
3054
/// assert_eq!("hello", unsafe { &*raw });
3023
3055
///
3024
- /// drop(unsafe { Weak::from_raw (raw) });
3056
+ /// drop(unsafe { Weak::from_raw_in (raw, alloc ) });
3025
3057
/// assert_eq!(0, Rc::weak_count(&strong));
3026
3058
/// ```
3027
3059
///
3028
- /// [`from_raw `]: Weak::from_raw
3060
+ /// [`from_raw_in `]: Weak::from_raw_in
3029
3061
/// [`as_ptr`]: Weak::as_ptr
3030
3062
#[ inline]
3031
3063
#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
3032
- pub fn into_raw_and_alloc ( self ) -> ( * const T , A ) {
3033
- let rc = mem:: ManuallyDrop :: new ( self ) ;
3034
- let result = rc. as_ptr ( ) ;
3035
- let alloc = unsafe { ptr:: read ( & rc. alloc ) } ;
3064
+ pub fn into_raw_with_allocator ( self ) -> ( * const T , A ) {
3065
+ let this = mem:: ManuallyDrop :: new ( self ) ;
3066
+ let result = this. as_ptr ( ) ;
3067
+ // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
3068
+ let alloc = unsafe { ptr:: read ( this. allocator ( ) ) } ;
3036
3069
( result, alloc)
3037
3070
}
3038
3071
0 commit comments