Skip to content

Commit 1c12801

Browse files
committed
Implement alloc::sync::{Arc,Weak,UniqueArc} with alloc::raw_rc types
1 parent 309102d commit 1c12801

File tree

10 files changed

+613
-1387
lines changed

10 files changed

+613
-1387
lines changed

library/alloc/src/raw_rc/raw_rc.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,16 @@ where
242242
self.weak.into_raw_parts()
243243
}
244244

245+
// `is_unique` only exists on `Arc`, so we need this `#[cfg(not(no_sync))]`. It can be removed
246+
// if `Rc::is_unique` is added.
247+
#[cfg(not(no_sync))]
248+
pub(crate) unsafe fn is_unique<R>(&self) -> bool
249+
where
250+
R: RefCounter,
251+
{
252+
unsafe { is_unique::<R>(self.value_ptr()) }
253+
}
254+
245255
#[cfg(not(no_global_oom_handling))]
246256
pub(crate) unsafe fn make_mut<R>(&mut self) -> &mut T
247257
where
@@ -740,6 +750,23 @@ impl<A> RawRc<dyn Any, A> {
740750
}
741751
}
742752

753+
#[cfg(not(no_sync))]
754+
impl<A> RawRc<dyn Any + Send + Sync, A> {
755+
pub(crate) fn downcast<T>(self) -> Result<RawRc<T, A>, Self>
756+
where
757+
T: Any,
758+
{
759+
if self.as_ref().is::<T>() { Ok(unsafe { self.downcast_unchecked() }) } else { Err(self) }
760+
}
761+
762+
pub(crate) unsafe fn downcast_unchecked<T>(self) -> RawRc<T, A>
763+
where
764+
T: Any,
765+
{
766+
unsafe { self.cast() }
767+
}
768+
}
769+
743770
impl<T, A> AsRef<T> for RawRc<T, A>
744771
where
745772
T: ?Sized,

library/alloc/src/raw_rc/raw_weak.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,19 @@ where
282282
!ptr::addr_eq(self.ptr.as_ptr(), other.ptr.as_ptr())
283283
}
284284

285+
/// Returns the `RefCounts` object inside the reference-counted allocation if `self` is
286+
/// non-dangling.
287+
#[cfg(not(no_sync))]
288+
pub(crate) fn ref_counts(&self) -> Option<&RefCounts> {
289+
(!is_dangling(self.ptr.cast())).then(|| unsafe { self.ref_counts_unchecked() })
290+
}
291+
285292
/// Returns the `RefCounts` object inside the reference-counted allocation, assume `self` is
286293
/// non-dangling.
287294
///
288295
/// # Safety
289296
///
290297
/// `self` is non-dangling.
291-
#[cfg(not(no_global_oom_handling))]
292298
pub(super) unsafe fn ref_counts_unchecked(&self) -> &RefCounts {
293299
unsafe { self.value_ptr_unchecked().ref_counts_ptr().as_ref() }
294300
}

library/alloc/src/rc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ use crate::vec::Vec;
272272

273273
type RefCounter = Cell<usize>;
274274

275-
unsafe impl raw_rc::RefCounter for RefCounter {
275+
unsafe impl raw_rc::RefCounter for Cell<usize> {
276276
#[inline]
277277
fn increment(&self) {
278278
// NOTE: If you `mem::forget` `Rc`s (or `Weak`s), drop is skipped and the ref-count

0 commit comments

Comments
 (0)