diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-08-03 13:45:50 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-03 13:45:50 +0530 |
| commit | cb9932ea64b3dd799fbdbb8942e5a036af6cc7aa (patch) | |
| tree | d0378b20027ed606543dd49d5393e1e1c65c18d6 | |
| parent | 5730f12b37f16637a6614d086ac534a9a88bfc55 (diff) | |
| parent | da3e11fc4298e6e832eba0575b77a21493a7adfe (diff) | |
| download | rust-cb9932ea64b3dd799fbdbb8942e5a036af6cc7aa.tar.gz rust-cb9932ea64b3dd799fbdbb8942e5a036af6cc7aa.zip | |
Rollup merge of #99614 - RalfJung:transmute-is-not-memcpy, r=thomcc
do not claim that transmute is like memcpy Saying transmute is like memcpy is not a well-formed statement, since memcpy is by-ref whereas transmute is by-val. The by-val nature of transmute inherently means that padding is lost along the way. (This is not specific to transmute, this is how all by-value operations work.) So adjust the docs to clarify this aspect. Cc `@workingjubilee`
| -rw-r--r-- | library/core/src/intrinsics.rs | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 7e65f4ebdad..cabc5017f1d 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1207,13 +1207,26 @@ 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 - /// 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` 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 + /// 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 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]. + /// 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 @@ -1221,15 +1234,7 @@ extern "rust-intrinsic" { /// 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 /// |
