@@ -962,59 +962,129 @@ 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 may *not* overlap.
965+ /// Copies `count * size_of:: <T>() ` bytes from `src` to `dst`. The source
966+ /// and destination must *not* overlap.
967967 ///
968- /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`.
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
969974 ///
970975 /// # Safety
971976 ///
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.
977+ /// Behavior is undefined if any of the following conditions are violated:
978+ ///
979+ /// * Both `src` and `dst` must be [valid].
980+ ///
981+ /// * Both `src` and `dst` must be properly aligned.
982+ ///
983+ /// * `src.offset(count)` must be [valid]. In other words, the region of
984+ /// memory which begins at `src` and has a length of `count *
985+ /// size_of::<T>()` bytes must belong to a single, live allocation.
986+ ///
987+ /// * `dst.offset(count)` must be [valid]. In other words, the region of
988+ /// memory which begins at `dst` and has a length of `count *
989+ /// size_of::<T>()` bytes must belong to a single, live allocation.
990+ ///
991+ /// * The two regions of memory must *not* overlap.
992+ ///
993+ /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
994+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
995+ /// in the region beginning at `*src` and the region beginning at `*dst` can
996+ /// [violate memory safety][read-ownership].
997+ ///
998+ /// [`Copy`]: ../marker/trait.Copy.html
999+ /// [`read`]: ../ptr/fn.read.html
1000+ /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
1001+ /// [valid]: ../ptr/index.html#safety
9781002 ///
9791003 /// # Examples
9801004 ///
981- /// A safe swap function :
1005+ /// Manually implement [`Vec::append`] :
9821006 ///
9831007 /// ```
984- /// use std::mem;
9851008 /// use std::ptr;
9861009 ///
987- /// # #[allow(dead_code)]
988- /// fn swap<T>(x: &mut T, y: &mut T) {
1010+ /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
1011+ /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
1012+ /// let src_len = src.len();
1013+ /// let dst_len = dst.len();
1014+ ///
1015+ /// // Ensure that `dst` has enough capacity to hold all of `src`.
1016+ /// dst.reserve(src_len);
1017+ ///
9891018 /// unsafe {
990- /// // Give ourselves some scratch space to work with
991- /// let mut t: T = mem::uninitialized();
1019+ /// // The call to offset is always safe because `Vec` will never
1020+ /// // allocate more than `isize::MAX` bytes.
1021+ /// let dst = dst.as_mut_ptr().offset(dst_len as isize);
1022+ /// let src = src.as_ptr();
1023+ ///
1024+ /// // The two regions cannot overlap becuase mutable references do
1025+ /// // not alias, and two different vectors cannot own the same
1026+ /// // memory.
1027+ /// ptr::copy_nonoverlapping(src, dst, src_len);
1028+ /// }
9921029 ///
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);
1030+ /// unsafe {
1031+ /// // Truncate `src` without dropping its contents.
1032+ /// src.set_len(0);
9971033 ///
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);
1034+ /// // Notify `dst` that it now holds the contents of `src`.
1035+ /// dst.set_len(dst_len + src_len);
10011036 /// }
10021037 /// }
1038+ ///
1039+ /// let mut a = vec!['r'];
1040+ /// let mut b = vec!['u', 's', 't'];
1041+ ///
1042+ /// append(&mut a, &mut b);
1043+ ///
1044+ /// assert_eq!(a, &['r', 'u', 's', 't']);
1045+ /// assert!(b.is_empty());
10031046 /// ```
1047+ ///
1048+ /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
10041049 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
10051050 pub fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) ;
10061051
1007- /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
1052+ /// Copies `count * size_of:: <T>() ` bytes from `src` to `dst`. The source
10081053 /// and destination may overlap.
10091054 ///
1010- /// `copy` is semantically equivalent to C's `memmove`.
1055+ /// If the source and destination will *never* overlap,
1056+ /// [`copy_nonoverlapping`] can be used instead.
1057+ ///
1058+ /// `copy` is semantically equivalent to C's [`memmove`].
1059+ ///
1060+ /// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
1061+ /// [`memmove`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memmove
10111062 ///
10121063 /// # Safety
10131064 ///
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.
1065+ /// Behavior is undefined if any of the following conditions are violated:
1066+ ///
1067+ /// * Both `src` and `dst` must be [valid].
1068+ ///
1069+ /// * Both `src` and `dst` must be properly aligned.
1070+ ///
1071+ /// * `src.offset(count)` must be [valid]. In other words, the region of
1072+ /// memory which begins at `src` and has a length of `count *
1073+ /// size_of::<T>()` bytes must belong to a single, live allocation.
1074+ ///
1075+ /// * `dst.offset(count)` must be [valid]. In other words, the region of
1076+ /// memory which begins at `dst` and has a length of `count *
1077+ /// size_of::<T>()` bytes must belong to a single, live allocation.
1078+ ///
1079+ /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
1080+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
1081+ /// in the region beginning at `*src` and the region beginning at `*dst` can
1082+ /// [violate memory safety][read-ownership].
1083+ ///
1084+ /// [`Copy`]: ../marker/trait.Copy.html
1085+ /// [`read`]: ../ptr/fn.read.html
1086+ /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
1087+ /// [valid]: ../ptr/index.html#safety
10181088 ///
10191089 /// # Examples
10201090 ///
@@ -1031,24 +1101,66 @@ extern "rust-intrinsic" {
10311101 /// dst
10321102 /// }
10331103 /// ```
1034- ///
10351104 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
10361105 pub fn copy < T > ( src : * const T , dst : * mut T , count : usize ) ;
10371106
1038- /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
1039- /// bytes of memory starting at `dst` to `val`.
1107+ /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
1108+ /// `val`.
1109+ ///
1110+ /// `write_bytes` is similar to C's [`memset`], but sets `count *
1111+ /// size_of::<T>()` bytes to `val`.
1112+ ///
1113+ /// [`memset`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memset
1114+ ///
1115+ /// # Safety
1116+ ///
1117+ /// Behavior is undefined if any of the following conditions are violated:
1118+ ///
1119+ /// * `dst` must be [valid].
1120+ ///
1121+ /// * `dst.offset(count)` must be [valid]. In other words, the region of
1122+ /// memory which begins at `dst` and has a length of `count *
1123+ /// size_of::<T>()` bytes must belong to a single, live allocation.
1124+ ///
1125+ /// * `dst` must be properly aligned.
1126+ ///
1127+ /// Additionally, the caller must ensure that writing `count *
1128+ /// size_of::<T>()` bytes to the given region of memory results in a valid
1129+ /// value of `T`. Creating an invalid value of `T` can result in undefined
1130+ /// behavior.
1131+ ///
1132+ /// [valid]: ../ptr/index.html#safety
10401133 ///
10411134 /// # Examples
10421135 ///
1136+ /// Basic usage:
1137+ ///
10431138 /// ```
10441139 /// use std::ptr;
10451140 ///
1046- /// let mut vec = vec![0 ; 4];
1141+ /// let mut vec = vec![0u32 ; 4];
10471142 /// unsafe {
10481143 /// let vec_ptr = vec.as_mut_ptr();
1049- /// ptr::write_bytes(vec_ptr, b'a' , 2);
1144+ /// ptr::write_bytes(vec_ptr, 0xfe , 2);
10501145 /// }
1051- /// assert_eq!(vec, [b'a', b'a', 0, 0]);
1146+ /// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
1147+ /// ```
1148+ ///
1149+ /// Creating an invalid value:
1150+ ///
1151+ /// ```no_run
1152+ /// use std::{mem, ptr};
1153+ ///
1154+ /// let mut v = Box::new(0i32);
1155+ ///
1156+ /// unsafe {
1157+ /// // Leaks the previously held value by overwriting the `Box<T>` with
1158+ /// // a null pointer.
1159+ /// ptr::write_bytes(&mut v, 0, 1);
1160+ /// }
1161+ ///
1162+ /// // At this point, using or dropping `v` results in undefined behavior.
1163+ /// // v = Box::new(0i32); // ERROR
10521164 /// ```
10531165 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
10541166 pub fn write_bytes < T > ( dst : * mut T , val : u8 , count : usize ) ;
0 commit comments