@@ -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
@@ -1127,12 +1117,9 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> {
11271117 /// ```
11281118 #[ unstable( feature = "new_uninit" , issue = "63291" ) ]
11291119 #[ 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) }
11361123 }
11371124}
11381125
@@ -1171,12 +1158,9 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> {
11711158 /// ```
11721159 #[ unstable( feature = "new_uninit" , issue = "63291" ) ]
11731160 #[ 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) }
11801164 }
11811165}
11821166
@@ -1293,6 +1277,17 @@ impl<T: ?Sized> Rc<T> {
12931277}
12941278
12951279impl < 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+
12961291 /// Consumes the `Rc`, returning the wrapped pointer.
12971292 ///
12981293 /// 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> {
13151310 ptr
13161311 }
13171312
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+
13181340 /// Provides a raw pointer to the data.
13191341 ///
13201342 /// 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> {
17421764 // reference to the allocation.
17431765 unsafe { & mut this. ptr . as_mut ( ) . value }
17441766 }
1767+ }
17451768
1769+ impl < T : Clone , A : Allocator > Rc < T , A > {
17461770 /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the
17471771 /// clone.
17481772 ///
@@ -1778,7 +1802,7 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
17781802 }
17791803}
17801804
1781- impl < A : Allocator + Clone > Rc < dyn Any , A > {
1805+ impl < A : Allocator > Rc < dyn Any , A > {
17821806 /// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
17831807 ///
17841808 /// # Examples
@@ -1801,12 +1825,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
18011825 #[ stable( feature = "rc_downcast" , since = "1.29.0" ) ]
18021826 pub fn downcast < T : Any > ( self ) -> Result < Rc < T , A > , Self > {
18031827 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) ) }
18101833 } else {
18111834 Err ( self )
18121835 }
@@ -1841,12 +1864,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
18411864 #[ inline]
18421865 #[ unstable( feature = "downcast_unchecked" , issue = "90850" ) ]
18431866 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) }
18501872 }
18511873}
18521874
@@ -2591,12 +2613,13 @@ impl From<Rc<str>> for Rc<[u8]> {
25912613}
25922614
25932615#[ 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 > ;
25962618
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 > {
25982620 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) } )
26002623 } else {
26012624 Err ( boxed_slice)
26022625 }
@@ -2849,6 +2872,13 @@ impl<T: ?Sized> Weak<T> {
28492872}
28502873
28512874impl < 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+
28522882 /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
28532883 ///
28542884 /// 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> {
29262956 result
29272957 }
29282958
2929- /// Consumes the `Weak<T>` and turns it into a raw pointer .
2959+ /// Consumes the `Weak<T>`, returning the wrapped pointer and allocator .
29302960 ///
29312961 /// This converts the weak pointer into a raw pointer, while still preserving the ownership of
29322962 /// 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 `].
29342964 ///
29352965 /// The same restrictions of accessing the target of the pointer as with
29362966 /// [`as_ptr`] apply.
29372967 ///
29382968 /// # Examples
29392969 ///
29402970 /// ```
2971+ /// #![feature(allocator_api)]
29412972 /// use std::rc::{Rc, Weak};
2973+ /// use std::alloc::System;
29422974 ///
2943- /// let strong = Rc::new ("hello".to_owned());
2975+ /// let strong = Rc::new_in ("hello".to_owned(), System );
29442976 /// let weak = Rc::downgrade(&strong);
2945- /// let raw = weak.into_raw ();
2977+ /// let ( raw, alloc) = weak.into_raw_with_allocator ();
29462978 ///
29472979 /// assert_eq!(1, Rc::weak_count(&strong));
29482980 /// assert_eq!("hello", unsafe { &*raw });
29492981 ///
2950- /// drop(unsafe { Weak::from_raw (raw) });
2982+ /// drop(unsafe { Weak::from_raw_in (raw, alloc ) });
29512983 /// assert_eq!(0, Rc::weak_count(&strong));
29522984 /// ```
29532985 ///
2954- /// [`from_raw `]: Weak::from_raw
2986+ /// [`from_raw_in `]: Weak::from_raw_in
29552987 /// [`as_ptr`]: Weak::as_ptr
29562988 #[ inline]
29572989 #[ 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 ( ) ) } ;
29652995 ( result, alloc)
29662996 }
29672997
0 commit comments