Skip to content

Commit 015bb74

Browse files
authored
Rollup merge of #69582 - RalfJung:vec-parts, r=Centril
improve transmute and Vec::from_raw_parts docs I think this fixes #64073. @Shnatsel please let me know if this is less confusing. :)
2 parents 02381db + b6e847c commit 015bb74

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

Diff for: src/liballoc/vec.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,10 @@ impl<T> Vec<T> {
404404
///
405405
/// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
406406
/// (at least, it's highly likely to be incorrect if it wasn't).
407-
/// * `ptr`'s `T` needs to have the same size and alignment as it was allocated with.
407+
/// * `T` needs to have the same size and alignment as what `ptr` was allocated with.
408+
/// (`T` having a less strict alignment is not sufficient, the alignment really
409+
/// needs to be equal to satsify the [`dealloc`] requirement that memory must be
410+
/// allocated and deallocated with the same layout.)
408411
/// * `length` needs to be less than or equal to `capacity`.
409412
/// * `capacity` needs to be the capacity that the pointer was allocated with.
410413
///
@@ -423,6 +426,7 @@ impl<T> Vec<T> {
423426
/// function.
424427
///
425428
/// [`String`]: ../../std/string/struct.String.html
429+
/// [`dealloc`]: ../../alloc/alloc/trait.GlobalAlloc.html#tymethod.dealloc
426430
///
427431
/// # Examples
428432
///

Diff for: src/libcore/intrinsics.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,8 @@ extern "rust-intrinsic" {
881881
/// // clone the vector as we will reuse them later
882882
/// let v_clone = v_orig.clone();
883883
///
884-
/// // Using transmute: this is Undefined Behavior, and a bad idea.
884+
/// // Using transmute: this relies on the unspecified data layout of `Vec`, which is a
885+
/// // bad idea and could cause Undefined Behavior.
885886
/// // However, it is no-copy.
886887
/// let v_transmuted = unsafe {
887888
/// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
@@ -897,13 +898,14 @@ extern "rust-intrinsic" {
897898
///
898899
/// let v_clone = v_orig.clone();
899900
///
900-
/// // The no-copy, unsafe way, still using transmute, but not UB.
901-
/// // This is equivalent to the original, but safer, and reuses the
902-
/// // same `Vec` internals. Therefore, the new inner type must have the
903-
/// // exact same size, and the same alignment, as the old type.
901+
/// // The no-copy, unsafe way, still using transmute, but not relying on the data layout.
902+
/// // Like the first approach, this reuses the `Vec` internals.
903+
/// // Therefore, the new inner type must have the
904+
/// // exact same size, *and the same alignment*, as the old type.
904905
/// // The same caveats exist for this method as transmute, for
905906
/// // the original inner type (`&i32`) to the converted inner type
906-
/// // (`Option<&i32>`), so read the nomicon pages linked above.
907+
/// // (`Option<&i32>`), so read the nomicon pages linked above and also
908+
/// // consult the [`from_raw_parts`] documentation.
907909
/// let v_from_raw = unsafe {
908910
// FIXME Update this when vec_into_raw_parts is stabilized
909911
/// // Ensure the original vector is not dropped.
@@ -914,6 +916,8 @@ extern "rust-intrinsic" {
914916
/// };
915917
/// ```
916918
///
919+
/// [`from_raw_parts`]: ../../std/vec/struct.Vec.html#method.from_raw_parts
920+
///
917921
/// Implementing `split_at_mut`:
918922
///
919923
/// ```

0 commit comments

Comments
 (0)