Skip to content

Commit b5ff71d

Browse files
authored
Merge pull request #1278 from RalfJung/unsafe
update 'unsafe'
2 parents bf1453f + d1e4ea1 commit b5ff71d

File tree

7 files changed

+63
-31
lines changed

7 files changed

+63
-31
lines changed

book.toml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ edit-url-template = "https://github.com/rust-lang/reference/edit/master/{path}"
1010

1111
[output.html.redirect]
1212
"/expressions/enum-variant-expr.html" = "struct-expr.html"
13+
"/unsafe-blocks.html" = "unsafe-keyword.html"
14+
"/unsafe-functions.html" = "unsafe-keyword.html"
1315

1416
[rust]
1517
edition = "2021"

src/SUMMARY.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,7 @@
118118
- [Inline assembly](inline-assembly.md)
119119

120120
- [Unsafety](unsafety.md)
121-
- [Unsafe functions](unsafe-functions.md)
122-
- [Unsafe blocks](unsafe-blocks.md)
121+
- [The `unsafe` keyword](unsafe-keyword.md)
123122
- [Behavior considered undefined](behavior-considered-undefined.md)
124123
- [Behavior not considered unsafe](behavior-not-considered-unsafe.md)
125124

src/attributes/codegen.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ trait object whose methods are attributed.
347347
[target architecture]: ../conditional-compilation.md#target_arch
348348
[trait]: ../items/traits.md
349349
[undefined behavior]: ../behavior-considered-undefined.md
350-
[unsafe function]: ../unsafe-functions.md
350+
[unsafe function]: ../unsafe-keyword.md
351351
[rust-abi]: ../items/external-blocks.md#abi
352352
[`core::intrinsics::caller_location`]: ../../core/intrinsics/fn.caller_location.html
353353
[`core::panic::Location::caller`]: ../../core/panic/struct.Location.html#method.caller

src/types/function-pointer.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,5 @@ restrictions as [regular function parameters].
6262
[closures]: closure.md
6363
[extern function]: ../items/functions.md#extern-function-qualifier
6464
[function items]: function-item.md
65-
[unsafe function]: ../unsafe-functions.md
65+
[unsafe function]: ../unsafe-keyword.md
6666
[regular function parameters]: ../items/functions.md#attributes-on-function-parameters

src/unsafe-blocks.md

-22
This file was deleted.

src/unsafe-functions.md

-5
This file was deleted.

src/unsafe-keyword.md

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# The `unsafe` keyword
2+
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+
## Unsafe functions (`unsafe fn`)
13+
14+
Unsafe functions are functions that are not safe in all contexts and/or for all possible inputs.
15+
We say they have *extra safety conditions*, which are requirements that must be upheld by all callers and that the compiler does not check.
16+
For example, [`get_unchecked`] has the extra safety condition that the index must be in-bounds.
17+
The unsafe function should come with documentation explaining what those extra safety conditions are.
18+
19+
Such a function must be prefixed with the keyword `unsafe` and can only be called from inside an `unsafe` block, or inside `unsafe fn` without the [`unsafe_op_in_unsafe_fn`] lint.
20+
21+
## Unsafe blocks (`unsafe {}`)
22+
23+
A block of code can be prefixed with the `unsafe` keyword, to permit calling `unsafe` functions or dereferencing raw pointers.
24+
By default, the body of an unsafe function is also considered to be an unsafe block;
25+
this can be changed by enabling the [`unsafe_op_in_unsafe_fn`] lint.
26+
27+
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.
28+
29+
Unsafe blocks are the logical dual to unsafe functions:
30+
where unsafe functions define a proof obligation that callers must uphold, unsafe blocks state that all relevant proof obligations have been discharged.
31+
There are many ways to discharge proof obligations;
32+
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.
33+
34+
Unsafe blocks are used to wrap foreign libraries, make direct use of hardware or implement features not directly present in the language.
35+
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.
36+
37+
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.
38+
For example, a doubly-linked list is not a tree structure and can only be represented with reference-counted pointers in safe code.
39+
By using `unsafe` blocks to represent the reverse links as raw pointers, it can be implemented without reference counting.
40+
(See ["Learn Rust With Entirely Too Many Linked Lists"](https://rust-unofficial.github.io/too-many-lists/) for a more in-depth exploration of this particular example.)
41+
42+
## Unsafe traits (`unsafe trait`)
43+
44+
An unsafe trait is a trait that comes with extra safety conditions that must be upheld by *implementations* of the trait.
45+
The unsafe trait should come with documentation explaining what those extra safety conditions are.
46+
47+
Such a trait must be prefixed with the keyword `unsafe` and can only be implemented by `unsafe impl` blocks.
48+
49+
## Unsafe trait implementations (`unsafe impl`)
50+
51+
When implementing an unsafe trait, the implementation needs to be prefixed with the `unsafe` keyword.
52+
By writing `unsafe impl`, the programmer states that they have taken care of satisfying the extra safety conditions required by the trait.
53+
54+
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.
55+
56+
[keyword]: ../std/keyword.unsafe.html
57+
[`get_unchecked`]: ../std/primitive.slice.html#method.get_unchecked
58+
[`unsafe_op_in_unsafe_fn`]: ../rustc/lints/listing/allowed-by-default.html#unsafe-op-in-unsafe-fn

0 commit comments

Comments
 (0)