Skip to content

Commit 1793215

Browse files
coolreader18simlay
authored andcommitted
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".
1 parent 191c285 commit 1793215

File tree

14 files changed

+134
-24
lines changed

14 files changed

+134
-24
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

+8-2
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,15 @@ 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. Additionally, if the element type
120+
/// `T` overrides `clone_from()`, this will reuse the resources of `self`'s
121+
/// elements as well.
122+
fn clone_from(&mut self, source: &Self) {
117123
self.clear();
118-
self.extend(other.iter().cloned());
124+
self.extend(source.iter().cloned());
119125
}
120126
}
121127

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1280,8 +1280,8 @@ impl<T: Clone> Clone for RefCell<T> {
12801280
/// Panics if `other` 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)