Skip to content

Commit 2134c8e

Browse files
committed
Relax allocator bounds on more Arc/Rc methods/impls.
Remove `A: Clone` bound from: * `downcast`, `downcast_unchecked`, `unwrap_or_clone` for both. * `From<Vec<T, A>> for Arc<[T], A>` (Rc's already didn't require A: Clone) * `TryFrom<Arc<[T], A>> for Arc<[T; N], A>` Make existing `TryFrom<Rc<[T]>> for Rc<[T; N]>` allocator-aware.
1 parent e037761 commit 2134c8e

File tree

2 files changed

+35
-34
lines changed

2 files changed

+35
-34
lines changed

library/alloc/src/rc.rs

+18-17
Original file line numberDiff line numberDiff line change
@@ -1760,7 +1760,9 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
17601760
// reference to the allocation.
17611761
unsafe { &mut this.ptr.as_mut().value }
17621762
}
1763+
}
17631764

1765+
impl<T: Clone, A: Allocator> Rc<T, A> {
17641766
/// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the
17651767
/// clone.
17661768
///
@@ -1796,7 +1798,7 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
17961798
}
17971799
}
17981800

1799-
impl<A: Allocator + Clone> Rc<dyn Any, A> {
1801+
impl<A: Allocator> Rc<dyn Any, A> {
18001802
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
18011803
///
18021804
/// # Examples
@@ -1819,12 +1821,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
18191821
#[stable(feature = "rc_downcast", since = "1.29.0")]
18201822
pub fn downcast<T: Any>(self) -> Result<Rc<T, A>, Self> {
18211823
if (*self).is::<T>() {
1822-
unsafe {
1823-
let ptr = self.ptr.cast::<RcBox<T>>();
1824-
let alloc = self.alloc.clone();
1825-
forget(self);
1826-
Ok(Rc::from_inner_in(ptr, alloc))
1827-
}
1824+
let this = mem::ManuallyDrop::new(self);
1825+
let ptr = this.ptr.cast::<RcBox<T>>();
1826+
// Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1827+
let alloc = unsafe { ptr::read(&this.alloc) };
1828+
unsafe { Ok(Rc::from_inner_in(ptr, alloc)) }
18281829
} else {
18291830
Err(self)
18301831
}
@@ -1859,12 +1860,11 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
18591860
#[inline]
18601861
#[unstable(feature = "downcast_unchecked", issue = "90850")]
18611862
pub unsafe fn downcast_unchecked<T: Any>(self) -> Rc<T, A> {
1862-
unsafe {
1863-
let ptr = self.ptr.cast::<RcBox<T>>();
1864-
let alloc = self.alloc.clone();
1865-
mem::forget(self);
1866-
Rc::from_inner_in(ptr, alloc)
1867-
}
1863+
let this = mem::ManuallyDrop::new(self);
1864+
let ptr = this.ptr.cast::<RcBox<T>>();
1865+
// Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
1866+
let alloc = unsafe { ptr::read(&this.alloc) };
1867+
unsafe { Rc::from_inner_in(ptr, alloc) }
18681868
}
18691869
}
18701870

@@ -2604,12 +2604,13 @@ impl From<Rc<str>> for Rc<[u8]> {
26042604
}
26052605

26062606
#[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
2607-
impl<T, const N: usize> TryFrom<Rc<[T]>> for Rc<[T; N]> {
2608-
type Error = Rc<[T]>;
2607+
impl<T, A: Allocator, const N: usize> TryFrom<Rc<[T], A>> for Rc<[T; N], A> {
2608+
type Error = Rc<[T], A>;
26092609

2610-
fn try_from(boxed_slice: Rc<[T]>) -> Result<Self, Self::Error> {
2610+
fn try_from(boxed_slice: Rc<[T], A>) -> Result<Self, Self::Error> {
26112611
if boxed_slice.len() == N {
2612-
Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) })
2612+
let (ptr, alloc) = Rc::into_raw_with_allocator(boxed_slice);
2613+
Ok(unsafe { Rc::from_raw_in(ptr as *mut [T; N], alloc) })
26132614
} else {
26142615
Err(boxed_slice)
26152616
}

library/alloc/src/sync.rs

+17-17
Original file line numberDiff line numberDiff line change
@@ -2187,7 +2187,9 @@ impl<T: Clone, A: Allocator + Clone> Arc<T, A> {
21872187
// either unique to begin with, or became one upon cloning the contents.
21882188
unsafe { Self::get_mut_unchecked(this) }
21892189
}
2190+
}
21902191

2192+
impl<T: Clone, A: Allocator> Arc<T, A> {
21912193
/// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the
21922194
/// clone.
21932195
///
@@ -2432,7 +2434,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Arc<T, A> {
24322434
}
24332435
}
24342436

2435-
impl<A: Allocator + Clone> Arc<dyn Any + Send + Sync, A> {
2437+
impl<A: Allocator> Arc<dyn Any + Send + Sync, A> {
24362438
/// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
24372439
///
24382440
/// # Examples
@@ -2458,12 +2460,11 @@ impl<A: Allocator + Clone> Arc<dyn Any + Send + Sync, A> {
24582460
T: Any + Send + Sync,
24592461
{
24602462
if (*self).is::<T>() {
2461-
unsafe {
2462-
let ptr = self.ptr.cast::<ArcInner<T>>();
2463-
let alloc = self.alloc.clone();
2464-
mem::forget(self);
2465-
Ok(Arc::from_inner_in(ptr, alloc))
2466-
}
2463+
let this = mem::ManuallyDrop::new(self);
2464+
let ptr = this.ptr.cast::<ArcInner<T>>();
2465+
// Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
2466+
let alloc = unsafe { ptr::read(&this.alloc) };
2467+
unsafe { Ok(Arc::from_inner_in(ptr, alloc)) }
24672468
} else {
24682469
Err(self)
24692470
}
@@ -2501,12 +2502,11 @@ impl<A: Allocator + Clone> Arc<dyn Any + Send + Sync, A> {
25012502
where
25022503
T: Any + Send + Sync,
25032504
{
2504-
unsafe {
2505-
let ptr = self.ptr.cast::<ArcInner<T>>();
2506-
let alloc = self.alloc.clone();
2507-
mem::forget(self);
2508-
Arc::from_inner_in(ptr, alloc)
2509-
}
2505+
let this = mem::ManuallyDrop::new(self);
2506+
let ptr = this.ptr.cast::<ArcInner<T>>();
2507+
// Safety: `this` is ManuallyDrop so the allocator will not be double-dropped
2508+
let alloc = unsafe { ptr::read(&this.alloc) };
2509+
unsafe { Arc::from_inner_in(ptr, alloc) }
25102510
}
25112511
}
25122512

@@ -3432,7 +3432,7 @@ impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Arc<T, A> {
34323432

34333433
#[cfg(not(no_global_oom_handling))]
34343434
#[stable(feature = "shared_from_slice", since = "1.21.0")]
3435-
impl<T, A: Allocator + Clone> From<Vec<T, A>> for Arc<[T], A> {
3435+
impl<T, A: Allocator> From<Vec<T, A>> for Arc<[T], A> {
34363436
/// Allocate a reference-counted slice and move `v`'s items into it.
34373437
///
34383438
/// # Example
@@ -3507,13 +3507,13 @@ impl From<Arc<str>> for Arc<[u8]> {
35073507
}
35083508

35093509
#[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
3510-
impl<T, A: Allocator + Clone, const N: usize> TryFrom<Arc<[T], A>> for Arc<[T; N], A> {
3510+
impl<T, A: Allocator, const N: usize> TryFrom<Arc<[T], A>> for Arc<[T; N], A> {
35113511
type Error = Arc<[T], A>;
35123512

35133513
fn try_from(boxed_slice: Arc<[T], A>) -> Result<Self, Self::Error> {
35143514
if boxed_slice.len() == N {
3515-
let alloc = boxed_slice.alloc.clone();
3516-
Ok(unsafe { Arc::from_raw_in(Arc::into_raw(boxed_slice) as *mut [T; N], alloc) })
3515+
let (ptr, alloc) = Arc::into_raw_with_allocator(boxed_slice);
3516+
Ok(unsafe { Arc::from_raw_in(ptr as *mut [T; N], alloc) })
35173517
} else {
35183518
Err(boxed_slice)
35193519
}

0 commit comments

Comments
 (0)