about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2021-03-11 19:04:47 +0100
committerMara Bos <m-ou.se@m-ou.se>2021-03-11 19:04:47 +0100
commitbf27819f37fb7cbe5fb67972d874ab285b741538 (patch)
treec96cb144c5b6148d9adfbcbf55ccc9ffd65fe8fd
parent1d6b0f626aad4ee9f2eaec4d5582f45620ccab80 (diff)
downloadrust-bf27819f37fb7cbe5fb67972d874ab285b741538.tar.gz
rust-bf27819f37fb7cbe5fb67972d874ab285b741538.zip
Don't implement mem::replace with mem::swap.
-rw-r--r--library/core/src/mem/mod.rs12
1 files changed, 9 insertions, 3 deletions
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index afce6e55b8f..84edbd30a5d 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -812,9 +812,15 @@ pub fn take<T: Default>(dest: &mut T) -> T {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[must_use = "if you don't need the old value, you can just assign the new value directly"]
-pub fn replace<T>(dest: &mut T, mut src: T) -> T {
-    swap(dest, &mut src);
-    src
+pub fn replace<T>(dest: &mut T, src: T) -> T {
+    // SAFETY: We read from `dest` but directly write `src` into it afterwards,
+    // such that the old value is not duplicated. Nothing is dropped and
+    // nothing here can panic.
+    unsafe {
+        let result = ptr::read(dest);
+        ptr::write(dest, src);
+        result
+    }
 }
 
 /// Disposes of a value.