about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2022-06-03 17:10:12 -0400
committerRalf Jung <post@ralfj.de>2022-06-05 10:09:42 -0400
commitcb7cd97641b7a2d1646520b7bf785934f9c6aaeb (patch)
tree6a2cd15f8d6c4c3343a08abd8785c2e14aacbccb
parentb96d1e45f188010f2cc6fff956902a455eb2178a (diff)
downloadrust-cb7cd97641b7a2d1646520b7bf785934f9c6aaeb.tar.gz
rust-cb7cd97641b7a2d1646520b7bf785934f9c6aaeb.zip
promise that ptr::copy and ptr::swap are doing untyped copies
-rw-r--r--library/core/src/intrinsics.rs6
-rw-r--r--library/core/src/ptr/mod.rs10
2 files changed, 14 insertions, 2 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 0b76790c009..9bed758c10a 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2043,6 +2043,9 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
 /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
 /// with the argument order swapped.
 ///
+/// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the
+/// requirements of `T`. The initialization state is preserved exactly.
+///
 /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
 ///
 /// # Safety
@@ -2148,6 +2151,9 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
 /// order swapped. Copying takes place as if the bytes were copied from `src`
 /// to a temporary array and then copied from the array to `dst`.
 ///
+/// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the
+/// requirements of `T`. The initialization state is preserved exactly.
+///
 /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
 ///
 /// # Safety
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 3b2b7ba8531..1035fdbf12d 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -774,7 +774,7 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
 /// Swaps the values at two mutable locations of the same type, without
 /// deinitializing either.
 ///
-/// But for the following two exceptions, this function is semantically
+/// But for the following exceptions, this function is semantically
 /// equivalent to [`mem::swap`]:
 ///
 /// * It operates on raw pointers instead of references. When references are
@@ -784,6 +784,9 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
 ///   overlapping region of memory from `x` will be used. This is demonstrated
 ///   in the second example below.
 ///
+/// * The operation is "untyped" in the sense that data may be uninitialized or otherwise violate
+///   the requirements of `T`. The initialization state is preserved exactly.
+///
 /// # Safety
 ///
 /// Behavior is undefined if any of the following conditions are violated:
@@ -860,6 +863,9 @@ pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
 /// Swaps `count * size_of::<T>()` bytes between the two regions of memory
 /// beginning at `x` and `y`. The two regions must *not* overlap.
 ///
+/// The operation is "untyped" in the sense that data may be uninitialized or otherwise violate the
+/// requirements of `T`. The initialization state is preserved exactly.
+///
 /// # Safety
 ///
 /// Behavior is undefined if any of the following conditions are violated:
@@ -965,7 +971,7 @@ const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, coun
         // SAFETY: By precondition, `i` is in-bounds because it's below `n`
         // and it's distinct from `x` since the ranges are non-overlapping
         let y = unsafe { &mut *y.add(i) };
-        mem::swap_simple(x, y);
+        mem::swap_simple::<MaybeUninit<T>>(x, y);
 
         i += 1;
     }