From 51d598ec285fc8aa29e2a1c64dc90394ccbd4130 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Thu, 19 Aug 2021 12:35:20 +0200 Subject: [PATCH 1/3] Adjust documentation of `Arc::make_mut` Related discussion in the users forum: https://users.rust-lang.org/t/what-s-this-alleged-difference-between-arc-make-mut-and-rc-make-mut/63747?u=steffahn Also includes small formatting improvement in the documentation of `Rc::make_mut`. This commit makes the two documentations in question complete analogs. The previously claimed point in which one "differs from the behavior of" the other turns out to be incorrect, AFAIK. One remaining inaccuracy: `Weak` pointers aren't disassociated from the allocation but only from the contained value, i.e. in case of outstanding `Weak` pointers there still is a new allocation created, just the call to `.clone()` is avoided, instead the value is moved from one allocation to the other. --- library/alloc/src/rc.rs | 10 +++++----- library/alloc/src/sync.rs | 34 +++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 0b3079fa59db6..90b077210a475 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1115,11 +1115,11 @@ impl Rc { /// /// let mut data = Rc::new(5); /// - /// *Rc::make_mut(&mut data) += 1; // Won't clone anything - /// let mut other_data = Rc::clone(&data); // Won't clone inner data - /// *Rc::make_mut(&mut data) += 1; // Clones inner data - /// *Rc::make_mut(&mut data) += 1; // Won't clone anything - /// *Rc::make_mut(&mut other_data) *= 2; // Won't clone anything + /// *Rc::make_mut(&mut data) += 1; // Won't clone anything + /// let mut other_data = Rc::clone(&data); // Won't clone inner data + /// *Rc::make_mut(&mut data) += 1; // Clones inner data + /// *Rc::make_mut(&mut data) += 1; // Won't clone anything + /// *Rc::make_mut(&mut other_data) *= 2; // Won't clone anything /// /// // Now `data` and `other_data` point to different allocations. /// assert_eq!(*data, 8); diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 3183a6db410b8..7e4cb6d2c60f2 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1346,18 +1346,17 @@ impl Receiver for Arc {} impl Arc { /// Makes a mutable reference into the given `Arc`. /// - /// If there are other `Arc` or [`Weak`] pointers to the same allocation, - /// then `make_mut` will create a new allocation and invoke [`clone`][clone] on the inner value - /// to ensure unique ownership. This is also referred to as clone-on-write. + /// If there are other `Arc` pointers to the same allocation, then `make_mut` will + /// [`clone`] the inner value to a new allocation to ensure unique ownership. This is also + /// referred to as clone-on-write. /// - /// Note that this differs from the behavior of [`Rc::make_mut`] which disassociates - /// any remaining `Weak` pointers. + /// If there are no other `Arc` pointers to this allocation, then [`Weak`] + /// pointers to this allocation will be disassociated. /// - /// See also [`get_mut`][get_mut], which will fail rather than cloning. + /// See also [`get_mut`], which will fail rather than cloning. /// - /// [clone]: Clone::clone - /// [get_mut]: Arc::get_mut - /// [`Rc::make_mut`]: super::rc::Rc::make_mut + /// [`clone`]: Clone::clone + /// [`get_mut`]: Arc::get_mut /// /// # Examples /// @@ -1376,6 +1375,23 @@ impl Arc { /// assert_eq!(*data, 8); /// assert_eq!(*other_data, 12); /// ``` + /// + /// [`Weak`] pointers will be disassociated: + /// + /// ``` + /// use std::sync::Arc; + /// + /// let mut data = Arc::new(75); + /// let weak = Arc::downgrade(&data); + /// + /// assert!(75 == *data); + /// assert!(75 == *weak.upgrade().unwrap()); + /// + /// *Arc::make_mut(&mut data) += 1; + /// + /// assert!(76 == *data); + /// assert!(weak.upgrade().is_none()); + /// ``` #[cfg(not(no_global_oom_handling))] #[inline] #[stable(feature = "arc_unique", since = "1.4.0")] From 335bf7ca6b2e63ffc5b7ee732819b7bf228a179e Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Tue, 24 Aug 2021 21:15:26 +0200 Subject: [PATCH 2/3] =?UTF-8?q?Clarifiy=20weak=20pointers=20being=20diasso?= =?UTF-8?q?ciated=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …noting the fact that `clone` is not called. Co-authored-by: Mark Rousskov --- library/alloc/src/rc.rs | 5 +++-- library/alloc/src/sync.rs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 90b077210a475..272fc119f4edd 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1100,8 +1100,9 @@ impl Rc { /// [`clone`] the inner value to a new allocation to ensure unique ownership. This is also /// referred to as clone-on-write. /// - /// If there are no other `Rc` pointers to this allocation, then [`Weak`] - /// pointers to this allocation will be disassociated. + /// However, if there are no other `Rc` pointers to this allocation, but some [`Weak`] + /// pointers, then the [`Weak`] pointers will be disassociated and the inner value will not + /// be cloned. /// /// See also [`get_mut`], which will fail rather than cloning. /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 7e4cb6d2c60f2..2367eaec4b938 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1350,8 +1350,9 @@ impl Arc { /// [`clone`] the inner value to a new allocation to ensure unique ownership. This is also /// referred to as clone-on-write. /// - /// If there are no other `Arc` pointers to this allocation, then [`Weak`] - /// pointers to this allocation will be disassociated. + /// However, if there are no other `Arc` pointers to this allocation, but some [`Weak`] + /// pointers, then the [`Weak`] pointers will be disassociated and the inner value will not + /// be cloned. /// /// See also [`get_mut`], which will fail rather than cloning. /// From 90354c719a94db7d393134c00b2a91bd651b5e7a Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Tue, 24 Aug 2021 21:34:12 +0200 Subject: [PATCH 3/3] Make explanations of cross-references between `make_mut` and `get_mut` more accurate --- library/alloc/src/rc.rs | 5 +++-- library/alloc/src/sync.rs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 272fc119f4edd..a9d147fa1a55c 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1011,7 +1011,7 @@ impl Rc { /// mutate a shared value. /// /// See also [`make_mut`][make_mut], which will [`clone`][clone] - /// the inner value when there are other pointers. + /// the inner value when there are other `Rc` pointers. /// /// [make_mut]: Rc::make_mut /// [clone]: Clone::clone @@ -1104,7 +1104,8 @@ impl Rc { /// pointers, then the [`Weak`] pointers will be disassociated and the inner value will not /// be cloned. /// - /// See also [`get_mut`], which will fail rather than cloning. + /// See also [`get_mut`], which will fail rather than cloning the inner value + /// or diassociating [`Weak`] pointers. /// /// [`clone`]: Clone::clone /// [`get_mut`]: Rc::get_mut diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 2367eaec4b938..a066e0b49e25c 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1354,7 +1354,8 @@ impl Arc { /// pointers, then the [`Weak`] pointers will be disassociated and the inner value will not /// be cloned. /// - /// See also [`get_mut`], which will fail rather than cloning. + /// See also [`get_mut`], which will fail rather than cloning the inner value + /// or diassociating [`Weak`] pointers. /// /// [`clone`]: Clone::clone /// [`get_mut`]: Arc::get_mut @@ -1458,7 +1459,7 @@ impl Arc { /// mutate a shared value. /// /// See also [`make_mut`][make_mut], which will [`clone`][clone] - /// the inner value when there are other pointers. + /// the inner value when there are other `Arc` pointers. /// /// [make_mut]: Arc::make_mut /// [clone]: Clone::clone