Skip to content

Commit ab6e108

Browse files
committed
improve Vec example soundness in mem::transmute docs
1 parent 3287a65 commit ab6e108

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

src/libcore/intrinsics.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -845,21 +845,26 @@ extern "rust-intrinsic" {
845845
///
846846
/// ```
847847
/// let store = [0, 1, 2, 3];
848-
/// let mut v_orig = store.iter().collect::<Vec<&i32>>();
848+
/// let v_orig = store.iter().collect::<Vec<&i32>>();
849+
///
850+
/// // clone the vector as we will reuse them later
851+
/// let v_clone = v_orig.clone();
849852
///
850853
/// // Using transmute: this is Undefined Behavior, and a bad idea.
851854
/// // However, it is no-copy.
852855
/// let v_transmuted = unsafe {
853-
/// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
854-
/// v_orig.clone())
856+
/// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
855857
/// };
856858
///
859+
/// let v_clone = v_orig.clone();
860+
///
857861
/// // This is the suggested, safe way.
858862
/// // It does copy the entire vector, though, into a new array.
859-
/// let v_collected = v_orig.clone()
860-
/// .into_iter()
861-
/// .map(|r| Some(r))
862-
/// .collect::<Vec<Option<&i32>>>();
863+
/// let v_collected = v_clone.into_iter()
864+
/// .map(Some)
865+
/// .collect::<Vec<Option<&i32>>>();
866+
///
867+
/// let v_clone = v_orig.clone();
863868
///
864869
/// // The no-copy, unsafe way, still using transmute, but not UB.
865870
/// // This is equivalent to the original, but safer, and reuses the
@@ -869,11 +874,12 @@ extern "rust-intrinsic" {
869874
/// // the original inner type (`&i32`) to the converted inner type
870875
/// // (`Option<&i32>`), so read the nomicon pages linked above.
871876
/// let v_from_raw = unsafe {
872-
/// Vec::from_raw_parts(v_orig.as_mut_ptr() as *mut Option<&i32>,
873-
/// v_orig.len(),
874-
/// v_orig.capacity())
877+
/// // Ensure the original vector is not dropped.
878+
/// let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
879+
/// Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,
880+
/// v_clone.len(),
881+
/// v_clone.capacity())
875882
/// };
876-
/// std::mem::forget(v_orig);
877883
/// ```
878884
///
879885
/// Implementing `split_at_mut`:

0 commit comments

Comments
 (0)