about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-02-29 18:54:04 +0100
committerGitHub <noreply@github.com>2020-02-29 18:54:04 +0100
commit015bb74650f80de4411b8d12d897fad9ed35a915 (patch)
tree487b5cd77158c4d80e355943a858923451b4d496
parent02381db8e0cd4412bec4254fd78e140e7b036fa7 (diff)
parentb6e847cc983c3e4d4ab96b026cea6743db00a133 (diff)
downloadrust-015bb74650f80de4411b8d12d897fad9ed35a915.tar.gz
rust-015bb74650f80de4411b8d12d897fad9ed35a915.zip
Rollup merge of #69582 - RalfJung:vec-parts, r=Centril
improve transmute and Vec::from_raw_parts docs

I think this fixes https://github.com/rust-lang/rust/issues/64073. @Shnatsel please let me know if this is less confusing. :)
-rw-r--r--src/liballoc/vec.rs6
-rw-r--r--src/libcore/intrinsics.rs16
2 files changed, 15 insertions, 7 deletions
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 29987ac44e6..fc50d06b33c 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -404,7 +404,10 @@ impl<T> Vec<T> {
     ///
     /// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
     ///   (at least, it's highly likely to be incorrect if it wasn't).
-    /// * `ptr`'s `T` needs to have the same size and alignment as it was allocated with.
+    /// * `T` needs to have the same size and alignment as what `ptr` was allocated with.
+    ///   (`T` having a less strict alignment is not sufficient, the alignment really
+    ///   needs to be equal to satsify the [`dealloc`] requirement that memory must be
+    ///   allocated and deallocated with the same layout.)
     /// * `length` needs to be less than or equal to `capacity`.
     /// * `capacity` needs to be the capacity that the pointer was allocated with.
     ///
@@ -423,6 +426,7 @@ impl<T> Vec<T> {
     /// function.
     ///
     /// [`String`]: ../../std/string/struct.String.html
+    /// [`dealloc`]: ../../alloc/alloc/trait.GlobalAlloc.html#tymethod.dealloc
     ///
     /// # Examples
     ///
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 94928211a97..fca2c3d31d9 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -881,7 +881,8 @@ extern "rust-intrinsic" {
     /// // clone the vector as we will reuse them later
     /// let v_clone = v_orig.clone();
     ///
-    /// // Using transmute: this is Undefined Behavior, and a bad idea.
+    /// // Using transmute: this relies on the unspecified data layout of `Vec`, which is a
+    /// // bad idea and could cause Undefined Behavior.
     /// // However, it is no-copy.
     /// let v_transmuted = unsafe {
     ///     std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
@@ -897,13 +898,14 @@ extern "rust-intrinsic" {
     ///
     /// let v_clone = v_orig.clone();
     ///
-    /// // The no-copy, unsafe way, still using transmute, but not UB.
-    /// // This is equivalent to the original, but safer, and reuses the
-    /// // same `Vec` internals. Therefore, the new inner type must have the
-    /// // exact same size, and the same alignment, as the old type.
+    /// // The no-copy, unsafe way, still using transmute, but not relying on the data layout.
+    /// // Like the first approach, this reuses the `Vec` internals.
+    /// // Therefore, the new inner type must have the
+    /// // exact same size, *and the same alignment*, as the old type.
     /// // The same caveats exist for this method as transmute, for
     /// // the original inner type (`&i32`) to the converted inner type
-    /// // (`Option<&i32>`), so read the nomicon pages linked above.
+    /// // (`Option<&i32>`), so read the nomicon pages linked above and also
+    /// // consult the [`from_raw_parts`] documentation.
     /// let v_from_raw = unsafe {
     // FIXME Update this when vec_into_raw_parts is stabilized
     ///     // Ensure the original vector is not dropped.
@@ -914,6 +916,8 @@ extern "rust-intrinsic" {
     /// };
     /// ```
     ///
+    /// [`from_raw_parts`]: ../../std/vec/struct.Vec.html#method.from_raw_parts
+    ///
     /// Implementing `split_at_mut`:
     ///
     /// ```