1
Fork 0

Rollup merge of #64436 - llogiq:transmute-docs, r=RalfJung

improve Vec example soundness in mem::transmute docs

The previous version of the `Vec` example had a case of questionable soundness, because at one point `v_orig` was aliased.

r? @RalfJung
This commit is contained in:
Tyler Mandry 2019-09-17 14:10:50 -07:00 committed by GitHub
commit d6f2205ed8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -845,21 +845,26 @@ extern "rust-intrinsic" {
/// ///
/// ``` /// ```
/// let store = [0, 1, 2, 3]; /// let store = [0, 1, 2, 3];
/// let mut v_orig = store.iter().collect::<Vec<&i32>>(); /// let v_orig = store.iter().collect::<Vec<&i32>>();
///
/// // 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 is Undefined Behavior, and a bad idea.
/// // However, it is no-copy. /// // However, it is no-copy.
/// let v_transmuted = unsafe { /// let v_transmuted = unsafe {
/// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>( /// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
/// v_orig.clone())
/// }; /// };
/// ///
/// let v_clone = v_orig.clone();
///
/// // This is the suggested, safe way. /// // This is the suggested, safe way.
/// // It does copy the entire vector, though, into a new array. /// // It does copy the entire vector, though, into a new array.
/// let v_collected = v_orig.clone() /// let v_collected = v_clone.into_iter()
/// .into_iter() /// .map(Some)
/// .map(|r| Some(r)) /// .collect::<Vec<Option<&i32>>>();
/// .collect::<Vec<Option<&i32>>>(); ///
/// let v_clone = v_orig.clone();
/// ///
/// // The no-copy, unsafe way, still using transmute, but not UB. /// // The no-copy, unsafe way, still using transmute, but not UB.
/// // This is equivalent to the original, but safer, and reuses the /// // This is equivalent to the original, but safer, and reuses the
@ -869,11 +874,12 @@ extern "rust-intrinsic" {
/// // the original inner type (`&i32`) to the converted inner type /// // 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.
/// let v_from_raw = unsafe { /// let v_from_raw = unsafe {
/// Vec::from_raw_parts(v_orig.as_mut_ptr() as *mut Option<&i32>, /// // Ensure the original vector is not dropped.
/// v_orig.len(), /// let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
/// v_orig.capacity()) /// Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,
/// v_clone.len(),
/// v_clone.capacity())
/// }; /// };
/// std::mem::forget(v_orig);
/// ``` /// ```
/// ///
/// Implementing `split_at_mut`: /// Implementing `split_at_mut`: