@@ -846,6 +846,12 @@ extern "rust-intrinsic" {
846
846
/// destination value, then forgets the original. It's equivalent to C's
847
847
/// `memcpy` under the hood, just like `transmute_copy`.
848
848
///
849
+ /// Because `transmute` is a by-value operation, alignment of the *transmuted values
850
+ /// themselves* is not a concern. As with any other function, the compiler already ensures
851
+ /// both `T` and `U` are properly aligned. However, when transmuting values that *point
852
+ /// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
853
+ /// alignment of the pointed-to values.
854
+ ///
849
855
/// `transmute` is **incredibly** unsafe. There are a vast number of ways to
850
856
/// cause [undefined behavior][ub] with this function. `transmute` should be
851
857
/// the absolute last resort.
@@ -965,7 +971,13 @@ extern "rust-intrinsic" {
965
971
/// assert_eq!(b"Rust", &[82, 117, 115, 116]);
966
972
/// ```
967
973
///
968
- /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`:
974
+ /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`.
975
+ ///
976
+ /// To transmute the inner type of the contents of a container, you must make sure to not
977
+ /// violate any of the container's invariants. For `Vec`, this means that both the size
978
+ /// *and alignment* of the inner types have to match. Other containers might rely on the
979
+ /// size of the type, alignment, or even the `TypeId`, in which case transmuting wouldn't
980
+ /// be possible at all without violating the container invariants.
969
981
///
970
982
/// ```
971
983
/// let store = [0, 1, 2, 3];
@@ -991,14 +1003,11 @@ extern "rust-intrinsic" {
991
1003
///
992
1004
/// let v_clone = v_orig.clone();
993
1005
///
994
- /// // The no-copy, unsafe way, still using transmute, but not relying on the data layout.
995
- /// // Like the first approach, this reuses the `Vec` internals.
996
- /// // Therefore, the new inner type must have the
997
- /// // exact same size, *and the same alignment*, as the old type.
998
- /// // The same caveats exist for this method as transmute, for
999
- /// // the original inner type (`&i32`) to the converted inner type
1000
- /// // (`Option<&i32>`), so read the nomicon pages linked above and also
1001
- /// // consult the [`from_raw_parts`] documentation.
1006
+ /// // This is the proper no-copy, unsafe way of "transmuting" a `Vec`, without relying on the
1007
+ /// // data layout. Instead of literally calling `transmute`, we perform a pointer cast, but
1008
+ /// // in terms of converting the original inner type (`&i32`) to the new one (`Option<&i32>`),
1009
+ /// // this has all the same caveats. Besides the information provided above, also consult the
1010
+ /// // [`from_raw_parts`] documentation.
1002
1011
/// let v_from_raw = unsafe {
1003
1012
// FIXME Update this when vec_into_raw_parts is stabilized
1004
1013
/// // Ensure the original vector is not dropped.
0 commit comments