Skip to content

Commit 33cd535

Browse files
committed
update unsafe docs
1 parent f24b8d4 commit 33cd535

File tree

1 file changed

+60
-11
lines changed

1 file changed

+60
-11
lines changed

src/unsafe-keyword.md

+60-11
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,79 @@
11
# The `unsafe` keyword
22

3-
## Unsafe functions
3+
The `unsafe` keyword in Rust can occur in several different context: unsafe
4+
functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe
5+
trait`), and unsafe trait implementations (`unsafe impl`). It plays several
6+
different roles, depending on where it is used and whether the
7+
`unsafe_op_in_unsafe_fn` lint is enabled:
8+
- it is used to mark code that *defines* extra safety conditions (`unsafe fn`,
9+
`unsafe trait`)
10+
- it is used to mark code that needs to *satisfy* extra safety conditions
11+
(`unsafe {}`, `unsafe impl`, `unsafe fn` without `unsafe_op_in_unsafe_fn`)
12+
13+
The following discusses each of these cases. See the
14+
[keyword documentation][keyword] for some illustrative examples.
15+
16+
[keyword]: ../../std/keyword.unsafe.html
17+
18+
## Unsafe functions (`unsafe fn`)
419

520
Unsafe functions are functions that are not safe in all contexts and/or for all
6-
possible inputs. Such a function must be prefixed with the keyword `unsafe` and
7-
can only be called from an `unsafe` block or another `unsafe` function.
21+
possible inputs. We say they have *extra safety conditions*, which are
22+
requirements that must be upheld by all callers and that the compiler does not
23+
check. For example, `get_unchecked` has the extra safety
24+
condition that the index must be in-bounds. The module defining an unsafe
25+
function is responsible for documenting what those extra safety conditions are.
826

9-
## Unsafe blocks
27+
Such a function must be prefixed with the keyword `unsafe` and can only be
28+
called from inside an `unsafe` block.
29+
30+
## Unsafe blocks (`unsafe {}`)
1031

1132
A block of code can be prefixed with the `unsafe` keyword, to permit calling
12-
`unsafe` functions or dereferencing raw pointers within a safe function.
33+
`unsafe` functions or dereferencing raw pointers. By default, the body of an
34+
unsafe function is also considered to be an unsafe block; this can be changed by
35+
enabling the `unsafe_op_in_unsafe_fn` lint.
36+
37+
By putting operations into an unsafe block, the programmer states that they have
38+
taken care of satisfying the extra safety conditions of all operations inside
39+
that block.
1340

14-
When a programmer has sufficient conviction that a sequence of potentially
15-
unsafe operations is actually safe, they can encapsulate that sequence (taken
16-
as a whole) within an `unsafe` block. The compiler will consider uses of such
17-
code safe, in the surrounding context.
41+
Unsafe blocks are the logical dual to unsafe functions: where unsafe functions
42+
define a proof obligation that callers must uphold, unsafe blocks state that all
43+
relevant proof obligations have been discharged. There are many ways to
44+
discharge proof obligations; for example, there could be run-time checks or data
45+
structure invariants that guarantee that certain properties are definitely true,
46+
or the unsafe block could be inside an `unsafe fn` and use its own proof
47+
obligations to discharge the proof obligations of its callees.
1848

1949
Unsafe blocks are used to wrap foreign libraries, make direct use of hardware
2050
or implement features not directly present in the language. For example, Rust
2151
provides the language features necessary to implement memory-safe concurrency
22-
in the language but the implementation of threads and message passing is in the
23-
standard library.
52+
in the language but the implementation of threads and message passing in the
53+
standard library uses unsafe blocks.
2454

2555
Rust's type system is a conservative approximation of the dynamic safety
2656
requirements, so in some cases there is a performance cost to using safe code.
2757
For example, a doubly-linked list is not a tree structure and can only be
2858
represented with reference-counted pointers in safe code. By using `unsafe`
2959
blocks to represent the reverse links as raw pointers, it can be implemented
3060
with only boxes.
61+
62+
## Unsafe traits (`unsafe trait`)
63+
64+
An unsafe trait is a trait that comes with extra safety conditions that must be
65+
upheld by *implementations* of the trait. The module defining an unsafe trait is
66+
responsible for documenting what those extra safety conditions are.
67+
68+
Such a trait must be prefixed with the keyword `unsafe` and can only be
69+
implemented by `unsafe impl` blocks.
70+
71+
## Unsafe trait implementations (`unsafe impl`)
72+
73+
When implementing an unsafe trait, the implementation needs to be prefixed with
74+
the `unsafe` keyword. By writing `unsafe impl`, the programmer states that they
75+
have taken care of satisfying the extra safety conditions required by the trait.
76+
77+
Unsafe traits are the logical dual to unsafe traits: where unsafe traits define
78+
a proof obligation that implementations must uphold, unsafe implementations
79+
state that all relevant proof obligations have been discharged.

0 commit comments

Comments
 (0)