Skip to content

Commit 5947141

Browse files
committed
Add section on unsafe functions, reword explanation on unsafe-overriding-purity.
1 parent cb4c747 commit 5947141

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

doc/rust.md

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -960,24 +960,12 @@ pure fn pure_length<T>(ls: List<T>) -> uint { ... }
960960
pure fn nonempty_list<T>(ls: List<T>) -> bool { pure_length(ls) > 0u }
961961
~~~~
962962

963-
*TODO:* should actually define referential transparency.
964-
965-
The effect checking rules previously enumerated are a restricted set
966-
of typechecking rules meant to approximate the universe of observably
967-
referentially transparent Rust procedures conservatively. Sometimes,
968-
these rules are *too* restrictive. Rust allows programmers to violate
969-
these rules by writing pure functions that the compiler cannot prove
970-
to be referentially transparent, using "unsafe blocks". When writing
971-
code that uses unsafe blocks, programmers should always be aware that
972-
they have an obligation to show that the code *behaves* referentially
973-
transparently at all times, even if the compiler cannot *prove*
974-
automatically that the code is referentially transparent. In the
975-
presence of unsafe blocks, the compiler provides no static guarantee
976-
that the code will behave as expected at runtime. Rather, the
977-
programmer has an independent obligation to verify the semantics of
978-
the pure functions they write.
979-
980-
*TODO:* last two sentences are vague.
963+
These purity-checking rules approximate the concept of referential transparency:
964+
that a call-expression could be rewritten with the literal-expression of its return value, without changing the meaning of the program.
965+
Since they are an approximation, sometimes these rules are *too* restrictive.
966+
Rust allows programmers to violate these rules using [`unsafe` blocks](#unsafe-blocks).
967+
As with any `unsafe` block, those that violate static purity carry transfer the burden of safety-proof from the compiler to the programmer.
968+
Programmers should exercise caution when breaking such rules.
981969

982970
An example of a pure function that uses an unsafe block:
983971

@@ -1045,6 +1033,28 @@ Similarly, [trait](#traits) bounds can be specified for type
10451033
parameters to allow methods with that trait to be called on values
10461034
of that type.
10471035

1036+
#### Unsafe functions
1037+
1038+
Unsafe functions are those containing unsafe operations that are not contained in an [`unsafe` block](#unsafe-blocks).
1039+
1040+
Unsafe operations are those that potentially violate the memory-safety guarantees of Rust's static semantics.
1041+
Specifically, the following operations are considered unsafe:
1042+
1043+
- Dereferencing a [raw pointer](#pointer-types)
1044+
- Casting a [raw pointer](#pointer-types) to a safe pointer type
1045+
- Breaking the [purity-checking rules](#pure-functions)
1046+
- Calling an unsafe function
1047+
1048+
##### Unsafe blocks
1049+
1050+
A block of code can also be prefixed with the `unsafe` keyword,
1051+
to permit a sequence of unsafe operations in an otherwise-safe function.
1052+
This facility exists because the static semantics of a Rust are a necessary approximation of the dynamic semantics.
1053+
When a programmer has sufficient conviction that a sequence of unsafe operations is actually safe,
1054+
they can encapsulate that sequence (taken as a whole) within an `unsafe` block.
1055+
The compiler will consider uses of such code "safe", to the surrounding context.
1056+
1057+
10481058
#### Extern functions
10491059

10501060
Extern functions are part of Rust's foreign function interface, providing
@@ -1059,7 +1069,7 @@ extern fn new_vec() -> ~[int] { ~[] }
10591069
~~~
10601070

10611071
Extern functions may not be called from Rust code, but their value
1062-
may be taken as an unsafe `u8` pointer.
1072+
may be taken as a raw `u8` pointer.
10631073

10641074
~~~
10651075
# extern fn new_vec() -> ~[int] { ~[] }
@@ -2852,7 +2862,7 @@ exploiting.]
28522862
### Communication between tasks
28532863

28542864
Rust tasks are isolated and generally unable to interfere with one another's memory directly,
2855-
except through [`unsafe` code](#unsafe-code).
2865+
except through [`unsafe` code](#unsafe-functions).
28562866
All contact between tasks is mediated by safe forms of ownership transfer,
28572867
and data races on memory are prohibited by the type system.
28582868

0 commit comments

Comments
 (0)