Skip to content

Commit bc074ab

Browse files
committed
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.
1 parent 378c8fc commit bc074ab

File tree

2 files changed

+29
-32
lines changed

2 files changed

+29
-32
lines changed

Diff for: alloc/src/rc.rs

+22-25
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,12 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
365365
unsafe { self.ptr.as_ref() }
366366
}
367367

368+
#[inline]
369+
fn into_inner_with_allocator(this: Self) -> (NonNull<RcBox<T>>, A) {
370+
let this = mem::ManuallyDrop::new(this);
371+
(this.ptr, unsafe { ptr::read(&this.alloc) })
372+
}
373+
368374
#[inline]
369375
unsafe fn from_inner_in(ptr: NonNull<RcBox<T>>, alloc: A) -> Self {
370376
Self { ptr, phantom: PhantomData, alloc }
@@ -1145,12 +1151,9 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> {
11451151
/// ```
11461152
#[unstable(feature = "new_uninit", issue = "63291")]
11471153
#[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()) }
1154+
pub unsafe fn assume_init(self) -> Rc<T, A> {
1155+
let (ptr, alloc) = Rc::into_inner_with_allocator(self);
1156+
unsafe { Rc::from_inner_in(ptr.cast(), alloc) }
11541157
}
11551158
}
11561159

@@ -1189,12 +1192,9 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> {
11891192
/// ```
11901193
#[unstable(feature = "new_uninit", issue = "63291")]
11911194
#[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()) }
1195+
pub unsafe fn assume_init(self) -> Rc<[T], A> {
1196+
let (ptr, alloc) = Rc::into_inner_with_allocator(self);
1197+
unsafe { Rc::from_ptr_in(ptr.as_ptr() as _, alloc) }
11981198
}
11991199
}
12001200

@@ -1845,7 +1845,7 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> {
18451845
}
18461846
}
18471847

1848-
impl<A: Allocator + Clone> Rc<dyn Any, A> {
1848+
impl<A: Allocator> Rc<dyn Any, A> {
18491849
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
18501850
///
18511851
/// # Examples
@@ -1869,10 +1869,8 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
18691869
pub fn downcast<T: Any>(self) -> Result<Rc<T, A>, Self> {
18701870
if (*self).is::<T>() {
18711871
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))
1872+
let (ptr, alloc) = Rc::into_inner_with_allocator(self);
1873+
Ok(Rc::from_inner_in(ptr.cast(), alloc))
18761874
}
18771875
} else {
18781876
Err(self)
@@ -1909,10 +1907,8 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> {
19091907
#[unstable(feature = "downcast_unchecked", issue = "90850")]
19101908
pub unsafe fn downcast_unchecked<T: Any>(self) -> Rc<T, A> {
19111909
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)
1910+
let (ptr, alloc) = Rc::into_inner_with_allocator(self);
1911+
Rc::from_inner_in(ptr.cast(), alloc)
19161912
}
19171913
}
19181914
}
@@ -2661,12 +2657,13 @@ impl From<Rc<str>> for Rc<[u8]> {
26612657
}
26622658

26632659
#[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]>;
2660+
impl<T, A: Allocator, const N: usize> TryFrom<Rc<[T], A>> for Rc<[T; N], A> {
2661+
type Error = Rc<[T], A>;
26662662

2667-
fn try_from(boxed_slice: Rc<[T]>) -> Result<Self, Self::Error> {
2663+
fn try_from(boxed_slice: Rc<[T], A>) -> Result<Self, Self::Error> {
26682664
if boxed_slice.len() == N {
2669-
Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) })
2665+
let (ptr, alloc) = Rc::into_inner_with_allocator(boxed_slice);
2666+
Ok(unsafe { Rc::from_inner_in(ptr.cast(), alloc) })
26702667
} else {
26712668
Err(boxed_slice)
26722669
}

Diff for: alloc/src/sync.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,8 @@ impl<T: ?Sized> Arc<T> {
280280

281281
impl<T: ?Sized, A: Allocator> Arc<T, A> {
282282
#[inline]
283-
fn internal_into_inner_with_allocator(self) -> (NonNull<ArcInner<T>>, A) {
284-
let this = mem::ManuallyDrop::new(self);
283+
fn into_inner_with_allocator(this: Self) -> (NonNull<ArcInner<T>>, A) {
284+
let this = mem::ManuallyDrop::new(this);
285285
(this.ptr, unsafe { ptr::read(&this.alloc) })
286286
}
287287

@@ -1290,7 +1290,7 @@ impl<T, A: Allocator> Arc<mem::MaybeUninit<T>, A> {
12901290
#[must_use = "`self` will be dropped if the result is not used"]
12911291
#[inline]
12921292
pub unsafe fn assume_init(self) -> Arc<T, A> {
1293-
let (ptr, alloc) = self.internal_into_inner_with_allocator();
1293+
let (ptr, alloc) = Arc::into_inner_with_allocator(self);
12941294
unsafe { Arc::from_inner_in(ptr.cast(), alloc) }
12951295
}
12961296
}
@@ -1332,7 +1332,7 @@ impl<T, A: Allocator> Arc<[mem::MaybeUninit<T>], A> {
13321332
#[must_use = "`self` will be dropped if the result is not used"]
13331333
#[inline]
13341334
pub unsafe fn assume_init(self) -> Arc<[T], A> {
1335-
let (ptr, alloc) = self.internal_into_inner_with_allocator();
1335+
let (ptr, alloc) = Arc::into_inner_with_allocator(self);
13361336
unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) }
13371337
}
13381338
}
@@ -2499,7 +2499,7 @@ impl<A: Allocator> Arc<dyn Any + Send + Sync, A> {
24992499
{
25002500
if (*self).is::<T>() {
25012501
unsafe {
2502-
let (ptr, alloc) = self.internal_into_inner_with_allocator();
2502+
let (ptr, alloc) = Arc::into_inner_with_allocator(self);
25032503
Ok(Arc::from_inner_in(ptr.cast(), alloc))
25042504
}
25052505
} else {
@@ -2540,7 +2540,7 @@ impl<A: Allocator> Arc<dyn Any + Send + Sync, A> {
25402540
T: Any + Send + Sync,
25412541
{
25422542
unsafe {
2543-
let (ptr, alloc) = self.internal_into_inner_with_allocator();
2543+
let (ptr, alloc) = Arc::into_inner_with_allocator(self);
25442544
Arc::from_inner_in(ptr.cast(), alloc)
25452545
}
25462546
}
@@ -3506,7 +3506,7 @@ impl<T, A: Allocator, const N: usize> TryFrom<Arc<[T], A>> for Arc<[T; N], A> {
35063506

35073507
fn try_from(boxed_slice: Arc<[T], A>) -> Result<Self, Self::Error> {
35083508
if boxed_slice.len() == N {
3509-
let (ptr, alloc) = boxed_slice.internal_into_inner_with_allocator();
3509+
let (ptr, alloc) = Arc::into_inner_with_allocator(boxed_slice);
35103510
Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) })
35113511
} else {
35123512
Err(boxed_slice)

0 commit comments

Comments
 (0)