about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-09-17 15:14:19 +0200
committerRalf Jung <post@ralfj.de>2018-09-17 15:14:19 +0200
commit2713d3667927e2633098d16c5bb764c789bc7775 (patch)
treedd9386327612962422af7f751d46d08c01abbe3b
parentc44e88cc8a75fa672ab6bdbfe76ad4323399f254 (diff)
downloadrust-2713d3667927e2633098d16c5bb764c789bc7775.tar.gz
rust-2713d3667927e2633098d16c5bb764c789bc7775.zip
tweaks
-rw-r--r--src/libcore/intrinsics.rs6
-rw-r--r--src/libcore/ptr.rs25
2 files changed, 27 insertions, 4 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 823678ec880..e6e830b1b6c 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1118,7 +1118,7 @@ extern "rust-intrinsic" {
     ///
     /// * `dst` must be properly aligned.
     ///
-    /// Additionally, the caller should ensure that writing `count *
+    /// Additionally, the caller must ensure that writing `count *
     /// size_of::<T>()` bytes to the given region of memory results in a valid
     /// value of `T`. Using a region of memory typed as a `T` that contains an
     /// invalid value of `T` is undefined behavior.
@@ -1153,7 +1153,7 @@ extern "rust-intrinsic" {
     /// unsafe {
     ///     // Leaks the previously held value by overwriting the `Box<T>` with
     ///     // a null pointer.
-    ///     ptr::write_bytes(&mut v, 0, 1);
+    ///     ptr::write_bytes(&mut v as *mut Box<i32>, 0, 1);
     /// }
     ///
     /// // At this point, using or dropping `v` results in undefined behavior.
@@ -1164,7 +1164,7 @@ extern "rust-intrinsic" {
     ///
     /// unsafe {
     ///     // Let us instead put in a valid value
-    ///     ptr::write(&mut v, Box::new(42i32));
+    ///     ptr::write(&mut v as *mut Box<i32>, Box::new(42i32));
     /// }
     ///
     /// // Now the box is fine
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index defe3d807fa..68082e3ae80 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -117,7 +117,6 @@ pub use intrinsics::write_bytes;
 ///
 /// * `to_drop` must be properly aligned.  See the example below for how to drop
 ///   an unaligned pointer.
-
 ///
 /// Additionally, if `T` is not [`Copy`], using the pointed-to value after
 /// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
@@ -185,6 +184,10 @@ pub use intrinsics::write_bytes;
 ///     mem::forget(p);
 /// }
 /// ```
+///
+/// Notice that the compiler performs this copy automatically when dropping packed structs,
+/// i.e., you do not usually have to worry about such issues unless you call `drop_in_place`
+/// manually.
 #[stable(feature = "drop_in_place", since = "1.8.0")]
 #[lang = "drop_in_place"]
 #[allow(unconditional_recursion)]
@@ -547,6 +550,9 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
 ///
 ///         // Move `tmp` into `b`.
 ///         ptr::write(b, tmp);
+///
+///         // `tmp` has been moved (`write` takes ownership of its second argument),
+///         // so nothing is dropped implicitly here.
 ///     }
 /// }
 ///
@@ -688,9 +694,26 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
 ///
 /// fn swap<T>(a: &mut T, b: &mut T) {
 ///     unsafe {
+///         // Create a bitwise copy of the value at `a` in `tmp`.
 ///         let tmp = ptr::read(a);
+///
+///         // Exiting at this point (either by explicitly returning or by
+///         // calling a function which panics) would cause the value in `tmp` to
+///         // be dropped while the same value is still referenced by `a`. This
+///         // could trigger undefined behavior if `T` is not `Copy`.
+///
+///         // Create a bitwise copy of the value at `b` in `a`.
+///         // This is safe because mutable references cannot alias.
 ///         ptr::copy_nonoverlapping(b, a, 1);
+///
+///         // As above, exiting here could trigger undefined behavior because
+///         // the same value is referenced by `a` and `b`.
+///
+///         // Move `tmp` into `b`.
 ///         ptr::write(b, tmp);
+///
+///         // `tmp` has been moved (`write` takes ownership of its second argument),
+///         // so nothing is dropped implicitly here.
 ///     }
 /// }
 ///