]> git.proxmox.com Git - rustc.git/blob - src/doc/nomicon/src/what-unsafe-does.md
c82c70c678f016744fdd57aceaa4136eb7564b22
[rustc.git] / src / doc / nomicon / src / what-unsafe-does.md
1 # What Unsafe Rust Can Do
2
3 The only things that are different in Unsafe Rust are that you can:
4
5 * Dereference raw pointers
6 * Call `unsafe` functions (including C functions, compiler intrinsics, and the raw allocator)
7 * Implement `unsafe` traits
8 * Mutate statics
9 * Access fields of `union`s
10
11 That's it. The reason these operations are relegated to Unsafe is that misusing
12 any of these things will cause the ever dreaded Undefined Behavior. Invoking
13 Undefined Behavior gives the compiler full rights to do arbitrarily bad things
14 to your program. You definitely *should not* invoke Undefined Behavior.
15
16 Unlike C, Undefined Behavior is pretty limited in scope in Rust. All the core
17 language cares about is preventing the following things:
18
19 * Dereferencing (using the `*` operator on) dangling or unaligned pointers (see below)
20 * Breaking the [pointer aliasing rules][]
21 * Calling a function with the wrong call ABI or unwinding from a function with the wrong unwind ABI.
22 * Causing a [data race][race]
23 * Executing code compiled with [target features][] that the current thread of execution does
24 not support
25 * Producing invalid values (either alone or as a field of a compound type such
26 as `enum`/`struct`/array/tuple):
27 * a `bool` that isn't 0 or 1
28 * an `enum` with an invalid discriminant
29 * a null `fn` pointer
30 * a `char` outside the ranges [0x0, 0xD7FF] and [0xE000, 0x10FFFF]
31 * a `!` (all values are invalid for this type)
32 * an integer (`i*`/`u*`), floating point value (`f*`), or raw pointer read from
33 [uninitialized memory][], or uninitialized memory in a `str`.
34 * a reference/`Box` that is dangling, unaligned, or points to an invalid value.
35 * a wide reference, `Box`, or raw pointer that has invalid metadata:
36 * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for
37 `Trait` that matches the actual dynamic trait the pointer or reference points to
38 * slice metadata is invalid if the length is not a valid `usize`
39 (i.e., it must not be read from uninitialized memory)
40 * a type with custom invalid values that is one of those values, such as a
41 [`NonNull`] that is null. (Requesting custom invalid values is an unstable
42 feature, but some stable libstd types, like `NonNull`, make use of it.)
43
44 "Producing" a value happens any time a value is assigned, passed to a
45 function/primitive operation or returned from a function/primitive operation.
46
47 A reference/pointer is "dangling" if it is null or not all of the bytes it
48 points to are part of the same allocation (so in particular they all have to be
49 part of *some* allocation). The span of bytes it points to is determined by the
50 pointer value and the size of the pointee type. As a consequence, if the span is
51 empty, "dangling" is the same as "non-null". Note that slices and strings point
52 to their entire range, so it's important that the length metadata is never too
53 large (in particular, allocations and therefore slices and strings cannot be
54 bigger than `isize::MAX` bytes). If for some reason this is too cumbersome,
55 consider using raw pointers.
56
57 That's it. That's all the causes of Undefined Behavior baked into Rust. Of
58 course, unsafe functions and traits are free to declare arbitrary other
59 constraints that a program must maintain to avoid Undefined Behavior. For
60 instance, the allocator APIs declare that deallocating unallocated memory is
61 Undefined Behavior.
62
63 However, violations of these constraints generally will just transitively lead to one of
64 the above problems. Some additional constraints may also derive from compiler
65 intrinsics that make special assumptions about how code can be optimized. For instance,
66 Vec and Box make use of intrinsics that require their pointers to be non-null at all times.
67
68 Rust is otherwise quite permissive with respect to other dubious operations.
69 Rust considers it "safe" to:
70
71 * Deadlock
72 * Have a [race condition][race]
73 * Leak memory
74 * Fail to call destructors
75 * Overflow integers
76 * Abort the program
77 * Delete the production database
78
79 However any program that actually manages to do such a thing is *probably*
80 incorrect. Rust provides lots of tools to make these things rare, but
81 these problems are considered impractical to categorically prevent.
82
83 [pointer aliasing rules]: references.html
84 [uninitialized memory]: uninitialized.html
85 [race]: races.html
86 [target features]: ../reference/attributes/codegen.html#the-target_feature-attribute
87 [`NonNull`]: ../std/ptr/struct.NonNull.html