Skip to content

Commit 9e103ac

Browse files
committed
auto merge of #15165 : zookoatleastauthoritycom/rust/14148-Optimize-out-exhortations-about-being-careful-2, r=huonw
Yes, it is important to be careful, but repeated emphasis about it is probably not helpful — it starts to sound like you came for a tutorial but found a finger-wagging lecture. Even after I removed a few of these comments, there are still several left in the text. That's probably fine! A couple of mentions of how this is dangerous and you ought to be careful may be a good reminder to the reader. After making the edits, I reflowed the paragraphs that I had touched, using emacs's "M-x fill-paragraph", with fill-column equal to 70.
2 parents 7a93bee + e3050ff commit 9e103ac

File tree

1 file changed

+33
-35
lines changed

1 file changed

+33
-35
lines changed

src/doc/guide-unsafe.md

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
# Introduction
44

55
Rust aims to provide safe abstractions over the low-level details of
6-
the CPU and operating system, but sometimes one is forced to drop down
7-
and write code at that level (those abstractions have to be created
8-
somehow). This guide aims to provide an overview of the dangers and
9-
power one gets with Rust's unsafe subset.
6+
the CPU and operating system, but sometimes one needs to drop down and
7+
write code at that level. This guide aims to provide an overview of
8+
the dangers and power one gets with Rust's unsafe subset.
109

1110
Rust provides an escape hatch in the form of the `unsafe { ... }`
12-
block which allows the programmer to dodge some of the compilers
11+
block which allows the programmer to dodge some of the compiler's
1312
checks and do a wide range of operations, such as:
1413

