Skip to content

Commit 46a934a

Browse files
committed
Auto merge of #83022 - m-ou-se:mem-replace-no-swap, r=nagisa
Don't implement mem::replace with mem::swap. `swap` is a complicated operation, so this changes the implementation of `replace` to use `read` and `write` instead. See #83019. I wrote there: > Implementing the simpler operation (replace) with the much more complicated operation (swap) doesn't make a whole lot of sense. `replace` is just read+write, and the primitive for moving out of a `&mut`. `swap` is for doing that to *two* `&mut` at the same time, which is both more niche and more complicated (as shown by `swap_nonoverlapping_bytes`). This could be especially interesting for `Option<VeryLargeStruct>::take()`, since swapping such a large structure with `swap_nonoverlapping_bytes` is going to be much less efficient than `ptr::write()`'ing a `None`. But also for small values where `swap` just reads/writes using temporary variable, this makes a `replace` or `take` operation simpler: ![image](https://user-images.githubusercontent.com/783247/110839393-c7e6bd80-82a3-11eb-97b7-28acb14deffd.png)
2 parents b3e19a2 + bf27819 commit 46a934a

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

library/core/src/mem/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -812,9 +812,15 @@ pub fn take<T: Default>(dest: &mut T) -> T {
812812
#[inline]
813813
#[stable(feature = "rust1", since = "1.0.0")]
814814
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
815-
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
816-
swap(dest, &mut src);
817-
src
815+
pub fn replace<T>(dest: &mut T, src: T) -> T {
816+
// SAFETY: We read from `dest` but directly write `src` into it afterwards,
817+
// such that the old value is not duplicated. Nothing is dropped and
818+
// nothing here can panic.
819+
unsafe {
820+
let result = ptr::read(dest);
821+
ptr::write(dest, src);
822+
result
823+
}
818824
}
819825

820826
/// Disposes of a value.

0 commit comments

Comments
 (0)