Skip to content

Commit 0b89e52

Browse files
committed
Implement alloc::sync::{Arc,Weak,UniqueArc} with alloc::raw_rc types
1 parent 1266321 commit 0b89e52

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
@@ -246,6 +246,16 @@ where
246246
self.weak.into_raw_parts()
247247
}
248248

249+
// `is_unique` only exists on `Arc`, so we need this `#[cfg(not(no_sync))]`. It can be removed
250+
// if `Rc::is_unique` is added.
251+
#[cfg(not(no_sync))]
252+
pub(crate) unsafe fn is_unique<R>(&self) -> bool
253+
where
254+
R: RefCounter,
255+
{
256+
unsafe { is_unique::<R>(self.value_ptr()) }
257+
}
258+
249259
#[cfg(not(no_global_oom_handling))]
250260
pub(crate) unsafe fn make_mut<R>(&mut self) -> &mut T
251261
where
@@ -744,6 +754,23 @@ impl<A> RawRc<dyn Any, A> {
744754
}
745755
}
746756

757+
#[cfg(not(no_sync))]
758+
impl<A> RawRc<dyn Any + Send + Sync, A> {
759+
pub(crate) fn downcast<T>(self) -> Result<RawRc<T, A>, Self>
760+
where
761+
T: Any,
762+
{
763+
if self.as_ref().is::<T>() { Ok(unsafe { self.downcast_unchecked() }) } else { Err(self) }
764+
}
765+
766+
pub(crate) unsafe fn downcast_unchecked<T>(self) -> RawRc<T, A>
767+
where
768+
T: Any,
769+
{
770+
unsafe { self.cast() }
771+
}
772+
}
773+
747774
impl<T, A> AsRef<T> for RawRc<T, A>
748775
where
749776
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)