about summary refs log tree commit diff
path: root/library/alloc/src/vec/mod.rs
diff options
context:
space:
mode:
authorJP Posma <janpaul123@users.noreply.github.com>2022-03-16 09:34:12 -0700
committerGitHub <noreply@github.com>2022-03-16 09:34:12 -0700
commit80340f62fee46c1ac5ea787e4dcbe553c6abd41a (patch)
tree7256127b11375cf0bd94324fa5862cd48035b7eb /library/alloc/src/vec/mod.rs
parent461e8078010433ff7de2db2aaae8a3cfb0847215 (diff)
downloadrust-80340f62fee46c1ac5ea787e4dcbe553c6abd41a.tar.gz
rust-80340f62fee46c1ac5ea787e4dcbe553c6abd41a.zip
Docs: make Vec::from_raw_parts documentation less strict
This is my first PR; be gentle!

In https://users.rust-lang.org/t/why-does-vec-from-raw-parts-require-same-size-and-not-same-size-capacity/73036/2?u=janpaul123 it was suggested to me that I should make a PR to make the documentation of `Vec::from_raw_parts` less strict, since we don't require `T` to have the same size, just `size_of::<T>() * capacity` to be the same, since that is what results in `Layout::size` being the same in `dealloc`, which is really what matters.

Also in https://users.rust-lang.org/t/why-does-vec-from-raw-parts-require-same-size-and-not-same-size-capacity/73036/8?u=janpaul123 it was suggested that it's better to use `slice::from_raw_parts`, which I think is useful advise that could also be mentioned in the docs, so I added that too.

Let me know what you think! :)
Diffstat (limited to 'library/alloc/src/vec/mod.rs')
-rw-r--r--library/alloc/src/vec/mod.rs10
1 files changed, 7 insertions, 3 deletions
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 5131168db0c..13d13a9d7d1 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -479,12 +479,14 @@ 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).
-    /// * `T` needs to have the same size and alignment as what `ptr` was allocated with.
+    /// * `T` needs to have the same alignment as what `ptr` was allocated with.
     ///   (`T` having a less strict alignment is not sufficient, the alignment really
     ///   needs to be equal to satisfy the [`dealloc`] requirement that memory must be
     ///   allocated and deallocated with the same layout.)
+    /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
+    ///   to be the same size as the pointer was allocated with. (Because similar to
+    ///   alignment, [`dealloc`] must be called with the same layout `size`.)
     /// * `length` needs to be less than or equal to `capacity`.
-    /// * `capacity` needs to be the capacity that the pointer was allocated with.
     ///
     /// Violating these may cause problems like corrupting the allocator's
     /// internal data structures. For example it is **not** safe
@@ -492,7 +494,9 @@ impl<T> Vec<T> {
     /// It's also not safe to build one from a `Vec<u16>` and its length, because
     /// the allocator cares about the alignment, and these two types have different
     /// alignments. The buffer was allocated with alignment 2 (for `u16`), but after
-    /// turning it into a `Vec<u8>` it'll be deallocated with alignment 1.
+    /// turning it into a `Vec<u8>` it'll be deallocated with alignment 1. To avoid
+    /// these issues, it is often preferable to do casting/transmuting using
+    /// [`slice::from_raw_parts`] instead.
     ///
     /// The ownership of `ptr` is effectively transferred to the
     /// `Vec<T>` which may then deallocate, reallocate or change the