|
|
|
@ -41,12 +41,15 @@ The standard library has a number of unsafe functions, including:
|
|
|
|
|
* All FFI (Foreign Function Interface) functions are `unsafe` to call because the
|
|
|
|
|
other language can do arbitrary operations that the Rust compiler can't check.
|
|
|
|
|
|
|
|
|
|
As of Rust 1.0 there are exactly two unsafe traits:
|
|
|
|
|
As of Rust 1.29.2 the standard library defines the following unsafe traits
|
|
|
|
|
(there are others, but they are not stabilized yet and some of them may never
|
|
|
|
|
be):
|
|
|
|
|
|
|
|
|
|
* `Send` is a marker trait (a trait with no API) that promises implementors are
|
|
|
|
|
safe to send (move) to another thread.
|
|
|
|
|
* `Sync` is a marker trait that promises threads can safely share implementors
|
|
|
|
|
* [`Send`] is a marker trait (a trait with no API) that promises implementors
|
|
|
|
|
are safe to send (move) to another thread.
|
|
|
|
|
* [`Sync`] is a marker trait that promises threads can safely share implementors
|
|
|
|
|
through a shared reference.
|
|
|
|
|
* [`GlobalAlloc`] allows customizing the memory allocator of the whole program.
|
|
|
|
|
|
|
|
|
|
Much of the Rust standard library also uses Unsafe Rust internally. These
|
|
|
|
|
implementations have generally been rigorously manually checked, so the Safe Rust
|
|
|
|
@ -122,24 +125,35 @@ The decision of whether to mark a trait `unsafe` is an API design choice.
|
|
|
|
|
Rust has traditionally avoided doing this because it makes Unsafe
|
|
|
|
|
Rust pervasive, which isn't desirable. `Send` and `Sync` are marked unsafe
|
|
|
|
|
because thread safety is a *fundamental property* that unsafe code can't
|
|
|
|
|
possibly hope to defend against in the way it could defend against a bad
|
|
|
|
|
`Ord` implementation. The decision of whether to mark your own traits `unsafe`
|
|
|
|
|
depends on the same sort of consideration. If `unsafe` code can't reasonably
|
|
|
|
|
expect to defend against a bad implementation of the trait, then marking the
|
|
|
|
|
trait `unsafe` is a reasonable choice.
|
|
|
|
|
possibly hope to defend against in the way it could defend against a buggy
|
|
|
|
|
`Ord` implementation. Similarly, `GlobalAllocator` is keeping accounts of all
|
|
|
|
|
the memory in the program and other things like `Box` or `Vec` build on top of
|
|
|
|
|
it. If it does something weird (giving the same chunk of memory to another
|
|
|
|
|
request when it is still in use), there's no chance to detect that and do
|
|
|
|
|
anything about it.
|
|
|
|
|
|
|
|
|
|
The decision of whether to mark your own traits `unsafe` depends on the same
|
|
|
|
|
sort of consideration. If `unsafe` code can't reasonably expect to defend
|
|
|
|
|
against a broken implementation of the trait, then marking the trait `unsafe` is
|
|
|
|
|
a reasonable choice.
|
|
|
|
|
|
|
|
|
|
As an aside, while `Send` and `Sync` are `unsafe` traits, they are *also*
|
|
|
|
|
automatically implemented for types when such derivations are provably safe
|
|
|
|
|
to do. `Send` is automatically derived for all types composed only of values
|
|
|
|
|
whose types also implement `Send`. `Sync` is automatically derived for all
|
|
|
|
|
types composed only of values whose types also implement `Sync`. This minimizes
|
|
|
|
|
the pervasive unsafety of making these two traits `unsafe`.
|
|
|
|
|
the pervasive unsafety of making these two traits `unsafe`. And not many people
|
|
|
|
|
are going to *implement* memory allocators (or use them directly, for that
|
|
|
|
|
matter).
|
|
|
|
|
|
|
|
|
|
This is the balance between Safe and Unsafe Rust. The separation is designed to
|
|
|
|
|
make using Safe Rust as ergonomic as possible, but requires extra effort and
|
|
|
|
|
care when writing Unsafe Rust. The rest of this book is largely a discussion
|
|
|
|
|
of the sort of care that must be taken, and what contracts Unsafe Rust must uphold.
|
|
|
|
|
|
|
|
|
|
[`Send`]: ../std/marker/trait.Send.html
|
|
|
|
|
[`Sync`]: ../std/marker/trait.Sync.html
|
|
|
|
|
[`GlobalAlloc`]: ../std/alloc/trait.GlobalAlloc.html
|
|
|
|
|
[conversions]: conversions.html
|
|
|
|
|
[ptr_offset]: ../std/primitive.pointer.html#method.offset
|
|
|
|
|
|
|
|
|
|