diff options
| author | Tyler Mandry <tmandry@gmail.com> | 2019-09-17 14:10:50 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-09-17 14:10:50 -0700 |
| commit | d6f2205ed8460da20f21e959e019d2bc6817cb5a (patch) | |
| tree | e3db80825b82ee7a17d8fd1ac5e35684392ff133 /src/libcore | |
| parent | ffee7bbf9a3ae1cff2bdf3cb17d3f5d8b01951c0 (diff) | |
| parent | ab6e108644474ece91711e889cff7d36a0adf7f0 (diff) | |
| download | rust-d6f2205ed8460da20f21e959e019d2bc6817cb5a.tar.gz rust-d6f2205ed8460da20f21e959e019d2bc6817cb5a.zip | |
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
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/intrinsics.rs | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index d145f2212f9..ecff40a7597 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -845,21 +845,26 @@ extern "rust-intrinsic" { /// /// ``` /// 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. /// // However, it is no-copy. /// let v_transmuted = unsafe { - /// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>( - /// v_orig.clone()) + /// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone) /// }; /// + /// let v_clone = v_orig.clone(); + /// /// // This is the suggested, safe way. /// // It does copy the entire vector, though, into a new array. - /// let v_collected = v_orig.clone() - /// .into_iter() - /// .map(|r| Some(r)) - /// .collect::<Vec<Option<&i32>>>(); + /// let v_collected = v_clone.into_iter() + /// .map(Some) + /// .collect::<Vec<Option<&i32>>>(); + /// + /// let v_clone = v_orig.clone(); /// /// // The no-copy, unsafe way, still using transmute, but not UB. /// // 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 /// // (`Option<&i32>`), so read the nomicon pages linked above. /// let v_from_raw = unsafe { - /// Vec::from_raw_parts(v_orig.as_mut_ptr() as *mut Option<&i32>, - /// v_orig.len(), - /// v_orig.capacity()) + /// // Ensure the original vector is not dropped. + /// let mut v_clone = std::mem::ManuallyDrop::new(v_clone); + /// 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`: |
