]> git.proxmox.com Git - rustc.git/blob - src/doc/nomicon/safe-unsafe-meaning.md
New upstream version 1.13.0+dfsg1
[rustc.git] / src / doc / nomicon / safe-unsafe-meaning.md
1 % How Safe and Unsafe Interact
2
3 What's the relationship between Safe Rust and Unsafe Rust? How do they
4 interact?
5
6 The separation between Safe Rust and Unsafe Rust is controlled with the
7 `unsafe` keyword, which acts as an interface from one to the other. This is
8 why we can say Safe Rust is a safe language: all the unsafe parts are kept
9 exclusively behind the boundary.
10
11 The `unsafe` keyword has two uses: to declare the existence of contracts the
12 compiler can't check, and to declare that the adherence of some code to
13 those contracts has been checked by the programmer.
14
15 You can use `unsafe` to indicate the existence of unchecked contracts on
16 _functions_ and on _trait declarations_. On functions, `unsafe` means that
17 users of the function must check that function's documentation to ensure
18 they are using it in a way that maintains the contracts the function
19 requires. On trait declarations, `unsafe` means that implementors of the
20 trait must check the trait documentation to ensure their implementation
21 maintains the contracts the trait requires.
22
23 You can use `unsafe` on a block to declare that all constraints required
24 by an unsafe function within the block have been adhered to, and the code
25 can therefore be trusted. You can use `unsafe` on a trait implementation
26 to declare that the implementation of that trait has adhered to whatever
27 contracts the trait's documentation requires.
28
29 The standard library has a number of unsafe functions, including:
30
31 * `slice::get_unchecked`, which performs unchecked indexing, allowing
32 memory safety to be freely violated.
33 * `mem::transmute` reinterprets some value as having a given type, bypassing
34 type safety in arbitrary ways (see [conversions] for details).
35 * Every raw pointer to a sized type has an intrinstic `offset` method that
36 invokes Undefined Behavior if the passed offset is not "in bounds" as
37 defined by LLVM.
38 * All FFI functions are `unsafe` because the other language can do arbitrary
39 operations that the Rust compiler can't check.
40
41 As of Rust 1.0 there are exactly two unsafe traits:
42
43 * `Send` is a marker trait (a trait with no API) that promises implementors are
44 safe to send (move) to another thread.
45 * `Sync` is a marker trait that promises threads can safely share implementors
46 through a shared reference.
47
48 Much of the Rust standard library also uses Unsafe Rust internally, although
49 these implementations are rigorously manually checked, and the Safe Rust
50 interfaces provided on top of these implementations can be assumed to be safe.
51
52 The need for all of this separation boils down a single fundamental property
53 of Safe Rust:
54
55 **No matter what, Safe Rust can't cause Undefined Behavior.**
56
57 The design of the safe/unsafe split means that Safe Rust inherently has to
58 trust that any Unsafe Rust it touches has been written correctly (meaning
59 the Unsafe Rust actually maintains whatever contracts it is supposed to
60 maintain). On the other hand, Unsafe Rust has to be very careful about
61 trusting Safe Rust.
62
63 As an example, Rust has the `PartialOrd` and `Ord` traits to differentiate
64 between types which can "just" be compared, and those that provide a total
65 ordering (where every value of the type is either equal to, greater than,
66 or less than any other value of the same type). The sorted map type
67 `BTreeMap` doesn't make sense for partially-ordered types, and so it
68 requires that any key type for it implements the `Ord` trait. However,
69 `BTreeMap` has Unsafe Rust code inside of its implementation, and this
70 Unsafe Rust code cannot assume that any `Ord` implementation it gets makes
71 sense. The unsafe portions of `BTreeMap`'s internals have to be careful to
72 maintain all necessary contracts, even if a key type's `Ord` implementation
73 does not implement a total ordering.
74
75 Unsafe Rust cannot automatically trust Safe Rust. When writing Unsafe Rust,
76 you must be careful to only rely on specific Safe Rust code, and not make
77 assumptions about potential future Safe Rust code providing the same
78 guarantees.
79
80 This is the problem that `unsafe` traits exist to resolve. The `BTreeMap`
81 type could theoretically require that keys implement a new trait called
82 `UnsafeOrd`, rather than `Ord`, that might look like this:
83
84 ```rust
85 use std::cmp::Ordering;
86
87 unsafe trait UnsafeOrd {
88 fn cmp(&self, other: &Self) -> Ordering;
89 }
90 ```
91
92 Then, a type would use `unsafe` to implement `UnsafeOrd`, indicating that
93 they've ensured their implementation maintains whatever contracts the
94 trait expects. In this situation, the Unsafe Rust in the internals of
95 `BTreeMap` could trust that the key type's `UnsafeOrd` implementation is
96 correct. If it isn't, it's the fault of the unsafe trait implementation
97 code, which is consistent with Rust's safety guarantees.
98
99 The decision of whether to mark a trait `unsafe` is an API design choice.
100 Rust has traditionally avoided marking traits unsafe because it makes Unsafe
101 Rust pervasive, which is not desirable. `Send` and `Sync` are marked unsafe
102 because thread safety is a *fundamental property* that unsafe code can't
103 possibly hope to defend against in the way it could defend against a bad
104 `Ord` implementation. The decision of whether to mark your own traits `unsafe`
105 depends on the same sort of consideration. If `unsafe` code cannot reasonably
106 expect to defend against a bad implementation of the trait, then marking the
107 trait `unsafe` is a reasonable choice.
108
109 As an aside, while `Send` and `Sync` are `unsafe` traits, they are
110 automatically implemented for types when such derivations are provably safe
111 to do. `Send` is automatically derived for all types composed only of values
112 whose types also implement `Send`. `Sync` is automatically derived for all
113 types composed only of values whose types also implement `Sync`.
114
115 This is the dance of Safe Rust and Unsafe Rust. It is designed to make using
116 Safe Rust as ergonomic as possible, but requires extra effort and care when
117 writing Unsafe Rust. The rest of the book is largely a discussion of the sort
118 of care that must be taken, and what contracts it is expected of Unsafe Rust
119 to uphold.
120
121 [drop flags]: drop-flags.html
122 [conversions]: conversions.html
123