Change:
<!-- Thank you for creating a tracking issue! Tracking issues are for tracking a feature from implementation to stabilisation. Make sure to include the relevant RFC for the feature if it has one. Otherwise provide a short summary of the feature and link any relevant PRs or issues, and remove any sections that are not relevant to the feature. Remember to add team labels to the tracking issue. For a language team feature, this would e.g., be . Such a feature should also be labeled with e.g., . This label is used to associate issues (e.g., bugs and design questions) to the feature. --The feature gate for the issue is . <!-- Include each step required to complete the feature. Typically this is a PR implementing a feature, followed by a PR that stabilises the feature. However for larger features an implementation could be broken up into multiple PRs. --- [x] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) [x] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) [stabilization-guide]: https://rustc-dev- [doc-guide]: https://rustc-dev- <!-- Include any open questions that need to be answered before the feature can be stabilised. --- [ ] Can we improve the docs phrasing on ? <!-- Include a list of all the PRs that were involved in implementing the feature. --- Initial PR in Stabilization PR in
Hello Would it make sense to also include similar methods for Rc? And possibly similar ones to both Weaks? It would be in part for the sake of completeness, but I do some manipulation like this in the arc-swap crate and if this would become the „official“ way, it would be nice to be supported on all the related types.
I think that's a great idea, and we should file follow-up issues to implement those.

Discussion:
/// # Examples /// /// ``` <del> /// #![feature(arc_mutate_strong_count)] /// </del> /// use std::sync::Arc; /// /// let five = Arc::new(5); /// /// unsafe { ///     let ptr = Arc::into_raw(five); <del> ///     Arc::incr_strong_count(ptr); </del> <ins> ///     Arc::increment_strong_count(ptr); </ins> /// ///     // This assertion is deterministic because we haven't shared ///     // the `Arc` between threads.

/// } /// ``` #[inline] <del> #[unstable(feature = "arc_mutate_strong_count", issue = "71983")] pub unsafe fn incr_strong_count(ptr: *const T) { </del> <ins> #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] pub unsafe fn increment_strong_count(ptr: *const T) { </ins> // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop let arc = unsafe { mem::ManuallyDrop::new(Arc::<T>::from_raw(ptr)) }; // Now increase refcount, but don't drop new refcount either

/// # Examples /// /// ``` <del> /// #![feature(arc_mutate_strong_count)] /// </del> /// use std::sync::Arc; /// /// let five = Arc::new(5); /// /// unsafe { ///     let ptr = Arc::into_raw(five); <del> ///     Arc::incr_strong_count(ptr); </del> <ins> ///     Arc::increment_strong_count(ptr); </ins> /// ///     // Those assertions are deterministic because we haven't shared ///     // the `Arc` between threads. ///     let five = Arc::from_raw(ptr); ///     assert_eq!(2, Arc::strong_count(&five)); <del> ///     Arc::decr_strong_count(ptr); </del> <ins> ///     Arc::decrement_strong_count(ptr); </ins> ///     assert_eq!(1, Arc::strong_count(&five)); /// } /// ``` #[inline] <del> #[unstable(feature = "arc_mutate_strong_count", issue = "71983")] pub unsafe fn decr_strong_count(ptr: *const T) { </del> <ins> #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] pub unsafe fn decrement_strong_count(ptr: *const T) { </ins> unsafe { mem::drop(Arc::from_raw(ptr)) }; }

fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker { // Increment the reference count of the arc to clone it. unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker { <del> unsafe { Arc::incr_strong_count(waker as *const W) }; </del> <ins> unsafe { Arc::increment_strong_count(waker as *const W) }; </ins> RawWaker::new( waker as *const (), &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),

// Decrement the reference count of the Arc on drop unsafe fn drop_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) { <del> unsafe { Arc::decr_strong_count(waker as *const W) }; </del> <ins> unsafe { Arc::decrement_strong_count(waker as *const W) }; </ins> } RawWaker::new(