Skip to content

Commit 53ea73a

Browse files
Rollup merge of rust-lang#50837 - steveklabnik:revert-49767, r=QuietMisdreavus
Revert rust-lang#49767 There was [some confusion](rust-lang#49767 (comment)) and I accidentally merged a PR that wasn't ready.
2 parents 54df1bf + eac94d1 commit 53ea73a

File tree

2 files changed

+101
-430
lines changed

2 files changed

+101
-430
lines changed

src/libcore/intrinsics.rs

+31-130
Original file line numberDiff line numberDiff line change
@@ -962,122 +962,59 @@ extern "rust-intrinsic" {
962962
/// value is not necessarily valid to be used to actually access memory.
963963
pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
964964

965-
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
966-
/// and destination must *not* overlap.
965+
/// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
966+
/// and destination may *not* overlap.
967967
///
968-
/// For regions of memory which might overlap, use [`copy`] instead.
969-
///
970-
/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`].
971-
///
972-
/// [`copy`]: ./fn.copy.html
973-
/// [`memcpy`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memcpy
968+
/// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`.
974969
///
975970
/// # Safety
976971
///
977-
/// Behavior is undefined if any of the following conditions are violated:
978-
///
979-
/// * The region of memory which begins at `src` and has a length of
980-
/// `count * size_of::<T>()` bytes must be *both* valid and initialized.
981-
///
982-
/// * The region of memory which begins at `dst` and has a length of
983-
/// `count * size_of::<T>()` bytes must be valid (but may or may not be
984-
/// initialized).
985-
///
986-
/// * The two regions of memory must *not* overlap.
987-
///
988-
/// * `src` must be properly aligned.
989-
///
990-
/// * `dst` must be properly aligned.
991-
///
992-
/// Additionally, if `T` is not [`Copy`], only the region at `src` *or* the
993-
/// region at `dst` can be used or dropped after calling
994-
/// `copy_nonoverlapping`. `copy_nonoverlapping` creates bitwise copies of
995-
/// `T`, regardless of whether `T: Copy`, which can result in undefined
996-
/// behavior if both copies are used.
997-
///
998-
/// [`Copy`]: ../marker/trait.Copy.html
972+
/// Beyond requiring that the program must be allowed to access both regions
973+
/// of memory, it is Undefined Behavior for source and destination to
974+
/// overlap. Care must also be taken with the ownership of `src` and
975+
/// `dst`. This method semantically moves the values of `src` into `dst`.
976+
/// However it does not drop the contents of `dst`, or prevent the contents
977+
/// of `src` from being dropped or used.
999978
///
1000979
/// # Examples
1001980
///
1002-
/// Manually implement [`Vec::append`]:
981+
/// A safe swap function:
1003982
///
1004983
/// ```
984+
/// use std::mem;
1005985
/// use std::ptr;
1006986
///
1007-
/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
1008-
/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
1009-
/// let src_len = src.len();
1010-
/// let dst_len = dst.len();
1011-
///
1012-
/// // Ensure that `dst` has enough capacity to hold all of `src`.
1013-
/// dst.reserve(src_len);
1014-
///
987+
/// # #[allow(dead_code)]
988+
/// fn swap<T>(x: &mut T, y: &mut T) {
1015989
/// unsafe {
1016-
/// // The call to offset is always safe because `Vec` will never
1017-
/// // allocate more than `isize::MAX` bytes.
1018-
/// let dst = dst.as_mut_ptr().offset(dst_len as isize);
1019-
/// let src = src.as_ptr();
1020-
///
1021-
/// // The two regions cannot overlap becuase mutable references do
1022-
/// // not alias, and two different vectors cannot own the same
1023-
/// // memory.
1024-
/// ptr::copy_nonoverlapping(src, dst, src_len);
1025-
/// }
990+
/// // Give ourselves some scratch space to work with
991+
/// let mut t: T = mem::uninitialized();
1026992
///
1027-
/// unsafe {
1028-
/// // Truncate `src` without dropping its contents.
1029-
/// src.set_len(0);
993+
/// // Perform the swap, `&mut` pointers never alias
994+
/// ptr::copy_nonoverlapping(x, &mut t, 1);
995+
/// ptr::copy_nonoverlapping(y, x, 1);
996+
/// ptr::copy_nonoverlapping(&t, y, 1);
1030997
///
1031-
/// // Notify `dst` that it now holds the contents of `src`.
1032-
/// dst.set_len(dst_len + src_len);
998+
/// // y and t now point to the same thing, but we need to completely forget `t`
999+
/// // because it's no longer relevant.
1000+
/// mem::forget(t);
10331001
/// }
10341002
/// }
1035-
///
1036-
/// let mut a = vec!['r'];
1037-
/// let mut b = vec!['u', 's', 't'];
1038-
///
1039-
/// append(&mut a, &mut b);
1040-
///
1041-
/// assert_eq!(a, &['r', 'u', 's', 't']);
1042-
/// assert!(b.is_empty());
10431003
/// ```
1044-
///
1045-
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
10461004
#[stable(feature = "rust1", since = "1.0.0")]
10471005
pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
10481006

1049-
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1007+
/// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
10501008
/// and destination may overlap.
10511009
///
1052-
/// If the source and destination will *never* overlap,
1053-
/// [`copy_nonoverlapping`] can be used instead.
1054-
///
1055-
/// `copy` is semantically equivalent to C's [`memmove`].
1056-
///
1057-
/// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
1058-
/// [`memmove`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memmove
1010+
/// `copy` is semantically equivalent to C's `memmove`.
10591011
///
10601012
/// # Safety
10611013
///
1062-
/// Behavior is undefined if any of the following conditions are violated:
1063-
///
1064-
/// * The region of memory which begins at `src` and has a length of
1065-
/// `count * size_of::<T>()` bytes must be *both* valid and initialized.
1066-
///
1067-
/// * The region of memory which begins at `dst` and has a length of
1068-
/// `count * size_of::<T>()` bytes must be valid (but may or may not be
1069-
/// initialized).
1070-
///
1071-
/// * `src` must be properly aligned.
1072-
///
1073-
/// * `dst` must be properly aligned.
1074-
///
1075-
/// Additionally, if `T` is not [`Copy`], only the region at `src` *or* the
1076-
/// region at `dst` can be used or dropped after calling `copy`. `copy`
1077-
/// creates bitwise copies of `T`, regardless of whether `T: Copy`, which
1078-
/// can result in undefined behavior if both copies are used.
1079-
///
1080-
/// [`Copy`]: ../marker/trait.Copy.html
1014+
/// Care must be taken with the ownership of `src` and `dst`.
1015+
/// This method semantically moves the values of `src` into `dst`.
1016+
/// However it does not drop the contents of `dst`, or prevent the contents of `src`
1017+
/// from being dropped or used.
10811018
///
10821019
/// # Examples
10831020
///
@@ -1094,34 +1031,15 @@ extern "rust-intrinsic" {
10941031
/// dst
10951032
/// }
10961033
/// ```
1034+
///
10971035
#[stable(feature = "rust1", since = "1.0.0")]
10981036
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
10991037

1100-
/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
1101-
/// `val`.
1102-
///
1103-
/// `write_bytes` is semantically equivalent to C's [`memset`].
1104-
///
1105-
/// [`memset`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memset
1106-
///
1107-
/// # Safety
1108-
///
1109-
/// Behavior is undefined if any of the following conditions are violated:
1110-
///
1111-
/// * The region of memory which begins at `dst` and has a length of
1112-
/// `count` bytes must be valid.
1113-
///
1114-
/// * `dst` must be properly aligned.
1115-
///
1116-
/// Additionally, the caller must ensure that writing `count` bytes to the
1117-
/// given region of memory results in a valid value of `T`. Creating an
1118-
/// invalid value of `T` can result in undefined behavior. An example is
1119-
/// provided below.
1038+
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
1039+
/// bytes of memory starting at `dst` to `val`.
11201040
///
11211041
/// # Examples
11221042
///
1123-
/// Basic usage:
1124-
///
11251043
/// ```
11261044
/// use std::ptr;
11271045
///
@@ -1132,23 +1050,6 @@ extern "rust-intrinsic" {
11321050
/// }
11331051
/// assert_eq!(vec, [b'a', b'a', 0, 0]);
11341052
/// ```
1135-
///
1136-
/// Creating an invalid value:
1137-
///
1138-
/// ```no_run
1139-
/// use std::{mem, ptr};
1140-
///
1141-
/// let mut v = Box::new(0i32);
1142-
///
1143-
/// unsafe {
1144-
/// // Leaks the previously held value by overwriting the `Box<T>` with
1145-
/// // a null pointer.
1146-
/// ptr::write_bytes(&mut v, 0, mem::size_of::<Box<i32>>());
1147-
/// }
1148-
///
1149-
/// // At this point, using or dropping `v` results in undefined behavior.
1150-
/// // v = Box::new(0i32); // ERROR
1151-
/// ```
11521053
#[stable(feature = "rust1", since = "1.0.0")]
11531054
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
11541055

0 commit comments

Comments
 (0)