From 89f120840684c56bdc4919767175e5831d80c42c Mon Sep 17 00:00:00 2001 From: malezjaa Date: Mon, 28 Sep 2026 21:23:45 +0200 Subject: [PATCH 1/2] stabilize {Arc,Rc}::is_unique --- library/alloc/src/rcs/arc.rs | 6 +----- library/alloc/src/rcs/rc.rs | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/rcs/arc.rs b/library/alloc/src/rcs/arc.rs index e61ea5193eccb..981e8fd1a0251 100644 --- a/library/alloc/src/rcs/arc.rs +++ b/library/alloc/src/rcs/arc.rs @@ -2870,8 +2870,6 @@ impl Arc { /// # Examples /// /// ``` - /// #![feature(arc_is_unique)] - /// /// use std::sync::Arc; /// /// let x = Arc::new(3); @@ -2894,8 +2892,6 @@ impl Arc { /// following code is valid, even though it would be UB if it used `Arc::get_mut`: /// /// ``` - /// #![feature(arc_is_unique)] - /// /// use std::sync::Arc; /// /// let arc = Arc::new(5); @@ -2915,7 +2911,7 @@ impl Arc { /// /// [`get_mut_unchecked`]: Self::get_mut_unchecked #[inline] - #[unstable(feature = "arc_is_unique", issue = "138938")] + #[stable(feature = "arc_is_unique", since = "CURRENT_RUSTC_VERSION")] pub fn is_unique(this: &Self) -> bool { // lock the weak pointer count if we appear to be the sole weak pointer // holder. diff --git a/library/alloc/src/rcs/rc.rs b/library/alloc/src/rcs/rc.rs index 04e08c47fb587..a5bb5c13ecb5a 100644 --- a/library/alloc/src/rcs/rc.rs +++ b/library/alloc/src/rcs/rc.rs @@ -1996,8 +1996,6 @@ impl Rc { /// # Examples /// /// ``` - /// #![feature(arc_is_unique)] - /// /// use std::rc::Rc; /// /// let x = Rc::new(3); @@ -2020,8 +2018,6 @@ impl Rc { /// following code is valid, even though it would be UB if it used `Rc::get_mut`: /// /// ``` - /// #![feature(arc_is_unique)] - /// /// use std::rc::Rc; /// /// let rc = Rc::new(5); @@ -2032,7 +2028,7 @@ impl Rc { /// /// [`get_mut_unchecked`]: Self::get_mut_unchecked #[inline] - #[unstable(feature = "arc_is_unique", issue = "138938")] + #[stable(feature = "arc_is_unique", since = "CURRENT_RUSTC_VERSION")] pub fn is_unique(this: &Self) -> bool { Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1 } From ef6ae0a7c809e2eba25ea8d2ad7e763ea1a64bc2 Mon Sep 17 00:00:00 2001 From: malezjaa Date: Fri, 9 Oct 2026 09:55:20 +0200 Subject: [PATCH 2/2] update documentation --- library/alloc/src/rcs/arc.rs | 16 +++++++++++++--- library/alloc/src/rcs/rc.rs | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/rcs/arc.rs b/library/alloc/src/rcs/arc.rs index 981e8fd1a0251..db8620c9e32c0 100644 --- a/library/alloc/src/rcs/arc.rs +++ b/library/alloc/src/rcs/arc.rs @@ -2864,8 +2864,12 @@ impl Arc { /// Returns `true` if there are no other `Arc` or [`Weak`] pointers to the same allocation; /// returns `false` otherwise. /// - /// If this function returns `true`, then is guaranteed to be safe to call [`get_mut_unchecked`] - /// on this `Arc`, so long as no clones occur in between. + /// If this function returns `true`, then it is guaranteed to be safe to call [`get_mut_unchecked`] + /// on this `Arc`, as long as no clones occur in between. + /// + /// The result can become stale if another thread can call `clone` or + /// `downgrade` through a shared reference. Make sure you have exclusive + /// access to the `Arc`. /// /// # Examples /// @@ -2889,7 +2893,7 @@ impl Arc { /// This function will always return the same value as `Arc::get_mut(arc).is_some()`. However, /// unlike that operation it does not produce any mutable references to the underlying data, /// meaning no pointers to the data inside the `Arc` are invalidated by the call. Thus, the - /// following code is valid, even though it would be UB if it used `Arc::get_mut`: + /// following code is valid: /// /// ``` /// use std::sync::Arc; @@ -2900,6 +2904,12 @@ impl Arc { /// assert_eq!(unsafe { *pointer }, 5); /// ``` /// + /// The following changes would make the example unsound: + /// + /// - Using `Arc::get_mut` to create a mutable reference while also accessing the value + /// through `pointer`. + /// - Dropping `arc` before dereferencing `pointer`, leaving it dangling. + /// /// # Atomic orderings /// /// Concurrent drops to other `Arc` pointers to the same allocation will synchronize with this diff --git a/library/alloc/src/rcs/rc.rs b/library/alloc/src/rcs/rc.rs index a5bb5c13ecb5a..8ec716961f768 100644 --- a/library/alloc/src/rcs/rc.rs +++ b/library/alloc/src/rcs/rc.rs @@ -1990,8 +1990,12 @@ impl Rc { /// Returns `true` if there are no other `Rc` or [`Weak`] pointers to the same allocation; /// returns `false` otherwise. /// - /// If this function returns `true`, it is safe to call [`get_mut_unchecked`] - /// immediately afterward. + /// If this function returns `true`, then it is guaranteed to be safe to call + /// [`get_mut_unchecked`] on this `Rc`, as long as no clones occur in between. + /// + /// The result can become stale if the `Rc` is cloned or downgraded between + /// the check and its use. Make sure no new `Rc` or `Weak` pointers are created + /// in between. /// /// # Examples /// @@ -2015,7 +2019,7 @@ impl Rc { /// This function will always return the same value as `Rc::get_mut(rc).is_some()`. However, /// unlike that operation it does not produce any mutable references to the underlying data, /// meaning no pointers to the data inside the `Rc` are invalidated by the call. Thus, the - /// following code is valid, even though it would be UB if it used `Rc::get_mut`: + /// following code is valid: /// /// ``` /// use std::rc::Rc; @@ -2026,6 +2030,12 @@ impl Rc { /// assert_eq!(unsafe { *pointer }, 5); /// ``` /// + /// The following changes would make the example unsound: + /// + /// - Using `Rc::get_mut` to create a mutable reference while also accessing the value + /// through `pointer`. + /// - Dropping `rc` before dereferencing `pointer`, leaving it dangling. + /// /// [`get_mut_unchecked`]: Self::get_mut_unchecked #[inline] #[stable(feature = "arc_is_unique", since = "CURRENT_RUSTC_VERSION")]