# What Unsafe Rust Can Do The only things that are different in Unsafe Rust are that you can: * Dereference raw pointers * Call `unsafe` functions (including C functions, compiler intrinsics, and the raw allocator) * Implement `unsafe` traits * Mutate statics * Access fields of `union`s That's it. The reason these operations are relegated to Unsafe is that misusing any of these things will cause the ever dreaded Undefined Behavior. Invoking Undefined Behavior gives the compiler full rights to do arbitrarily bad things to your program. You definitely *should not* invoke Undefined Behavior. Unlike C, Undefined Behavior is pretty limited in scope in Rust. All the core language cares about is preventing the following things: * Dereferencing null, dangling, or unaligned references or raw pointers * Performing out-of-bounds arithmetic for the computation of an `enum`/`struct`/array/slice/tuple field address * Reading [uninitialized memory][] * Breaking the [pointer aliasing rules][] * Producing invalid primitive values: * dangling/null/unaligned references * null `fn` pointers * a `bool` that isn't 0 or 1 * an undefined `enum` discriminant * a `char` outside the ranges [0x0, 0xD7FF] and [0xE000, 0x10FFFF] * a non-utf8 `str` * a `NonNull` or `NonZero*` that is 0 * a compound type (`enum`/`struct`/array/tuple) with an invalid field * Unwinding into another language * Causing a [data race][race] "Producing" a value happens any time a value is assigned, passed to a function/primitive operation or returned from a function/primitive operation. That's it. That's all the causes of Undefined Behavior baked into Rust. Of course, unsafe functions and traits are free to declare arbitrary other constraints that a program must maintain to avoid Undefined Behavior. For instance, the allocator APIs declare that deallocating unallocated memory is Undefined Behavior. However, violations of these constraints generally will just transitively lead to one of the above problems. Some additional constraints may also derive from compiler intrinsics that make special assumptions about how code can be optimized. For instance, Vec and Box make use of intrinsics that require their pointers to be non-null at all times. Rust is otherwise quite permissive with respect to other dubious operations. Rust considers it "safe" to: * Deadlock * Have a [race condition][race] * Leak memory * Fail to call destructors * Overflow integers * Abort the program * Delete the production database However any program that actually manages to do such a thing is *probably* incorrect. Rust provides lots of tools to make these things rare, but these problems are considered impractical to categorically prevent. [pointer aliasing rules]: references.html [uninitialized memory]: uninitialized.html [race]: races.html