Skip to content

Commit 505846e

Browse files
authored
Rollup merge of #83476 - mystor:rc_mutate_strong_count, r=m-ou-se
Add strong_count mutation methods to Rc The corresponding methods were stabilized on `Arc` in #79285 (tracking: #71983). This patch implements and stabilizes identical methods on the `Rc` types as well.
2 parents 1c158b6 + a591d7a commit 505846e

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

library/alloc/src/rc.rs

+67
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,73 @@ impl<T: ?Sized> Rc<T> {
910910
this.inner().strong()
911911
}
912912

913+
/// Increments the strong reference count on the `Rc<T>` associated with the
914+
/// provided pointer by one.
915+
///
916+
/// # Safety
917+
///
918+
/// The pointer must have been obtained through `Rc::into_raw`, and the
919+
/// associated `Rc` instance must be valid (i.e. the strong count must be at
920+
/// least 1) for the duration of this method.
921+
///
922+
/// # Examples
923+
///
924+
/// ```
925+
/// use std::rc::Rc;
926+
///
927+
/// let five = Rc::new(5);
928+
///
929+
/// unsafe {
930+
/// let ptr = Rc::into_raw(five);
931+
/// Rc::increment_strong_count(ptr);
932+
///
933+
/// let five = Rc::from_raw(ptr);
934+
/// assert_eq!(2, Rc::strong_count(&five));
935+
/// }
936+
/// ```
937+
#[inline]
938+
#[stable(feature = "rc_mutate_strong_count", since = "1.53.0")]
939+
pub unsafe fn increment_strong_count(ptr: *const T) {
940+
// Retain Rc, but don't touch refcount by wrapping in ManuallyDrop
941+
let rc = unsafe { mem::ManuallyDrop::new(Rc::<T>::from_raw(ptr)) };
942+
// Now increase refcount, but don't drop new refcount either
943+
let _rc_clone: mem::ManuallyDrop<_> = rc.clone();
944+
}
945+
946+
/// Decrements the strong reference count on the `Rc<T>` associated with the
947+
/// provided pointer by one.
948+
///
949+
/// # Safety
950+
///
951+
/// The pointer must have been obtained through `Rc::into_raw`, and the
952+
/// associated `Rc` instance must be valid (i.e. the strong count must be at
953+
/// least 1) when invoking this method. This method can be used to release
954+
/// the final `Rc` and backing storage, but **should not** be called after
955+
/// the final `Rc` has been released.
956+
///
957+
/// # Examples
958+
///
959+
/// ```
960+
/// use std::rc::Rc;
961+
///
962+
/// let five = Rc::new(5);
963+
///
964+
/// unsafe {
965+
/// let ptr = Rc::into_raw(five);
966+
/// Rc::increment_strong_count(ptr);
967+
///
968+
/// let five = Rc::from_raw(ptr);
969+
/// assert_eq!(2, Rc::strong_count(&five));
970+
/// Rc::decrement_strong_count(ptr);
971+
/// assert_eq!(1, Rc::strong_count(&five));
972+
/// }
973+
/// ```
974+
#[inline]
975+
#[stable(feature = "rc_mutate_strong_count", since = "1.53.0")]
976+
pub unsafe fn decrement_strong_count(ptr: *const T) {
977+
unsafe { mem::drop(Rc::from_raw(ptr)) };
978+
}
979+
913980
/// Returns `true` if there are no other `Rc` or [`Weak`] pointers to
914981
/// this allocation.
915982
#[inline]

0 commit comments

Comments
 (0)