Skip to content

Commit e3050ff

Browse files
author
Zooko Wilcox-O'Hearn
committed
Optimize out exhortations about being careful.
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.
1 parent 0550b79 commit e3050ff

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
@@ -298,8 +297,8 @@ asm!(assembly template
298297
Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
299298
crate to allow) and of course requires an `unsafe` block.
300299

301-
> **Note**: the examples here are given in x86/x86-64 assembly, but all
302-
> platforms are supported.
300+
> **Note**: the examples here are given in x86/x86-64 assembly, but
301+
> all platforms are supported.
303302
304303
## Assembly template
305304

@@ -497,7 +496,7 @@ detects that it will overflow its stack. The example above uses the
497496
> parts of the language may never be full specified and so details may
498497
> differ wildly between implementations (and even versions of `rustc`
499498
> itself).
500-
>
499+
>
501500
> Furthermore, this is just an overview; the best form of
502501
> documentation for specific instances of these features are their
503502
> definitions and uses in `std`.
@@ -584,8 +583,7 @@ fn main(_argc: int, _argv: **u8) -> int {
584583
```
585584

586585
Note the use of `abort`: the `exchange_malloc` lang item is assumed to
587-
return a valid pointer, and so needs to do the check
588-
internally.
586+
return a valid pointer, and so needs to do the check internally.
589587

590588
Other features provided by lang items include:
591589

0 commit comments

Comments
 (0)