From 1a81b928e01689a726207406c554e52343fabd05 Mon Sep 17 00:00:00 2001 From: Carter Hunt Fogelman Date: Wed, 25 Oct 2023 13:51:46 -0700 Subject: [PATCH 1/2] Refactor unsafe implementation of std::mem::replace The function now defers to mem::swap, which both eliminates the use of `unsafe` in the function, and also allows it (and mem::take) to benefit from any performance enhancements to mem::swap, such as the current use of ptr::swap_nonoverlapping for large types. --- library/core/src/mem/mod.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index a79a204e2c6a0..da0048cca6e05 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -908,15 +908,9 @@ pub fn take(dest: &mut T) -> T { #[must_use = "if you don't need the old value, you can just assign the new value directly"] #[rustc_const_unstable(feature = "const_replace", issue = "83164")] #[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")] -pub const fn replace(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 - } +pub const fn replace(dest: &mut T, mut src: T) -> T { + swap(dest, &mut src); + src } /// Disposes of a value. From e1fe09cfc00df366932ae1c00c67f729598ff606 Mon Sep 17 00:00:00 2001 From: Carter Hunt Fogelman Date: Wed, 25 Oct 2023 16:24:26 -0700 Subject: [PATCH 2/2] Update aliasing_mut4 miri test --- .../miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr index 106e5c19bf277..79c6bb67efb48 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: write access through is forbidden --> RUSTLIB/core/src/mem/mod.rs:LL:CC | -LL | ptr::write(dest, src); - | ^^^^^^^^^^^^^^^^^^^^^ write access through is forbidden +LL | ptr::write(x, b); + | ^^^^^^^^^^^^^^^^ write access through is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) @@ -19,6 +19,8 @@ help: the protected tag was created here, in the initial state Frozen LL | pub fn safe(x: &i32, y: &mut Cell) { | ^ = note: BACKTRACE (of the first span): + = note: inside `std::mem::swap_simple::` at RUSTLIB/core/src/mem/mod.rs:LL:CC + = note: inside `std::mem::swap::` at RUSTLIB/core/src/mem/mod.rs:LL:CC = note: inside `std::mem::replace::` at RUSTLIB/core/src/mem/mod.rs:LL:CC = note: inside `std::cell::Cell::::replace` at RUSTLIB/core/src/cell.rs:LL:CC = note: inside `std::cell::Cell::::set` at RUSTLIB/core/src/cell.rs:LL:CC