diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 5244e478018..4ec49a6d0b9 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -728,10 +728,6 @@ pub const fn swap(x: &mut T, y: &mut T) { // reinterpretation of values as (chunkable) byte arrays, and the loop in the // block optimization in `swap_slice` is hard to rewrite back // into the (unoptimized) direct swapping implementation, so we disable it. - // FIXME(eddyb) the block optimization also prevents MIR optimizations from - // understanding `mem::replace`, `Option::take`, etc. - a better overall - // solution might be to make `ptr::swap_nonoverlapping` into an intrinsic, which - // a backend can choose to implement using the block optimization, or not. #[cfg(not(any(target_arch = "spirv")))] { // For types that are larger multiples of their alignment, the simple way @@ -768,11 +764,14 @@ pub(crate) const fn swap_simple(x: &mut T, y: &mut T) { // And LLVM actually optimizes it to 3Ă—memcpy if called with // a type larger than it's willing to keep in a register. // Having typed reads and writes in MIR here is also good as - // it lets MIRI and CTFE understand them better, including things + // it lets Miri and CTFE understand them better, including things // like enforcing type validity for them. // Importantly, read+copy_nonoverlapping+write introduces confusing // asymmetry to the behaviour where one value went through read+write // whereas the other was copied over by the intrinsic (see #94371). + // Furthermore, using only read+write here benefits limited backends + // such as SPIR-V that work on an underlying *typed* view of memory, + // and thus have trouble with Rust's untyped memory operations. // SAFETY: exclusive references are always valid to read/write, // including being aligned, and nothing here panics so it's drop-safe.