From c0e913fdd7f35b197c6da198c25569fc63244b85 Mon Sep 17 00:00:00 2001 From: Noa Date: Fri, 8 Mar 2024 12:27:24 -0600 Subject: [PATCH 01/12] Document overrides of `clone_from()` Specifically, when an override doesn't just forward to an inner type, document the behavior and that it's preferred over simply assigning a clone of source. Also, change instances where the second parameter is "other" to "source". --- library/alloc/src/boxed.rs | 26 +++++++++++--- .../alloc/src/collections/binary_heap/mod.rs | 6 ++++ library/alloc/src/collections/btree/set.rs | 4 +-- library/alloc/src/collections/linked_list.rs | 22 +++++++----- .../alloc/src/collections/vec_deque/mod.rs | 10 ++++-- library/alloc/src/string.rs | 4 +++ library/alloc/src/vec/mod.rs | 26 ++++++++++++-- library/core/src/cell.rs | 4 +-- library/core/src/cmp.rs | 4 +-- library/core/src/task/wake.rs | 36 +++++++++++++++++++ library/std/src/collections/hash/map.rs | 4 +-- library/std/src/collections/hash/set.rs | 4 +++ library/std/src/ffi/os_str.rs | 4 +++ library/std/src/path.rs | 4 +++ 14 files changed, 134 insertions(+), 24 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 2736e5ee6c588..91247e7ad4c2d 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2084,11 +2084,29 @@ impl Clone for Box<[T], A> { self.to_vec_in(alloc).into_boxed_slice() } - fn clone_from(&mut self, other: &Self) { - if self.len() == other.len() { - self.clone_from_slice(&other); + /// Copies `source`'s contents into `self` without creating a new allocation, + /// so long as the two are of the same length. + /// + /// # Examples + /// + /// ``` + /// let x = Box::new([5, 6, 7]); + /// let mut y = Box::new([8, 9, 10]); + /// let yp: *const [i32] = &*y; + /// + /// y.clone_from(&x); + /// + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // And no allocation occurred + /// assert_eq!(yp, &*y); + /// ``` + fn clone_from(&mut self, source: &Self) { + if self.len() == source.len() { + self.clone_from_slice(&source); } else { - *self = other.clone(); + *self = source.clone(); } } } diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 83b2678f7f52d..c54f0062824a1 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -385,6 +385,12 @@ impl Clone for BinaryHeap { BinaryHeap { data: self.data.clone() } } + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. + /// + /// See [`Vec::clone_from()`] for more details. fn clone_from(&mut self, source: &Self) { self.data.clone_from(&source.data); } diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index ed91ae1a66e3d..2d42de4747cbd 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -116,8 +116,8 @@ impl Clone for BTreeSet { BTreeSet { map: self.map.clone() } } - fn clone_from(&mut self, other: &Self) { - self.map.clone_from(&other.map); + fn clone_from(&mut self, source: &Self) { + self.map.clone_from(&source.map); } } diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 6dfb82ac807a0..1c90c171a155b 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -2126,16 +2126,22 @@ impl Clone for LinkedList { list } - fn clone_from(&mut self, other: &Self) { - let mut iter_other = other.iter(); - if self.len() > other.len() { - self.split_off(other.len()); + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation of the nodes of the linked list. Additionally, + /// if the element type `T` overrides `clone_from()`, this will reuse the + /// resources of `self`'s elements as well. + fn clone_from(&mut self, source: &Self) { + let mut source_iter = source.iter(); + if self.len() > source.len() { + self.split_off(source.len()); } - for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) { - elem.clone_from(elem_other); + for (elem, source_elem) in self.iter_mut().zip(&mut source_iter) { + elem.clone_from(source_elem); } - if !iter_other.is_empty() { - self.extend(iter_other.cloned()); + if !source_iter.is_empty() { + self.extend(source_iter.cloned()); } } } diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index c35bab5ef6657..8df7ca3411d67 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -113,9 +113,15 @@ impl Clone for VecDeque { deq } - fn clone_from(&mut self, other: &Self) { + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. Additionally, if the element type + /// `T` overrides `clone_from()`, this will reuse the resources of `self`'s + /// elements as well. + fn clone_from(&mut self, source: &Self) { self.clear(); - self.extend(other.iter().cloned()); + self.extend(source.iter().cloned()); } } diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 98ded7f6cdf5b..fd36583ec8e8b 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2084,6 +2084,10 @@ impl Clone for String { String { vec: self.vec.clone() } } + /// Clones the contents of `source` into `self`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. fn clone_from(&mut self, source: &Self) { self.vec.clone_from(&source.vec); } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index c0e934b3b1fcb..b8ed9710839ae 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2758,8 +2758,30 @@ impl Clone for Vec { crate::slice::to_vec(&**self, alloc) } - fn clone_from(&mut self, other: &Self) { - crate::slice::SpecCloneIntoVec::clone_into(other.as_slice(), self); + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. Additionally, if the element type + /// `T` overrides `clone_from()`, this will reuse the resources of `self`'s + /// elements as well. + /// + /// # Examples + /// + /// ``` + /// let x = vec![5, 6, 7]; + /// let mut y = vec![8, 9, 10]; + /// let yp: *const i32 = y.as_ptr(); + /// + /// y.clone_from(&x); + /// + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // And no reallocation occurred + /// assert_eq!(yp, y.as_ptr()); + /// ``` + fn clone_from(&mut self, source: &Self) { + crate::slice::SpecCloneIntoVec::clone_into(source.as_slice(), self); } } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 19b05448c8780..835edc4424d8b 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1276,8 +1276,8 @@ impl Clone for RefCell { /// Panics if `other` is currently mutably borrowed. #[inline] #[track_caller] - fn clone_from(&mut self, other: &Self) { - self.get_mut().clone_from(&other.borrow()) + fn clone_from(&mut self, source: &Self) { + self.get_mut().clone_from(&source.borrow()) } } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index a2f07814726ac..500fd5ef5c3a8 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -684,8 +684,8 @@ impl Clone for Reverse { } #[inline] - fn clone_from(&mut self, other: &Self) { - self.0.clone_from(&other.0) + fn clone_from(&mut self, source: &Self) { + self.0.clone_from(&source.0) } } diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 8fc942dedc9be..7ce9693576e7d 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -515,6 +515,42 @@ impl Clone for Waker { } } + /// Assigns a clone of `source` to `self`, unless [`self.will_wake(source)`][Waker::will_wake] anyway. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids cloning the waker if `self` is already the same waker. + /// + /// # Examples + /// + /// ``` + /// use std::future::Future; + /// use std::pin::Pin; + /// use std::sync::{Arc, Mutex}; + /// use std::task::{Context, Poll, Waker}; + /// + /// struct Waiter { + /// shared: Arc>, + /// } + /// + /// struct Shared { + /// waker: Waker, + /// // ... + /// } + /// + /// impl Future for Waiter { + /// type Output = (); + /// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + /// let mut shared = self.shared.lock().unwrap(); + /// + /// // update the waker + /// shared.waker.clone_from(cx.waker()); + /// + /// // readiness logic ... + /// # Poll::Ready(()) + /// } + /// } + /// + /// ``` #[inline] fn clone_from(&mut self, source: &Self) { if !self.will_wake(source) { diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 627befb63a1bb..7ec4d4829e5b6 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1271,8 +1271,8 @@ where } #[inline] - fn clone_from(&mut self, other: &Self) { - self.base.clone_from(&other.base); + fn clone_from(&mut self, source: &Self) { + self.base.clone_from(&source.base); } } diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 371201ff44cbe..fffbfe477e2b1 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -978,6 +978,10 @@ where Self { base: self.base.clone() } } + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. #[inline] fn clone_from(&mut self, other: &Self) { self.base.clone_from(&other.base); diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index e44da8e637e98..ef7976d2c5015 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -606,6 +606,10 @@ impl Clone for OsString { OsString { inner: self.inner.clone() } } + /// Clones the contents of `source` into `self`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. #[inline] fn clone_from(&mut self, source: &Self) { self.inner.clone_from(&source.inner) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 56ea51226f9d5..51cbb1a0f12e6 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1628,6 +1628,10 @@ impl Clone for PathBuf { PathBuf { inner: self.inner.clone() } } + /// Clones the contents of `source` into `self`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. #[inline] fn clone_from(&mut self, source: &Self) { self.inner.clone_from(&source.inner) From 8f3d7fe0388c433008a91da14ef92de9a338b237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 19 Oct 2023 23:15:21 +0200 Subject: [PATCH 02/12] meta: notify #t-rustdoc Zulip stream on backport nominations --- triagebot.toml | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index b96225c452059..f92f800ea9ebb 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -417,6 +417,54 @@ message_on_remove = "Issue #{number}'s prioritization request has been removed." message_on_close = "Issue #{number} has been closed while requested for prioritization." message_on_reopen = "Issue #{number} has been reopened." +# FIXME: Patch triagebot to support `notify-zulip.