Skip to content

Commit cb9932e

Browse files
authored
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`
2 parents 5730f12 + da3e11f commit cb9932e

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

library/core/src/intrinsics.rs

+18-13
Original file line numberDiff line numberDiff line change
@@ -1207,29 +1207,34 @@ extern "rust-intrinsic" {
12071207

12081208
/// Reinterprets the bits of a value of one type as another type.
12091209
///
1210-
/// Both types must have the same size. Neither the original, nor the result,
1211-
/// may be an [invalid value](../../nomicon/what-unsafe-does.html).
1210+
/// Both types must have the same size. Compilation will fail if this is not guaranteed.
12121211
///
12131212
/// `transmute` is semantically equivalent to a bitwise move of one type
12141213
/// into another. It copies the bits from the source value into the
1215-
/// destination value, then forgets the original. It's equivalent to C's
1216-
/// `memcpy` under the hood, just like `transmute_copy`.
1214+
/// destination value, then forgets the original. Note that source and destination
1215+
/// are passed by-value, which means if `T` or `U` contain padding, that padding
1216+
/// is *not* guaranteed to be preserved by `transmute`.
1217+
///
1218+
/// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at
1219+
/// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler
1220+
/// will generate code *assuming that you, the programmer, ensure that there will never be
1221+
/// undefined behavior*. It is therefore your responsibility to guarantee that every value
1222+
/// passed to `transmute` is valid at both types `T` and `U`. Failing to uphold this condition
1223+
/// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
1224+
/// unsafe**. `transmute` should be the absolute last resort.
1225+
///
1226+
/// Transmuting pointers to integers in a `const` context is [undefined behavior][ub].
1227+
/// Any attempt to use the resulting value for integer operations will abort const-evaluation.
1228+
/// (And even outside `const`, such transmutation is touching on many unspecified aspects of the
1229+
/// Rust memory model and should be avoided. See below for alternatives.)
12171230
///
12181231
/// Because `transmute` is a by-value operation, alignment of the *transmuted values
12191232
/// themselves* is not a concern. As with any other function, the compiler already ensures
12201233
/// both `T` and `U` are properly aligned. However, when transmuting values that *point
12211234
/// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
12221235
/// alignment of the pointed-to values.
12231236
///
1224-
/// `transmute` is **incredibly** unsafe. There are a vast number of ways to
1225-
/// cause [undefined behavior][ub] with this function. `transmute` should be
1226-
/// the absolute last resort.
1227-
///
1228-
/// Transmuting pointers to integers in a `const` context is [undefined behavior][ub].
1229-
/// Any attempt to use the resulting value for integer operations will abort const-evaluation.
1230-
///
1231-
/// The [nomicon](../../nomicon/transmutes.html) has additional
1232-
/// documentation.
1237+
/// The [nomicon](../../nomicon/transmutes.html) has additional documentation.
12331238
///
12341239
/// [ub]: ../../reference/behavior-considered-undefined.html
12351240
///

0 commit comments

Comments
 (0)