From 51d598ec285fc8aa29e2a1c64dc90394ccbd4130 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Thu, 19 Aug 2021 12:35:20 +0200 Subject: [PATCH] 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 0b3079fa59d..90b077210a4 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 3183a6db410..7e4cb6d2c60 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")]