@@ -661,16 +661,6 @@ impl<T> Rc<T> {
661661}
662662
663663impl < 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- }
674664 /// Constructs a new `Rc` in the provided allocator.
675665 ///
676666 /// # Examples
@@ -1145,12 +1135,9 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> {
11451135 /// ```
11461136 #[ unstable( feature = "new_uninit" , issue = "63291" ) ]
11471137 #[ 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) }
11541141 }
11551142}
11561143
@@ -1189,12 +1176,9 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> {
11891176 /// ```
11901177 #[ unstable( feature = "new_uninit" , issue = "63291" ) ]
11911178 #[ 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) }
11981182 }
11991183}
12001184
@@ -1333,6 +1317,17 @@ impl<T: ?Sized> Rc<T> {
13331317}
13341318
13351319impl < 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+
13361331 /// Consumes the `Rc`, returning the wrapped pointer.
13371332 ///
13381333 /// 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> {
13561351 ptr
13571352 }
13581353
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+
13591381 /// Provides a raw pointer to the data.
13601382 ///
13611383 /// 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> {
18091831 // reference to the allocation.
18101832 unsafe { & mut this. ptr . as_mut ( ) . value }
18111833 }
1834+ }
18121835
1836+ impl < T : Clone , A : Allocator > Rc < T , A > {
18131837 /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the
18141838 /// clone.
18151839 ///
@@ -1845,7 +1869,7 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
18451869 }
18461870}
18471871
1848- impl < A : Allocator + Clone > Rc < dyn Any , A > {
1872+ impl < A : Allocator > Rc < dyn Any , A > {
18491873 /// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
18501874 ///
18511875 /// # Examples
@@ -1868,12 +1892,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
18681892 #[ stable( feature = "rc_downcast" , since = "1.29.0" ) ]
18691893 pub fn downcast < T : Any > ( self ) -> Result < Rc < T , A > , Self > {
18701894 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) ) }
18771900 } else {
18781901 Err ( self )
18791902 }
@@ -1908,12 +1931,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
19081931 #[ inline]
19091932 #[ unstable( feature = "downcast_unchecked" , issue = "90850" ) ]
19101933 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) }
19171939 }
19181940}
19191941
@@ -2661,12 +2683,13 @@ impl From<Rc<str>> for Rc<[u8]> {
26612683}
26622684
26632685#[ 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 > ;
26662688
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 > {
26682690 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) } )
26702693 } else {
26712694 Err ( boxed_slice)
26722695 }
@@ -2923,6 +2946,13 @@ impl<T: ?Sized> Weak<T> {
29232946}
29242947
29252948impl < 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+
29262956 /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
29272957 ///
29282958 /// The pointer is valid only if there are some strong references. The pointer may be dangling,
@@ -3000,42 +3030,42 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
30003030 result
30013031 }
30023032
3003- /// Consumes the `Weak<T>` and turns it into a raw pointer .
3033+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator .
30043034 ///
30053035 /// This converts the weak pointer into a raw pointer, while still preserving the ownership of
30063036 /// 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 `].
30083038 ///
30093039 /// The same restrictions of accessing the target of the pointer as with
30103040 /// [`as_ptr`] apply.
30113041 ///
30123042 /// # Examples
30133043 ///
30143044 /// ```
3045+ /// #![feature(allocator_api)]
30153046 /// use std::rc::{Rc, Weak};
3047+ /// use std::alloc::System;
30163048 ///
3017- /// let strong = Rc::new ("hello".to_owned());
3049+ /// let strong = Rc::new_in ("hello".to_owned(), System );
30183050 /// let weak = Rc::downgrade(&strong);
3019- /// let raw = weak.into_raw ();
3051+ /// let ( raw, alloc) = weak.into_raw_with_allocator ();
30203052 ///
30213053 /// assert_eq!(1, Rc::weak_count(&strong));
30223054 /// assert_eq!("hello", unsafe { &*raw });
30233055 ///
3024- /// drop(unsafe { Weak::from_raw (raw) });
3056+ /// drop(unsafe { Weak::from_raw_in (raw, alloc ) });
30253057 /// assert_eq!(0, Rc::weak_count(&strong));
30263058 /// ```
30273059 ///
3028- /// [`from_raw `]: Weak::from_raw
3060+ /// [`from_raw_in `]: Weak::from_raw_in
30293061 /// [`as_ptr`]: Weak::as_ptr
30303062 #[ inline]
30313063 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
3032- pub fn into_raw_and_alloc ( self ) -> ( * const T , A )
3033- where
3034- A : Clone ,
3035- {
3036- let result = self . as_ptr ( ) ;
3037- let alloc = self . alloc . clone ( ) ;
3038- mem:: forget ( self ) ;
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 ( ) ) } ;
30393069 ( result, alloc)
30403070 }
30413071
0 commit comments