Unsafe

Rust's safety guarantees can be limiting when writing low-level code, because they prevent you from doing potentially dangerous things. Unsafe Rust allows you to sidestep some of these restrictions.

Unsafe Rust is very dangerous and can cause undefined behavior (UB). Because of this, it is always marked with the keyword. This makes it clear which parts of the code must be carefully vetted for safety. Furthermore, many Rust programs don't use  at all. It is good practice to always add a comment to  code, which explains why the code is safe, or what is required to use it safely.

Note that  code is not allowed to violate Rust's safety guarantees. If  is used, it's the programmer's responsibility to prevent undefined behavior, although the compiler can't verify this.

Unsafe operations
Using, it is possible to perform the following operations, which are not allowed elsewhere:


 * Dereference
 * Call  functions (including C functions, compiler intrinsics, and the raw allocator)
 * Access or modify a mutable static variable
 * Access fields of unions
 * Implement  traits

Unsafe contexts
An unsafe context is a context where the unsafe operations are allowed:


 * blocks within a function introduce a scope with an unsafe context.
 * functions currently introduce an unsafe context as well, but this will be changed in the future.
 * traits are implemented by writing.

Implications for safe code
When  code is used incorrectly, it can cause UB; we call such code unsound. Unfortunately, even safe code can be unsound, if it somehow relies on an unsound API. This means that incorrect usage of  can cause problems in different parts of the code and even different crates.

Examples
This example shows how to document unsafe functions following best practices:

This example uses the above function:

Writing unsafe code
If you think that you need to resort to, there are some things you should consider:


 * Read the article about Undefined Behavior and the relevant parts of the Rustonomicon and the Unsafe Code Guidelines.
 * When writing unsafe code, document it carefully.
 * Benchmark your code or look at the generated assembly, to verify that the unsafe code actually performs better than the equivalent safe code.
 * Ask other programmers for a code review.
 * Run your code in Miri.
 * Add unit tests to your code.
 * Fuzz your code.

Building safe abstractions
One of Rust's key patterns is isolating unsafe code into small, manageable sections, each performing a specific distinct task. This enables higher-level logic to only use idiomatic safe Rust code, without worrying about unsafe details — and that property of safe code is one of Rust's selling points as a whole. Ideally, all unsafe code should be designed with the intent to wrap potentially unsafe operations in a safe interface, "converting" undefined behavior conditions to panics and errors.

The term "safe abstraction" refers to one specific way of wrapping a certain set of unsafe operations into a safe public interface, and one single set of unsafe operations does not necessarily have one single way of being wrapped in a safe abstraction.

as an example of a safe abstraction
This shared mutability container is a great example of how a safe abstraction can wrap an unsafe interace in its own way with its own strong points and drawbacks. The implementation backbone is — on top of that unsafe primitive,   creates a safe interface, using runtime checks to ensure the validity of operations. Here's a typical formulation of this relationship: " is a safe abstraction over   which uses borrow checker styled checks at runtime to ensure safety".

, has its drawbacks, however, which may or may not matter in a specific use case. The primary trade-off is that because borrowing rules are enforced at runtime, the borrow checker cannot help with checking accesses to the contents of the  — the only way to know whether the code is correct is to actually see how it runs. The whole point of, however, is to provide more complex borrowing patterns which cannot be accepted by the borrow checker, which means that those complex borrowing patterns can be really hard to test for correctness. Another trade-off is that  cannot be shared between threads.

Most unsafe operations cannot be exhaustively covered by just one implementation of a safe abstraction. Considering again the /  example, there are alternatives to   which wrap the same unsafe internals —   — using different semantics, different interface and a different set of trade-offs. Those include, but are not limited to:


 * , which does not perform checks of any kind — it has better performance, at the cost of not being able to return references to the contents (operating only with // semantics). Similarly to, it cannot be shared between threads safely.
 * /, which are thread-safe versions of  used for sharing mutable data between threads. Those have a bigger runtime borrow-checking overhead (the typical behavior is to wait for the other thread to finish using the shared resource), but have no limitations regarding threading.
 * The crate provides four alternatives to, each with trade-offs and strong points of their own.