Skip to content

Commit 1423936

Browse files
committed
update unsafe docs
1 parent f24b8d4 commit 1423936

File tree

1 file changed

+53
-28
lines changed

1 file changed

+53
-28
lines changed

src/unsafe-keyword.md

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,55 @@
11
# The `unsafe` keyword
22

3-
## Unsafe functions
4-
5-
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.
8-
9-
## Unsafe blocks
10-
11-
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.
13-
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.
18-
19-
Unsafe blocks are used to wrap foreign libraries, make direct use of hardware
20-
or implement features not directly present in the language. For example, Rust
21-
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.
24-
25-
Rust's type system is a conservative approximation of the dynamic safety
26-
requirements, so in some cases there is a performance cost to using safe code.
27-
For example, a doubly-linked list is not a tree structure and can only be
28-
represented with reference-counted pointers in safe code. By using `unsafe`
29-
blocks to represent the reverse links as raw pointers, it can be implemented
30-
with only boxes.
3+
The `unsafe` keyword can occur in several different contexts:
4+
unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), and unsafe trait implementations (`unsafe impl`).
5+
It plays several different roles, depending on where it is used and whether the `unsafe_op_in_unsafe_fn` lint is enabled:
6+
- it is used to mark code that *defines* extra safety conditions (`unsafe fn`, `unsafe trait`)
7+
- it is used to mark code that needs to *satisfy* extra safety conditions (`unsafe {}`, `unsafe impl`, `unsafe fn` without `unsafe_op_in_unsafe_fn`)
8+
9+
The following discusses each of these cases.
10+
See the [keyword documentation][keyword] for some illustrative examples.
11+
12+
[keyword]: ../std/keyword.unsafe.html
13+
14+
## Unsafe functions (`unsafe fn`)
15+
16+
Unsafe functions are functions that are not safe in all contexts and/or for all possible inputs.
17+
We say they have *extra safety conditions*, which are requirements that must be upheld by all callers and that the compiler does not check.
18+
For example, `get_unchecked` has the extra safety condition that the index must be in-bounds.
19+
The module defining an unsafe function is responsible for documenting what those extra safety conditions are.
20+
21+
Such a function must be prefixed with the keyword `unsafe` and can only be called from inside an `unsafe` block.
22+
23+
## Unsafe blocks (`unsafe {}`)
24+
25+
A block of code can be prefixed with the `unsafe` keyword, to permit calling `unsafe` functions or dereferencing raw pointers.
26+
By default, the body of an unsafe function is also considered to be an unsafe block;
27+
this can be changed by enabling the `unsafe_op_in_unsafe_fn` lint.
28+
29+
By putting operations into an unsafe block, the programmer states that they have taken care of satisfying the extra safety conditions of all operations inside that block.
30+
31+
Unsafe blocks are the logical dual to unsafe functions:
32+
where unsafe functions define a proof obligation that callers must uphold, unsafe blocks state that all relevant proof obligations have been discharged.
33+
There are many ways to discharge proof obligations;
34+
for example, there could be run-time checks or data structure invariants that guarantee that certain properties are definitely true, or the unsafe block could be inside an `unsafe fn` and use its own proof obligations to discharge the proof obligations of its callees.
35+
36+
Unsafe blocks are used to wrap foreign libraries, make direct use of hardware or implement features not directly present in the language.
37+
For example, Rust provides the language features necessary to implement memory-safe concurrency in the language but the implementation of threads and message passing in the standard library uses unsafe blocks.
38+
39+
Rust's type system is a conservative approximation of the dynamic safety requirements, so in some cases there is a performance cost to using safe code.
40+
For example, a doubly-linked list is not a tree structure and can only be represented with reference-counted pointers in safe code.
41+
By using `unsafe` blocks to represent the reverse links as raw pointers, it can be implemented without reference counting.
42+
43+
## Unsafe traits (`unsafe trait`)
44+
45+
An unsafe trait is a trait that comes with extra safety conditions that must be upheld by *implementations* of the trait.
46+
The module defining an unsafe trait is responsible for documenting what those extra safety conditions are.
47+
48+
Such a trait must be prefixed with the keyword `unsafe` and can only be implemented by `unsafe impl` blocks.
49+
50+
## Unsafe trait implementations (`unsafe impl`)
51+
52+
When implementing an unsafe trait, the implementation needs to be prefixed with the `unsafe` keyword.
53+
By writing `unsafe impl`, the programmer states that they have taken care of satisfying the extra safety conditions required by the trait.
54+
55+
Unsafe trait implementations are the logical dual to unsafe traits: where unsafe traits define a proof obligation that implementations must uphold, unsafe implementations state that all relevant proof obligations have been discharged.

0 commit comments

Comments
 (0)