Skip to content

Commit 90a5a6c

Browse files
committed
transmute: caution against int2ptr transmutation
1 parent a6d93ac commit 90a5a6c

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

library/core/src/intrinsics.rs

+23-8
Original file line numberDiff line numberDiff line change
@@ -1169,14 +1169,6 @@ extern "rust-intrinsic" {
11691169
/// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
11701170
/// unsafe**. `transmute` should be the absolute last resort.
11711171
///
1172-
/// Transmuting pointers *to* integers in a `const` context is [undefined behavior][ub],
1173-
/// unless the pointer was originally created *from* an integer.
1174-
/// (That includes this function specifically, integer-to-pointer casts, and helpers like [`invalid`][crate::ptr::dangling],
1175-
/// but also semantically-equivalent conversions such as punning through `repr(C)` union fields.)
1176-
/// Any attempt to use the resulting value for integer operations will abort const-evaluation.
1177-
/// (And even outside `const`, such transmutation is touching on many unspecified aspects of the
1178-
/// Rust memory model and should be avoided. See below for alternatives.)
1179-
///
11801172
/// Because `transmute` is a by-value operation, alignment of the *transmuted values
11811173
/// themselves* is not a concern. As with any other function, the compiler already ensures
11821174
/// both `Src` and `Dst` are properly aligned. However, when transmuting values that *point
@@ -1187,6 +1179,29 @@ extern "rust-intrinsic" {
11871179
///
11881180
/// [ub]: ../../reference/behavior-considered-undefined.html
11891181
///
1182+
/// # Transmutation between pointers and integers
1183+
///
1184+
/// Special care has to be taken when transmuting between pointers and integers,
1185+
/// e.g. transmuting between `*const ()` and `usize`.
1186+
///
1187+
/// Transmuting *pointers to integers* in a `const` context is [undefined behavior][ub],
1188+
/// unless the pointer was originally created *from* an integer.
1189+
/// (That includes this function specifically, integer-to-pointer casts, and helpers like [`invalid`][crate::ptr::dangling],
1190+
/// but also semantically-equivalent conversions such as punning through `repr(C)` union fields.)
1191+
/// Any attempt to use the resulting value for integer operations will abort const-evaluation.
1192+
/// (And even outside `const`, such transmutation is touching on many unspecified aspects of the
1193+
/// Rust memory model and should be avoided. See below for alternatives.)
1194+
///
1195+
/// Transmuting *integers to pointers* is a largely unspecified operation. It is likely *not*
1196+
/// equivalent to an `as` cast. Doing non-zero-sized memory accesses with a pointer constructed
1197+
/// this way is currently considered undefined behavior.
1198+
///
1199+
/// All this also applies when the integer is nested inside an array, tuple, struct, or enum.
1200+
/// However, `MaybeUninit<usize>` is not considered an integer type for the purpose of this
1201+
/// section. Transmuting `*const ()` to `MaybeUninit<usize>` is fine---but then calling
1202+
/// `assume_init()` on that result is considered as completing the pointer-to-integer transmute
1203+
/// and thus runs into the issues discussed above.
1204+
///
11901205
/// # Examples
11911206
///
11921207
/// There are a few things that `transmute` is really useful for.

0 commit comments

Comments
 (0)