From 5d95a36244f60bbbc5134310460e7597e82e41b1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 22 Jul 2022 14:51:23 -0400 Subject: [PATCH 1/4] do not claim that transmute is like memcpy --- library/core/src/intrinsics.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index dc82b32214c37..6bf95a1b008e1 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1212,8 +1212,9 @@ extern "rust-intrinsic" { /// /// `transmute` is semantically equivalent to a bitwise move of one type /// into another. It copies the bits from the source value into the - /// destination value, then forgets the original. It's equivalent to C's - /// `memcpy` under the hood, just like `transmute_copy`. + /// destination value, then forgets the original. Note that source and destination + /// are passed by-value, which means if `T` or `U` contains padding, that padding + /// might *not* be preserved by `transmute`. /// /// Because `transmute` is a by-value operation, alignment of the *transmuted values /// themselves* is not a concern. As with any other function, the compiler already ensures From aed5cf3f8ccd42ce455b8d7adbc4a2acfe013f85 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 23 Jul 2022 08:14:46 -0400 Subject: [PATCH 2/4] say some more things about how transmute is UB --- library/core/src/intrinsics.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 6bf95a1b008e1..d043c61a47a39 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1207,8 +1207,7 @@ extern "rust-intrinsic" { /// Reinterprets the bits of a value of one type as another type. /// - /// Both types must have the same size. Neither the original, nor the result, - /// may be an [invalid value](../../nomicon/what-unsafe-does.html). + /// Both types must have the same size. Compilation will fail if this is not guaranteed. /// /// `transmute` is semantically equivalent to a bitwise move of one type /// into another. It copies the bits from the source value into the @@ -1216,21 +1215,24 @@ extern "rust-intrinsic" { /// are passed by-value, which means if `T` or `U` contains padding, that padding /// might *not* be preserved by `transmute`. /// + /// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at + /// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler + /// will generate code *assuming that you, the programmer, ensure that there will never be + /// undefined behavior*. It is therefore your responsibility to guarantee that every value + /// passed to `transmute` is valid at both types `T` and `U`. Failing to uphold this condition + /// may lead to unexpeced and unstable compilation results. This makes `transmute` **incredibly + /// unsafe**. `transmute` should be the absolute last resort. + /// + /// Transmuting pointers to integers in a `const` context is [undefined behavior][ub]. + /// Any attempt to use the resulting value for integer operations will abort const-evaluation. + /// /// Because `transmute` is a by-value operation, alignment of the *transmuted values /// themselves* is not a concern. As with any other function, the compiler already ensures /// both `T` and `U` are properly aligned. However, when transmuting values that *point /// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper /// alignment of the pointed-to values. /// - /// `transmute` is **incredibly** unsafe. There are a vast number of ways to - /// cause [undefined behavior][ub] with this function. `transmute` should be - /// the absolute last resort. - /// - /// Transmuting pointers to integers in a `const` context is [undefined behavior][ub]. - /// Any attempt to use the resulting value for integer operations will abort const-evaluation. - /// - /// The [nomicon](../../nomicon/transmutes.html) has additional - /// documentation. + /// The [nomicon](../../nomicon/transmutes.html) has additional documentation. /// /// [ub]: ../../reference/behavior-considered-undefined.html /// From c4aca2bc889a657825ea74db2b0dca1d7ea87a44 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 31 Jul 2022 09:00:49 -0400 Subject: [PATCH 3/4] typo Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index d043c61a47a39..f4234105ac649 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1220,7 +1220,7 @@ extern "rust-intrinsic" { /// will generate code *assuming that you, the programmer, ensure that there will never be /// undefined behavior*. It is therefore your responsibility to guarantee that every value /// passed to `transmute` is valid at both types `T` and `U`. Failing to uphold this condition - /// may lead to unexpeced and unstable compilation results. This makes `transmute` **incredibly + /// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly /// unsafe**. `transmute` should be the absolute last resort. /// /// Transmuting pointers to integers in a `const` context is [undefined behavior][ub]. From da3e11fc4298e6e832eba0575b77a21493a7adfe Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Aug 2022 20:43:28 -0400 Subject: [PATCH 4/4] wordsmithing --- library/core/src/intrinsics.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index f4234105ac649..37940c7921360 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1212,8 +1212,8 @@ extern "rust-intrinsic" { /// `transmute` is semantically equivalent to a bitwise move of one type /// into another. It copies the bits from the source value into the /// destination value, then forgets the original. Note that source and destination - /// are passed by-value, which means if `T` or `U` contains padding, that padding - /// might *not* be preserved by `transmute`. + /// are passed by-value, which means if `T` or `U` contain padding, that padding + /// is *not* guaranteed to be preserved by `transmute`. /// /// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at /// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler @@ -1225,6 +1225,8 @@ extern "rust-intrinsic" { /// /// Transmuting pointers to integers in a `const` context is [undefined behavior][ub]. /// Any attempt to use the resulting value for integer operations will abort const-evaluation. + /// (And even outside `const`, such transmutation is touching on many unspecified aspects of the + /// Rust memory model and should be avoided. See below for alternatives.) /// /// Because `transmute` is a by-value operation, alignment of the *transmuted values /// themselves* is not a concern. As with any other function, the compiler already ensures