From 377bbfe96b9d5f20ca6aec84f68ad8161f307ab5 Mon Sep 17 00:00:00 2001 From: ubsan Date: Sat, 2 Jul 2016 08:45:01 -0700 Subject: [PATCH] Add a new alternative --- src/libcore/intrinsics.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index d2bf9d94399..5bd35ae1ac2 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -346,6 +346,29 @@ extern "rust-intrinsic" { /// assert_eq!(b"Rust", [82, 117, 116, 116]); /// /// + /// // Turning a Vec<&T> into a Vec> + /// let store = [0, 1, 2, 3]; + /// let v_orig = store.iter().collect::>(); + /// // Using transmute; Undefined Behavior + /// let v_transmuted = mem::transmute::, Vec>>( + /// v_orig); + /// // The suggested, safe way + /// let v_collected = v_orig.into_iter() + /// .map(|r| Some(r)) + /// .collect::>>(); + /// // The no-copy, unsafe way, still using transmute, but not UB + /// let v_no_copy = Vec::from_raw_parts(v_orig.as_mut_ptr(), + /// v_orig.len(), + /// v_orig.capacity()); + /// mem::forget(v_orig); + /// // 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 or lesser 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 page linked above. + /// + /// /// // Copying an `&mut T` to reslice: /// fn split_at_mut_transmute(slice: &mut [T], index: usize) /// -> (&mut [T], &mut [T]) {