1514
- dereferencing [raw pointers](#raw-pointers)
@@ -18,13 +17,12 @@ checks and do a wide range of operations, such as:
1817
- [inline assembly](#inline-assembly)
1918

2019
Note that an `unsafe` block does not relax the rules about lifetimes
21-
of `&` and the freezing of borrowed data, it just allows the use of
22-
additional techniques for skirting the compiler's watchful eye. Any
23-
use of `unsafe` is the programmer saying "I know more than you" to the
24-
compiler, and, as such, the programmer should be very sure that they
25-
actually do know more about why that piece of code is valid.
20+
of `&` and the freezing of borrowed data.
2621

27-
In general, one should try to minimize the amount of unsafe code in a
22+
Any use of `unsafe` is the programmer saying "I know more than you" to
23+
the compiler, and, as such, the programmer should be very sure that
24+
they actually do know more about why that piece of code is valid. In
25+
general, one should try to minimize the amount of unsafe code in a
2826
code base; preferably by using the bare minimum `unsafe` blocks to
2927
build safe interfaces.
3028

@@ -38,25 +36,25 @@ build safe interfaces.
3836

3937
## References
4038

41-
One of Rust's biggest goals as a language is ensuring memory safety,
42-
achieved in part via [the lifetime system](guide-lifetimes.html) which
43-
every `&` references has associated with it. This system is how the
39+
One of Rust's biggest features is memory safety. This is achieved in
40+
part via [the lifetime system](guide-lifetimes.html), which is how the
4441
compiler can guarantee that every `&` reference is always valid, and,
4542
for example, never pointing to freed memory.
4643

47-
These restrictions on `&` have huge advantages. However, there's no
48-
free lunch club. For example, `&` isn't a valid replacement for C's
49-
pointers, and so cannot be used for FFI, in general. Additionally,
50-
both immutable (`&`) and mutable (`&mut`) references have some
51-
aliasing and freezing guarantees, required for memory safety.
44+
These restrictions on `&` have huge advantages. However, they also
45+
constrain how we can use them. For example, `&` doesn't behave
46+
identically to C's pointers, and so cannot be used for pointers in
47+
foreign function interfaces (FFI). Additionally, both immutable (`&`)
48+
and mutable (`&mut`) references have some aliasing and freezing
49+
guarantees, required for memory safety.
5250

5351
In particular, if you have an `&T` reference, then the `T` must not be
5452
modified through that reference or any other reference. There are some
5553
standard library types, e.g. `Cell` and `RefCell`, that provide inner
5654
mutability by replacing compile time guarantees with dynamic checks at
5755
runtime.
5856

59-
An `&mut` reference has a stronger requirement: when an object has an
57+
An `&mut` reference has a different constraint: when an object has an
6058
`&mut T` pointing into it, then that `&mut` reference must be the only
6159
such usable path to that object in the whole program. That is, an
6260
`&mut` cannot alias with any other references.
@@ -106,19 +104,19 @@ offered by the Rust language and libraries. For example, they
106104

107105
Fortunately, they come with a redeeming feature: the weaker guarantees
108106
mean weaker restrictions. The missing restrictions make raw pointers
109-
appropriate as a building block for (carefully!) implementing things
110-
like smart pointers and vectors inside libraries. For example, `*`
111-
pointers are allowed to alias, allowing them to be used to write
112-
shared-ownership types like reference counted and garbage collected
113-
pointers, and even thread-safe shared memory types (`Rc` and the `Arc`
114-
types are both implemented entirely in Rust).
107+
appropriate as a building block for implementing things like smart
108+
pointers and vectors inside libraries. For example, `*` pointers are
109+
allowed to alias, allowing them to be used to write shared-ownership
110+
types like reference counted and garbage collected pointers, and even
111+
thread-safe shared memory types (`Rc` and the `Arc` types are both
112+
implemented entirely in Rust).
115113

116114
There are two things that you are required to be careful about
117115
(i.e. require an `unsafe { ... }` block) with raw pointers:
118116

119117
- dereferencing: they can have any value: so possible results include
120118
a crash, a read of uninitialised memory, a use-after-free, or
121-
reading data as normal (and one hopes happens).
119+
reading data as normal.
122120
- pointer arithmetic via the `offset` [intrinsic](#intrinsics) (or
123121
`.offset` method): this intrinsic uses so-called "in-bounds"
124122
arithmetic, that is, it is only defined behaviour if the result is
@@ -177,9 +175,10 @@ code:
177175
- store pointers privately (i.e. not in public fields of public
178176
structs), so that you can see and control all reads and writes to
179177
the pointer in one place.
180-
- use `assert!()` a lot: once you've thrown away the protection of the
181-
compiler & type-system via `unsafe { ... }` you're left with just
182-
your wits and your `assert!()`s, any bug is potentially exploitable.
178+
- use `assert!()` a lot: since you can't rely on the protection of the
179+
compiler & type-system to ensure that your `unsafe` code is correct
180+
at compile-time, use `assert!()` to verify that it is doing the
181+
right thing at run-time.
183182
- implement the `Drop` for resource clean-up via a destructor, and use
184183
RAII (Resource Acquisition Is Initialization). This reduces the need
185184
for any manual memory management by users, and automatically ensures
@@ -305,8 +304,8 @@ asm!(assembly template
305304
Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
306305
crate to allow) and of course requires an `unsafe` block.
307306

308-
> **Note**: the examples here are given in x86/x86-64 assembly, but all
309-
> platforms are supported.
307+
> **Note**: the examples here are given in x86/x86-64 assembly, but
308+
> all platforms are supported.
310309
311310
## Assembly template
312311

@@ -596,7 +595,7 @@ standard library itself.
596595
> parts of the language may never be full specified and so details may
597596
> differ wildly between implementations (and even versions of `rustc`
598597
> itself).
599-
>
598+
>
600599
> Furthermore, this is just an overview; the best form of
601600
> documentation for specific instances of these features are their
602601
> definitions and uses in `std`.
@@ -689,8 +688,7 @@ fn main(argc: int, argv: **u8) -> int {
689688
```
690689

691690
Note the use of `abort`: the `exchange_malloc` lang item is assumed to
692-
return a valid pointer, and so needs to do the check
693-
internally.
691+
return a valid pointer, and so needs to do the check internally.
694692

695693
Other features provided by lang items include:
696694

0 commit comments

Comments
 (0)