Skip to content

Commit 4dc3a97

Browse files
committed
auto merge of #9258 : thestinger/rust/doc, r=catamorphism
Closes #9144
2 parents 460021b + e12c3bf commit 4dc3a97

File tree

1 file changed

+63
-11
lines changed

1 file changed

+63
-11
lines changed

doc/rust.md

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -962,24 +962,76 @@ parameters to allow methods with that trait to be called on values
962962
of that type.
963963

964964

965-
#### Unsafe functions
966-
967-
Unsafe functions are those containing unsafe operations that are not contained in an [`unsafe` block](#unsafe-blocks).
968-
Such a function must be prefixed with the keyword `unsafe`.
965+
#### Unsafety
969966

970967
Unsafe operations are those that potentially violate the memory-safety guarantees of Rust's static semantics.
971-
Specifically, the following operations are considered unsafe:
968+
969+
The following language level features cannot be used in the safe subset of Rust:
972970

973971
- Dereferencing a [raw pointer](#pointer-types).
974-
- Casting a [raw pointer](#pointer-types) to a safe pointer type.
975-
- Calling an unsafe function.
972+
- Calling an unsafe function (including an intrinsic or foreign function).
976973

977-
##### Unsafe blocks
974+
##### Unsafe functions
978975

979-
A block of code can also be prefixed with the `unsafe` keyword, to permit a sequence of unsafe operations in an otherwise-safe function.
980-
This facility exists because the static semantics of Rust are a necessary approximation of the dynamic semantics.
981-
When a programmer has sufficient conviction that a sequence of unsafe operations is actually safe, they can encapsulate that sequence (taken as a whole) within an `unsafe` block. The compiler will consider uses of such code "safe", to the surrounding context.
976+
Unsafe functions are functions that are not safe in all contexts and/or for all possible inputs.
977+
Such a function must be prefixed with the keyword `unsafe`.
978+
979+
##### Unsafe blocks
982980

981+
A block of code can also be prefixed with the `unsafe` keyword, to permit calling `unsafe` functions
982+
or dereferencing raw pointers within a safe function.
983+
984+
When a programmer has sufficient conviction that a sequence of potentially unsafe operations is
985+
actually safe, they can encapsulate that sequence (taken as a whole) within an `unsafe` block. The
986+
compiler will consider uses of such code safe, in the surrounding context.
987+
988+
Unsafe blocks are used to wrap foreign libraries, make direct use of hardware or implement features
989+
not directly present in the language. For example, Rust provides the language features necessary to
990+
implement memory-safe concurrency in the language but the implementation of tasks and message
991+
passing is in the standard library.
992+
993+
Rust's type system is a conservative approximation of the dynamic safety requirements, so in some
994+
cases there is a performance cost to using safe code. For example, a doubly-linked list is not a
995+
tree structure and can only be represented with managed or reference-counted pointers in safe code.
996+
By using `unsafe` blocks to represent the reverse links as raw pointers, it can be implemented with
997+
only owned pointers.
998+
999+
##### Behavior considered unsafe
1000+
1001+
This is a list of behavior which is forbidden in all Rust code. Type checking provides the guarantee
1002+
that these issues are never caused by safe code. An `unsafe` block or function is responsible for
1003+
never invoking this behaviour or exposing an API making it possible for it to occur in safe code.
1004+
1005+
* Data races
1006+
* Dereferencing a null/dangling raw pointer
1007+
* Mutating an immutable value/reference, if it is not marked as non-`Freeze`
1008+
* Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values) (uninitialized) memory
1009+
* Breaking the [pointer aliasing rules](http://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
1010+
with raw pointers (a subset of the rules used by C)
1011+
* Invoking undefined behavior via compiler intrinsics:
1012+
* Indexing outside of the bounds of an object with `std::ptr::offset` (`offset` intrinsic), with
1013+
the exception of one byte past the end which is permitted.
1014+
* Using `std::ptr::copy_nonoverlapping_memory` (`memcpy32`/`memcpy64` instrinsics) on
1015+
overlapping buffers
1016+
* Invalid values in primitive types, even in private fields/locals:
1017+
* Dangling/null pointers in non-raw pointers, or slices
1018+
* A value other than `false` (0) or `true` (1) in a `bool`
1019+
* A discriminant in an `enum` not included in the type definition
1020+
* A value in a `char` which is a surrogate or above `char::MAX`
1021+
* non-UTF-8 byte sequences in a `str`
1022+
1023+
##### Behaviour not considered unsafe
1024+
1025+
This is a list of behaviour not considered *unsafe* in Rust terms, but that may be undesired.
1026+
1027+
* Deadlocks
1028+
* Reading data from private fields (`std::repr`, `format!("{:?}", x)`)
1029+
* Leaks due to reference count cycles, even in the global heap
1030+
* Exiting without calling destructors
1031+
* Sending signals
1032+
* Accessing/modifying the file system
1033+
* Unsigned integer overflow (well-defined as wrapping)
1034+
* Signed integer overflow (well-defined as two's complement representation wrapping)
9831035

9841036
#### Diverging functions
9851037

0 commit comments

Comments
 (0)