]> git.proxmox.com Git - rustc.git/blame - src/doc/nomicon/src/transmutes.md
New upstream version 1.54.0+dfsg1
[rustc.git] / src / doc / nomicon / src / transmutes.md
CommitLineData
8bb4bdeb 1# Transmutes
c1a9b12d
SL
2
3Get out of our way type system! We're going to reinterpret these bits or die
4trying! Even though this book is all about doing things that are unsafe, I
5really can't emphasize that you should deeply think about finding Another Way
6than the operations covered in this section. This is really, truly, the most
416331ca 7horribly unsafe thing you can do in Rust. The guardrails here are dental floss.
c1a9b12d 8
48663c56
XL
9[`mem::transmute<T, U>`][transmute] takes a value of type `T` and reinterprets
10it to have type `U`. The only restriction is that the `T` and `U` are verified
11to have the same size. The ways to cause Undefined Behavior with this are mind
12boggling.
c1a9b12d
SL
13
14* First and foremost, creating an instance of *any* type with an invalid state
f035d41b
XL
15 is going to cause arbitrary chaos that can't really be predicted. Do not
16 transmute `3` to `bool`. Even if you never *do* anything with the `bool`. Just
17 don't.
29967ef6 18
c1a9b12d
SL
19* Transmute has an overloaded return type. If you do not specify the return type
20 it may produce a surprising type to satisfy inference.
29967ef6
XL
21
22* Transmuting an `&` to `&mut` is UB.
23 * Transmuting an `&` to `&mut` is *always* UB.
f035d41b
XL
24 * No you can't do it.
25 * No you're not special.
29967ef6 26
c1a9b12d 27* Transmuting to a reference without an explicitly provided lifetime
29967ef6
XL
28 produces an [unbounded lifetime].
29
f035d41b
XL
30* When transmuting between different compound types, you have to make sure they
31 are laid out the same way! If layouts differ, the wrong fields are going to
32 get filled with the wrong data, which will make you unhappy and can also be UB
33 (see above).
34
29967ef6 35 So how do you know if the layouts are the same? For `repr(C)` types and
f035d41b
XL
36 `repr(transparent)` types, layout is precisely defined. But for your
37 run-of-the-mill `repr(Rust)`, it is not. Even different instances of the same
38 generic type can have wildly different layout. `Vec<i32>` and `Vec<u32>`
39 *might* have their fields in the same order, or they might not. The details of
40 what exactly is and is not guaranteed for data layout are still being worked
41 out over [at the UCG WG][ucg-layout].
c1a9b12d 42
48663c56
XL
43[`mem::transmute_copy<T, U>`][transmute_copy] somehow manages to be *even more*
44wildly unsafe than this. It copies `size_of<U>` bytes out of an `&T` and
45interprets them as a `U`. The size check that `mem::transmute` has is gone (as
46it may be valid to copy out a prefix), though it is Undefined Behavior for `U`
47to be larger than `T`.
c1a9b12d 48
f035d41b
XL
49Also of course you can get all of the functionality of these functions using raw
50pointer casts or `union`s, but without any of the lints or other basic sanity
51checks. Raw pointer casts and `union`s do not magically avoid the above rules.
c1a9b12d
SL
52
53
29967ef6 54[unbounded lifetime]: ./unbounded-lifetimes.md
48663c56 55[transmute]: ../std/mem/fn.transmute.html
e1599b0c 56[transmute_copy]: ../std/mem/fn.transmute_copy.html
f035d41b 57[ucg-layout]: https://rust-lang.github.io/unsafe-code-guidelines/layout.html