Skip to content

Commit 892d4f6

Browse files
authored
Unrolled build for rust-lang#122201
Rollup merge of rust-lang#122201 - coolreader18:doc-clone_from, r=dtolnay Document overrides of `clone_from()` in core/std As mentioned in rust-lang#96979 (comment) 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". I reused some of the wording over and over for similar impls, but I'm not sure that the wording is actually *good*. Would appreciate feedback about that. Also, now some of these seem to provide pretty specific guarantees about behavior (e.g. will reuse the exact same allocation iff the len is the same), but I was basing it off of the docs for [`Box::clone_from`](https://doc.rust-lang.org/1.75.0/std/boxed/struct.Box.html#method.clone_from-1) - I'm not sure if providing those strong guarantees is actually good or not.
2 parents 00ed4ed + 87db7c3 commit 892d4f6

File tree

14 files changed

+133
-25
lines changed

14 files changed

+133
-25
lines changed

library/alloc/src/boxed.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -2088,11 +2088,29 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
20882088
self.to_vec_in(alloc).into_boxed_slice()
20892089
}
20902090

2091-
fn clone_from(&mut self, other: &Self) {
2092-
if self.len() == other.len() {
2093-
self.clone_from_slice(&other);
2091+
/// Copies `source`'s contents into `self` without creating a new allocation,
2092+
/// so long as the two are of the same length.
2093+
///
2094+
/// # Examples
2095+
///
2096+
/// ```
2097+
/// let x = Box::new([5, 6, 7]);
2098+
/// let mut y = Box::new([8, 9, 10]);
2099+
/// let yp: *const [i32] = &*y;
2100+
///
2101+
/// y.clone_from(&x);
2102+
///
2103+
/// // The value is the same
2104+
/// assert_eq!(x, y);
2105+
///
2106+
/// // And no allocation occurred
2107+
/// assert_eq!(yp, &*y);
2108+
/// ```
2109+
fn clone_from(&mut self, source: &Self) {
2110+
if self.len() == source.len() {
2111+
self.clone_from_slice(&source);
20942112
} else {
2095-
*self = other.clone();
2113+
*self = source.clone();
20962114
}
20972115
}
20982116
}

library/alloc/src/collections/binary_heap/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,12 @@ impl<T: Clone, A: Allocator + Clone> Clone for BinaryHeap<T, A> {
385385
BinaryHeap { data: self.data.clone() }
386386
}
387387

388+
/// Overwrites the contents of `self` with a clone of the contents of `source`.
389+
///
390+
/// This method is preferred over simply assigning `source.clone()` to `self`,
391+
/// as it avoids reallocation if possible.
392+
///
393+
/// See [`Vec::clone_from()`] for more details.
388394
fn clone_from(&mut self, source: &Self) {
389395
self.data.clone_from(&source.data);
390396
}

library/alloc/src/collections/btree/set.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ impl<T: Clone, A: Allocator + Clone> Clone for BTreeSet<T, A> {
116116
BTreeSet { map: self.map.clone() }
117117
}
118118

119-
fn clone_from(&mut self, other: &Self) {
120-
self.map.clone_from(&other.map);
119+
fn clone_from(&mut self, source: &Self) {
120+
self.map.clone_from(&source.map);
121121
}
122122
}
123123

library/alloc/src/collections/linked_list.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -2126,16 +2126,22 @@ impl<T: Clone, A: Allocator + Clone> Clone for LinkedList<T, A> {
21262126
list
21272127
}
21282128

2129-
fn clone_from(&mut self, other: &Self) {
2130-
let mut iter_other = other.iter();
2131-
if self.len() > other.len() {
2132-
self.split_off(other.len());
2129+
/// Overwrites the contents of `self` with a clone of the contents of `source`.
2130+
///
2131+
/// This method is preferred over simply assigning `source.clone()` to `self`,
2132+
/// as it avoids reallocation of the nodes of the linked list. Additionally,
2133+
/// if the element type `T` overrides `clone_from()`, this will reuse the
2134+
/// resources of `self`'s elements as well.
2135+
fn clone_from(&mut self, source: &Self) {
2136+
let mut source_iter = source.iter();
2137+
if self.len() > source.len() {
2138+
self.split_off(source.len());
21332139
}
2134-
for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) {
2135-
elem.clone_from(elem_other);
2140+
for (elem, source_elem) in self.iter_mut().zip(&mut source_iter) {
2141+
elem.clone_from(source_elem);
21362142
}
2137-
if !iter_other.is_empty() {
2138-
self.extend(iter_other.cloned());
2143+
if !source_iter.is_empty() {
2144+
self.extend(source_iter.cloned());
21392145
}
21402146
}
21412147
}

library/alloc/src/collections/vec_deque/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,13 @@ impl<T: Clone, A: Allocator + Clone> Clone for VecDeque<T, A> {
113113
deq
114114
}
115115

116-
fn clone_from(&mut self, other: &Self) {
116+
/// Overwrites the contents of `self` with a clone of the contents of `source`.
117+
///
118+
/// This method is preferred over simply assigning `source.clone()` to `self`,
119+
/// as it avoids reallocation if possible.
120+
fn clone_from(&mut self, source: &Self) {
117121
self.clear();
118-
self.extend(other.iter().cloned());
122+
self.extend(source.iter().cloned());
119123
}
120124
}
121125

library/alloc/src/string.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,10 @@ impl Clone for String {
20972097
String { vec: self.vec.clone() }
20982098
}
20992099

2100+
/// Clones the contents of `source` into `self`.
2101+
///
2102+
/// This method is preferred over simply assigning `source.clone()` to `self`,
2103+
/// as it avoids reallocation if possible.
21002104
fn clone_from(&mut self, source: &Self) {
21012105
self.vec.clone_from(&source.vec);
21022106
}

library/alloc/src/vec/mod.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -2846,8 +2846,30 @@ impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
28462846
crate::slice::to_vec(&**self, alloc)
28472847
}
28482848

2849-
fn clone_from(&mut self, other: &Self) {
2850-
crate::slice::SpecCloneIntoVec::clone_into(other.as_slice(), self);
2849+
/// Overwrites the contents of `self` with a clone of the contents of `source`.
2850+
///
2851+
/// This method is preferred over simply assigning `source.clone()` to `self`,
2852+
/// as it avoids reallocation if possible. Additionally, if the element type
2853+
/// `T` overrides `clone_from()`, this will reuse the resources of `self`'s
2854+
/// elements as well.
2855+
///
2856+
/// # Examples
2857+
///
2858+
/// ```
2859+
/// let x = vec![5, 6, 7];
2860+
/// let mut y = vec![8, 9, 10];
2861+
/// let yp: *const i32 = y.as_ptr();
2862+
///
2863+
/// y.clone_from(&x);
2864+
///
2865+
/// // The value is the same
2866+
/// assert_eq!(x, y);
2867+
///
2868+
/// // And no reallocation occurred
2869+
/// assert_eq!(yp, y.as_ptr());
2870+
/// ```
2871+
fn clone_from(&mut self, source: &Self) {
2872+
crate::slice::SpecCloneIntoVec::clone_into(source.as_slice(), self);
28512873
}
28522874
}
28532875

library/core/src/cell.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1277,11 +1277,11 @@ impl<T: Clone> Clone for RefCell<T> {
12771277

12781278
/// # Panics
12791279
///
1280-
/// Panics if `other` is currently mutably borrowed.
1280+
/// Panics if `source` is currently mutably borrowed.
12811281
#[inline]
12821282
#[track_caller]
1283-
fn clone_from(&mut self, other: &Self) {
1284-
self.get_mut().clone_from(&other.borrow())
1283+
fn clone_from(&mut self, source: &Self) {
1284+
self.get_mut().clone_from(&source.borrow())
12851285
}
12861286
}
12871287

library/core/src/cmp.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -688,8 +688,8 @@ impl<T: Clone> Clone for Reverse<T> {
688688
}
689689

690690
#[inline]
691-
fn clone_from(&mut self, other: &Self) {
692-
self.0.clone_from(&other.0)
691+
fn clone_from(&mut self, source: &Self) {
692+
self.0.clone_from(&source.0)
693693
}
694694
}
695695

library/core/src/task/wake.rs

+36
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,42 @@ impl Clone for Waker {
576576
}
577577
}
578578

579+
/// Assigns a clone of `source` to `self`, unless [`self.will_wake(source)`][Waker::will_wake] anyway.
580+
///
581+
/// This method is preferred over simply assigning `source.clone()` to `self`,
582+
/// as it avoids cloning the waker if `self` is already the same waker.
583+
///
584+
/// # Examples
585+
///
586+
/// ```
587+
/// use std::future::Future;
588+
/// use std::pin::Pin;
589+
/// use std::sync::{Arc, Mutex};
590+
/// use std::task::{Context, Poll, Waker};
591+
///
592+
/// struct Waiter {
593+
/// shared: Arc<Mutex<Shared>>,
594+
/// }
595+
///
596+
/// struct Shared {
597+
/// waker: Waker,
598+
/// // ...
599+
/// }
600+
///
601+
/// impl Future for Waiter {
602+
/// type Output = ();
603+
/// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
604+
/// let mut shared = self.shared.lock().unwrap();
605+
///
606+
/// // update the waker
607+
/// shared.waker.clone_from(cx.waker());
608+
///
609+
/// // readiness logic ...
610+
/// # Poll::Ready(())
611+
/// }
612+
/// }
613+
///
614+
/// ```
579615
#[inline]
580616
fn clone_from(&mut self, source: &Self) {
581617
if !self.will_wake(source) {

library/std/src/collections/hash/map.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1271,8 +1271,8 @@ where
12711271
}
12721272

12731273
#[inline]
1274-
fn clone_from(&mut self, other: &Self) {
1275-
self.base.clone_from(&other.base);
1274+
fn clone_from(&mut self, source: &Self) {
1275+
self.base.clone_from(&source.base);
12761276
}
12771277
}
12781278

library/std/src/collections/hash/set.rs

+4
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,10 @@ where
978978
Self { base: self.base.clone() }
979979
}
980980

981+
/// Overwrites the contents of `self` with a clone of the contents of `source`.
982+
///
983+
/// This method is preferred over simply assigning `source.clone()` to `self`,
984+
/// as it avoids reallocation if possible.
981985
#[inline]
982986
fn clone_from(&mut self, other: &Self) {
983987
self.base.clone_from(&other.base);

library/std/src/ffi/os_str.rs

+4
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,10 @@ impl Clone for OsString {
606606
OsString { inner: self.inner.clone() }
607607
}
608608

609+
/// Clones the contents of `source` into `self`.
610+
///
611+
/// This method is preferred over simply assigning `source.clone()` to `self`,
612+
/// as it avoids reallocation if possible.
609613
#[inline]
610614
fn clone_from(&mut self, source: &Self) {
611615
self.inner.clone_from(&source.inner)

library/std/src/path.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1628,6 +1628,10 @@ impl Clone for PathBuf {
16281628
PathBuf { inner: self.inner.clone() }
16291629
}
16301630

1631+
/// Clones the contents of `source` into `self`.
1632+
///
1633+
/// This method is preferred over simply assigning `source.clone()` to `self`,
1634+
/// as it avoids reallocation if possible.
16311635
#[inline]
16321636
fn clone_from(&mut self, source: &Self) {
16331637
self.inner.clone_from(&source.inner)

0 commit comments

Comments
 (0)