From dc2237c49fea94c8308f989c43f042a0cc327419 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 31 Aug 2018 17:01:53 +0200 Subject: [PATCH] apply feedback --- src/libcore/intrinsics.rs | 33 ++++++++++++++++++++------------- src/libcore/ptr.rs | 15 ++++++++------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 61d4390ebb7..927c6f26b62 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -967,10 +967,11 @@ extern "rust-intrinsic" { /// /// For regions of memory which might overlap, use [`copy`] instead. /// - /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`]. + /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but + /// with the argument order swapped. /// /// [`copy`]: ./fn.copy.html - /// [`memcpy`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memcpy + /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy /// /// # Safety /// @@ -1020,15 +1021,15 @@ extern "rust-intrinsic" { /// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize); /// let src_ptr = src.as_ptr(); /// + /// // Truncate `src` without dropping its contents. We do this first, + /// // to avoid problems in case something further down panics. + /// src.set_len(0); + /// /// // The two regions cannot overlap becuase mutable references do /// // not alias, and two different vectors cannot own the same /// // memory. /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len); /// - /// // Truncate `src` without dropping its contents. This cannot panic, - /// // so double-drops cannot happen. - /// src.set_len(0); - /// /// // Notify `dst` that it now holds the contents of `src`. /// dst.set_len(dst_len + src_len); /// } @@ -1053,12 +1054,12 @@ extern "rust-intrinsic" { /// If the source and destination will *never* overlap, /// [`copy_nonoverlapping`] can be used instead. /// - /// `copy` is semantically equivalent to C's [`memmove`]. Copying takes place as - /// if the bytes were copied from `src` to a temporary array and then copied from - /// the array to `dst`- + /// `copy` is semantically equivalent to C's [`memmove`], but with the argument + /// 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`. /// /// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html - /// [`memmove`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memmove + /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove /// /// # Safety /// @@ -1107,7 +1108,7 @@ extern "rust-intrinsic" { /// `write_bytes` is similar to C's [`memset`], but sets `count * /// size_of::()` bytes to `val`. /// - /// [`memset`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memset + /// [`memset`]: https://en.cppreference.com/w/c/string/byte/memset /// /// # Safety /// @@ -1158,8 +1159,14 @@ extern "rust-intrinsic" { /// // At this point, using or dropping `v` results in undefined behavior. /// // drop(v); // ERROR /// - /// // Leaking it does not invoke drop and is fine: - /// mem::forget(v) + /// // Even leaking `v` "uses" it, and henc eis undefined behavior. + /// // mem::forget(v); // ERROR + /// + /// // Let us instead put in a valid value + /// ptr::write(&mut v, Box::new(42i32); + /// + /// // Now the box is fine + /// assert_eq!(*v, 42); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn write_bytes(dst: *mut T, val: u8, count: usize); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index f112a96ea15..a6c3e544e16 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory - //! Manually manage memory through raw pointers. //! //! *[See also the pointer primitive types](../../std/primitive.pointer.html).* @@ -42,8 +40,10 @@ //! //! ## Alignment //! -//! Valid pointers are not necessarily properly aligned. However, most functions -//! require their arguments to be properly aligned, and will explicitly state +//! Valid pointers as defined above are not necessarily properly aligned (where +//! "proper" alignment is defind by the pointee type, i.e., `*const T` must be +//! aligned to `mem::align_of::()`). However, most functions require their +//! arguments to be properly aligned, and will explicitly state //! this requirement in their documentation. Notable exceptions to this are //! [`read_unaligned`] and [`write_unaligned`]. //! @@ -136,11 +136,12 @@ pub use intrinsics::write_bytes; /// let mut v = vec![Rc::new(0), last]; /// /// unsafe { +/// // Shorten `v` to prevent the last item from being dropped. We do that first, +/// // to prevent issues if the `drop_in_place` below panics. +/// v.set_len(1); /// // Without a call `drop_in_place`, the last item would never be dropped, /// // and the memory it manages would be leaked. /// ptr::drop_in_place(&mut v[1]); -/// // Shorten `v` to prevent the last item from being dropped. -/// v.set_len(1); /// } /// /// assert_eq!(v, &[0.into()]); @@ -745,7 +746,7 @@ pub unsafe fn write(dst: *mut T, src: T) { /// /// unsafe { /// // Take a reference to a 32-bit integer which is not aligned. -/// let unaligned = &mut x.unaligned; +/// let unaligned = &mut x.unaligned as *mut u32; /// /// // Dereferencing normally will emit an unaligned store instruction, /// // causing undefined behavior.