Relax allocator requirements on some Rc APIs.
* Remove A: Clone bound from Rc::assume_init, Rc::downcast, and Rc::downcast_unchecked. * Make From<Rc<[T; N]>> for Rc<[T]> allocator-aware. Internal changes: * Made Arc::internal_into_inner_with_allocator method into Arc::into_inner_with_allocator associated fn. * Add private Rc::into_inner_with_allocator (to match Arc), so other fns don't have to juggle ManuallyDrop.
This commit is contained in:
parent
6a19a87097
commit
d6122f1924
2 changed files with 29 additions and 32 deletions
|
@ -365,6 +365,12 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
|
||||||
unsafe { self.ptr.as_ref() }
|
unsafe { self.ptr.as_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn into_inner_with_allocator(this: Self) -> (NonNull<RcBox<T>>, A) {
|
||||||
|
let this = mem::ManuallyDrop::new(this);
|
||||||
|
(this.ptr, unsafe { ptr::read(&this.alloc) })
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn from_inner_in(ptr: NonNull<RcBox<T>>, alloc: A) -> Self {
|
unsafe fn from_inner_in(ptr: NonNull<RcBox<T>>, alloc: A) -> Self {
|
||||||
Self { ptr, phantom: PhantomData, alloc }
|
Self { ptr, phantom: PhantomData, alloc }
|
||||||
|
@ -1145,12 +1151,9 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> {
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "new_uninit", issue = "63291")]
|
#[unstable(feature = "new_uninit", issue = "63291")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn assume_init(self) -> Rc<T, A>
|
pub unsafe fn assume_init(self) -> Rc<T, A> {
|
||||||
where
|
let (ptr, alloc) = Rc::into_inner_with_allocator(self);
|
||||||
A: Clone,
|
unsafe { Rc::from_inner_in(ptr.cast(), alloc) }
|
||||||
{
|
|
||||||
let md_self = mem::ManuallyDrop::new(self);
|
|
||||||
unsafe { Rc::from_inner_in(md_self.ptr.cast(), md_self.alloc.clone()) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1189,12 +1192,9 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> {
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "new_uninit", issue = "63291")]
|
#[unstable(feature = "new_uninit", issue = "63291")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn assume_init(self) -> Rc<[T], A>
|
pub unsafe fn assume_init(self) -> Rc<[T], A> {
|
||||||
where
|
let (ptr, alloc) = Rc::into_inner_with_allocator(self);
|
||||||
A: Clone,
|
unsafe { Rc::from_ptr_in(ptr.as_ptr() as _, alloc) }
|
||||||
{
|
|
||||||
let md_self = mem::ManuallyDrop::new(self);
|
|
||||||
unsafe { Rc::from_ptr_in(md_self.ptr.as_ptr() as _, md_self.alloc.clone()) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1845,7 +1845,7 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: Allocator + Clone> Rc<dyn Any, A> {
|
impl<A: Allocator> Rc<dyn Any, A> {
|
||||||
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
|
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -1869,10 +1869,8 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
|
||||||
pub fn downcast<T: Any>(self) -> Result<Rc<T, A>, Self> {
|
pub fn downcast<T: Any>(self) -> Result<Rc<T, A>, Self> {
|
||||||
if (*self).is::<T>() {
|
if (*self).is::<T>() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = self.ptr.cast::<RcBox<T>>();
|
let (ptr, alloc) = Rc::into_inner_with_allocator(self);
|
||||||
let alloc = self.alloc.clone();
|
Ok(Rc::from_inner_in(ptr.cast(), alloc))
|
||||||
forget(self);
|
|
||||||
Ok(Rc::from_inner_in(ptr, alloc))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(self)
|
Err(self)
|
||||||
|
@ -1909,10 +1907,8 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
|
||||||
#[unstable(feature = "downcast_unchecked", issue = "90850")]
|
#[unstable(feature = "downcast_unchecked", issue = "90850")]
|
||||||
pub unsafe fn downcast_unchecked<T: Any>(self) -> Rc<T, A> {
|
pub unsafe fn downcast_unchecked<T: Any>(self) -> Rc<T, A> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = self.ptr.cast::<RcBox<T>>();
|
let (ptr, alloc) = Rc::into_inner_with_allocator(self);
|
||||||
let alloc = self.alloc.clone();
|
Rc::from_inner_in(ptr.cast(), alloc)
|
||||||
mem::forget(self);
|
|
||||||
Rc::from_inner_in(ptr, alloc)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2661,12 +2657,13 @@ impl From<Rc<str>> for Rc<[u8]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
|
#[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
|
||||||
impl<T, const N: usize> TryFrom<Rc<[T]>> for Rc<[T; N]> {
|
impl<T, A: Allocator, const N: usize> TryFrom<Rc<[T], A>> for Rc<[T; N], A> {
|
||||||
type Error = Rc<[T]>;
|
type Error = Rc<[T], A>;
|
||||||
|
|
||||||
fn try_from(boxed_slice: Rc<[T]>) -> Result<Self, Self::Error> {
|
fn try_from(boxed_slice: Rc<[T], A>) -> Result<Self, Self::Error> {
|
||||||
if boxed_slice.len() == N {
|
if boxed_slice.len() == N {
|
||||||
Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) })
|
let (ptr, alloc) = Rc::into_inner_with_allocator(boxed_slice);
|
||||||
|
Ok(unsafe { Rc::from_inner_in(ptr.cast(), alloc) })
|
||||||
} else {
|
} else {
|
||||||
Err(boxed_slice)
|
Err(boxed_slice)
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,8 +280,8 @@ impl<T: ?Sized> Arc<T> {
|
||||||
|
|
||||||
impl<T: ?Sized, A: Allocator> Arc<T, A> {
|
impl<T: ?Sized, A: Allocator> Arc<T, A> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn internal_into_inner_with_allocator(self) -> (NonNull<ArcInner<T>>, A) {
|
fn into_inner_with_allocator(this: Self) -> (NonNull<ArcInner<T>>, A) {
|
||||||
let this = mem::ManuallyDrop::new(self);
|
let this = mem::ManuallyDrop::new(this);
|
||||||
(this.ptr, unsafe { ptr::read(&this.alloc) })
|
(this.ptr, unsafe { ptr::read(&this.alloc) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1290,7 +1290,7 @@ impl<T, A: Allocator> Arc<mem::MaybeUninit<T>, A> {
|
||||||
#[must_use = "`self` will be dropped if the result is not used"]
|
#[must_use = "`self` will be dropped if the result is not used"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn assume_init(self) -> Arc<T, A> {
|
pub unsafe fn assume_init(self) -> Arc<T, A> {
|
||||||
let (ptr, alloc) = self.internal_into_inner_with_allocator();
|
let (ptr, alloc) = Arc::into_inner_with_allocator(self);
|
||||||
unsafe { Arc::from_inner_in(ptr.cast(), alloc) }
|
unsafe { Arc::from_inner_in(ptr.cast(), alloc) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1332,7 +1332,7 @@ impl<T, A: Allocator> Arc<[mem::MaybeUninit<T>], A> {
|
||||||
#[must_use = "`self` will be dropped if the result is not used"]
|
#[must_use = "`self` will be dropped if the result is not used"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn assume_init(self) -> Arc<[T], A> {
|
pub unsafe fn assume_init(self) -> Arc<[T], A> {
|
||||||
let (ptr, alloc) = self.internal_into_inner_with_allocator();
|
let (ptr, alloc) = Arc::into_inner_with_allocator(self);
|
||||||
unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) }
|
unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2499,7 +2499,7 @@ impl<A: Allocator> Arc<dyn Any + Send + Sync, A> {
|
||||||
{
|
{
|
||||||
if (*self).is::<T>() {
|
if (*self).is::<T>() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let (ptr, alloc) = self.internal_into_inner_with_allocator();
|
let (ptr, alloc) = Arc::into_inner_with_allocator(self);
|
||||||
Ok(Arc::from_inner_in(ptr.cast(), alloc))
|
Ok(Arc::from_inner_in(ptr.cast(), alloc))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2540,7 +2540,7 @@ impl<A: Allocator> Arc<dyn Any + Send + Sync, A> {
|
||||||
T: Any + Send + Sync,
|
T: Any + Send + Sync,
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let (ptr, alloc) = self.internal_into_inner_with_allocator();
|
let (ptr, alloc) = Arc::into_inner_with_allocator(self);
|
||||||
Arc::from_inner_in(ptr.cast(), alloc)
|
Arc::from_inner_in(ptr.cast(), alloc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3506,7 +3506,7 @@ impl<T, A: Allocator, const N: usize> TryFrom<Arc<[T], A>> for Arc<[T; N], A> {
|
||||||
|
|
||||||
fn try_from(boxed_slice: Arc<[T], A>) -> Result<Self, Self::Error> {
|
fn try_from(boxed_slice: Arc<[T], A>) -> Result<Self, Self::Error> {
|
||||||
if boxed_slice.len() == N {
|
if boxed_slice.len() == N {
|
||||||
let (ptr, alloc) = boxed_slice.internal_into_inner_with_allocator();
|
let (ptr, alloc) = Arc::into_inner_with_allocator(boxed_slice);
|
||||||
Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) })
|
Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) })
|
||||||
} else {
|
} else {
|
||||||
Err(boxed_slice)
|
Err(boxed_slice)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue