Skip to content

Commit ab3836b

Browse files
committed
---
yaml --- r: 81647 b: refs/heads/master c: c0cc37b h: refs/heads/master i: 81645: 7ec1ebf 81643: 26b617f 81639: 2021bab 81631: fdc760d v: v3
1 parent 79c346d commit ab3836b

File tree

4 files changed

+67
-41
lines changed

4 files changed

+67
-41
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: fd0fcba9f5b2ec9cb504d6f322c2dd89ab891e08
2+
refs/heads/master: c0cc37b96398aa21ca6f718cbe7170210ea337d9
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 6c08cc2db4f98e9f07ae7d50338396c4123c2f0a
55
refs/heads/try: 70152ff55722878cde684ee6462c14c65f2c4729

trunk/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

trunk/src/librustc/middle/trans/base.rs

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,38 +2388,12 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
23882388
let et = ccx.sess.entry_type.unwrap();
23892389
match et {
23902390
session::EntryMain => {
2391-
let llfn = create_main(ccx, main_llfn);
2392-
create_entry_fn(ccx, llfn, true);
2391+
create_entry_fn(ccx, main_llfn, true);
23932392
}
23942393
session::EntryStart => create_entry_fn(ccx, main_llfn, false),
23952394
session::EntryNone => {} // Do nothing.
23962395
}
23972396

2398-
fn create_main(ccx: @mut CrateContext, main_llfn: ValueRef) -> ValueRef {
2399-
let nt = ty::mk_nil();
2400-
let llfty = type_of_rust_fn(ccx, [], nt);
2401-
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
2402-
lib::llvm::CCallConv, llfty);
2403-
2404-
let fcx = new_fn_ctxt(ccx, ~[], llfdecl, nt, None);
2405-
2406-
// the args vector built in create_entry_fn will need
2407-
// be updated if this assertion starts to fail.
2408-
assert!(!fcx.caller_expects_out_pointer);
2409-
2410-
let bcx = fcx.entry_bcx.unwrap();
2411-
// Call main.
2412-
let llenvarg = unsafe {
2413-
let env_arg = fcx.env_arg_pos();
2414-
llvm::LLVMGetParam(llfdecl, env_arg as c_uint)
2415-
};
2416-
let args = ~[llenvarg];
2417-
Call(bcx, main_llfn, args, []);
2418-
2419-
finish_fn(fcx, bcx);
2420-
return llfdecl;
2421-
}
2422-
24232397
fn create_entry_fn(ccx: @mut CrateContext,
24242398
rust_main: ValueRef,
24252399
use_start_lang_item: bool) {

trunk/src/libstd/str.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,8 +1107,8 @@ pub mod raw {
11071107
Some(limit) => (true, limit),
11081108
None => (false, 0)
11091109
};
1110-
while(((limited_count && ctr < limit) || !limited_count)
1111-
&& *(curr_ptr as *libc::c_char) != 0 as libc::c_char) {
1110+
while(*(curr_ptr as *libc::c_char) != 0 as libc::c_char
1111+
&& ((limited_count && ctr < limit) || !limited_count)) {
11121112
let env_pair = from_c_str(
11131113
curr_ptr as *libc::c_char);
11141114
result.push(env_pair);

0 commit comments

Comments
 (0)