Skip to content

Commit d0ce391

Browse files
committed
swap_simple no longer needs to be a separate function
1 parent 6d2cb39 commit d0ce391

File tree

3 files changed

+18
-37
lines changed

3 files changed

+18
-37
lines changed

library/core/src/mem/mod.rs

-32
Original file line numberDiff line numberDiff line change
@@ -731,38 +731,6 @@ pub const fn swap<T>(x: &mut T, y: &mut T) {
731731
unsafe { intrinsics::typed_swap(x, y) }
732732
}
733733

734-
/// Same as [`swap`] semantically, but always uses the simple implementation.
735-
///
736-
/// Used elsewhere in `mem` and `ptr` at the bottom layer of calls.
737-
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
738-
#[inline]
739-
pub(crate) const fn swap_simple<T>(x: &mut T, y: &mut T) {
740-
// We arrange for this to typically be called with small types,
741-
// so this reads-and-writes approach is actually better than using
742-
// copy_nonoverlapping as it easily puts things in LLVM registers
743-
// directly and doesn't end up inlining allocas.
744-
// And LLVM actually optimizes it to 3×memcpy if called with
745-
// a type larger than it's willing to keep in a register.
746-
// Having typed reads and writes in MIR here is also good as
747-
// it lets Miri and CTFE understand them better, including things
748-
// like enforcing type validity for them.
749-
// Importantly, read+copy_nonoverlapping+write introduces confusing
750-
// asymmetry to the behaviour where one value went through read+write
751-
// whereas the other was copied over by the intrinsic (see #94371).
752-
// Furthermore, using only read+write here benefits limited backends
753-
// such as SPIR-V that work on an underlying *typed* view of memory,
754-
// and thus have trouble with Rust's untyped memory operations.
755-
756-
// SAFETY: exclusive references are always valid to read/write,
757-
// including being aligned, and nothing here panics so it's drop-safe.
758-
unsafe {
759-
let a = ptr::read(x);
760-
let b = ptr::read(y);
761-
ptr::write(x, b);
762-
ptr::write(y, a);
763-
}
764-
}
765-
766734
/// Replaces `dest` with the default value of `T`, returning the previous `dest` value.
767735
///
768736
/// * If you want to replace the values of two variables, see [`swap`].

library/core/src/ptr/mod.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -1062,11 +1062,26 @@ const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, coun
10621062
let mut i = 0;
10631063
while i < count {
10641064
// SAFETY: By precondition, `i` is in-bounds because it's below `n`
1065-
let x = unsafe { &mut *x.add(i) };
1065+
let x = unsafe { x.add(i) };
10661066
// SAFETY: By precondition, `i` is in-bounds because it's below `n`
10671067
// and it's distinct from `x` since the ranges are non-overlapping
1068-
let y = unsafe { &mut *y.add(i) };
1069-
mem::swap_simple::<MaybeUninit<T>>(x, y);
1068+
let y = unsafe { y.add(i) };
1069+
1070+
// If we end up here, it's because we're using a simple type -- like
1071+
// a small power-of-two-sized thing -- or a special type with particularly
1072+
// large alignment, particularly SIMD types.
1073+
// Thus we're fine just reading-and-writing it, as either it's small
1074+
// and that works well anyway or it's special and the type's author
1075+
// presumably wanted things to be done in the larger chunk.
1076+
1077+
// SAFETY: we're only ever given pointers that are valid to read/write,
1078+
// including being aligned, and nothing here panics so it's drop-safe.
1079+
unsafe {
1080+
let a: MaybeUninit<T> = read(x);
1081+
let b: MaybeUninit<T> = read(y);
1082+
write(x, b);
1083+
write(y, a);
1084+
}
10701085

10711086
i += 1;
10721087
}

tests/ui/consts/missing_span_in_backtrace.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ error[E0080]: evaluation of constant value failed
55
|
66
note: inside `std::ptr::read::<MaybeUninit<MaybeUninit<u8>>>`
77
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
8-
note: inside `mem::swap_simple::<MaybeUninit<MaybeUninit<u8>>>`
9-
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
108
note: inside `std::ptr::swap_nonoverlapping_simple_untyped::<MaybeUninit<u8>>`
119
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
1210
note: inside `swap_nonoverlapping::<MaybeUninit<u8>>`

0 commit comments

Comments
 (0)