Skip to content

Commit 7662788

Browse files
committed
---
yaml --- r: 83234 b: refs/heads/try c: c3ad785 h: refs/heads/master v: v3
1 parent e66f7a1 commit 7662788

File tree

9 files changed

+88
-182
lines changed

9 files changed

+88
-182
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 0e4d1fc8cae42e15e00f71d9f439b01bb25a86ae
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 6c08cc2db4f98e9f07ae7d50338396c4123c2f0a
5-
refs/heads/try: bf0e2a6f578251c093f935a9cdf100bba7ebf581
5+
refs/heads/try: c3ad785d83b583ad693424d9f0f993e36f0990f5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/doc/rust.md

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

964964

965-
#### Unsafety
965+
#### Unsafe functions
966966

967-
Unsafe operations are those that potentially violate the memory-safety guarantees of Rust's static semantics.
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`.
968969

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

971973
- Dereferencing a [raw pointer](#pointer-types).
972-
- Calling an unsafe function (including an intrinsic or foreign function).
973-
974-
##### Unsafe functions
975-
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`.
974+
- Casting a [raw pointer](#pointer-types) to a safe pointer type.
975+
- Calling an unsafe function.
978976

979977
##### Unsafe blocks
980978

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)
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.
982+
1035983

1036984
#### Diverging functions
1037985

branches/try/doc/tutorial-container.md

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44

55
The container traits are defined in the `std::container` module.
66

7-
## Unique vectors
7+
## Unique and managed vectors
88

9-
Vectors have `O(1)` indexing, push (to the end) and pop (from the end). Vectors
10-
are the most common container in Rust, and are flexible enough to fit many use
11-
cases.
9+
Vectors have `O(1)` indexing and removal from the end, along with `O(1)`
10+
amortized insertion. Vectors are the most common container in Rust, and are
11+
flexible enough to fit many use cases.
1212

1313
Vectors can also be sorted and used as efficient lookup tables with the
14-
`bsearch()` method, if all the elements are inserted at one time and
14+
`std::vec::bsearch` function, if all the elements are inserted at one time and
1515
deletions are unnecessary.
1616

1717
## Maps and sets
@@ -42,15 +42,10 @@ implementing the `IterBytes` trait.
4242

4343
## Double-ended queues
4444

45-
The `extra::ringbuf` module implements a double-ended queue with `O(1)`
46-
amortized inserts and removals from both ends of the container. It also has
47-
`O(1)` indexing like a vector. The contained elements are not required to be
48-
copyable, and the queue will be sendable if the contained type is sendable.
49-
Its interface `Deque` is defined in `extra::collections`.
50-
51-
The `extra::dlist` module implements a double-ended linked list, also
52-
implementing the `Deque` trait, with `O(1)` removals and inserts at either end,
53-
and `O(1)` concatenation.
45+
The `extra::deque` module implements a double-ended queue with `O(1)` amortized
46+
inserts and removals from both ends of the container. It also has `O(1)`
47+
indexing like a vector. The contained elements are not required to be copyable,
48+
and the queue will be sendable if the contained type is sendable.
5449

5550
## Priority queues
5651

@@ -202,11 +197,11 @@ The function `range` (or `range_inclusive`) allows to simply iterate through a g
202197
203198
~~~
204199
for i in range(0, 5) {
205-
print!("{} ", i) // prints "0 1 2 3 4"
200+
printf!("%d ", i) // prints "0 1 2 3 4"
206201
}
207202

208203
for i in std::iter::range_inclusive(0, 5) { // needs explicit import
209-
print!("{} ", i) // prints "0 1 2 3 4 5"
204+
printf!("%d ", i) // prints "0 1 2 3 4 5"
210205
}
211206
~~~
212207
@@ -238,15 +233,15 @@ let mut it = xs.iter().zip(ys.iter());
238233

239234
// print out the pairs of elements up to (&3, &"baz")
240235
for (x, y) in it {
241-
println!("{} {}", *x, *y);
236+
printfln!("%d %s", *x, *y);
242237

243238
if *x == 3 {
244239
break;
245240
}
246241
}
247242

248243
// yield and print the last pair from the iterator
249-
println!("last: {:?}", it.next());
244+
printfln!("last: %?", it.next());
250245

251246
// the iterator is now fully consumed
252247
assert!(it.next().is_none());
@@ -340,13 +335,13 @@ another `DoubleEndedIterator` with `next` and `next_back` exchanged.
340335
~~~
341336
let xs = [1, 2, 3, 4, 5, 6];
342337
let mut it = xs.iter();
343-
println!("{:?}", it.next()); // prints `Some(&1)`
344-
println!("{:?}", it.next()); // prints `Some(&2)`
345-
println!("{:?}", it.next_back()); // prints `Some(&6)`
338+
printfln!("%?", it.next()); // prints `Some(&1)`
339+
printfln!("%?", it.next()); // prints `Some(&2)`
340+
printfln!("%?", it.next_back()); // prints `Some(&6)`
346341
347342
// prints `5`, `4` and `3`
348343
for &x in it.invert() {
349-
println!("{}", x)
344+
printfln!("%?", x)
350345
}
351346
~~~
352347

@@ -361,11 +356,11 @@ let xs = [1, 2, 3, 4];
361356
let ys = [5, 6, 7, 8];
362357
let mut it = xs.iter().chain(ys.iter()).map(|&x| x * 2);
363358
364-
println!("{:?}", it.next()); // prints `Some(2)`
359+
printfln!("%?", it.next()); // prints `Some(2)`
365360
366361
// prints `16`, `14`, `12`, `10`, `8`, `6`, `4`
367362
for x in it.invert() {
368-
println!("{}", x);
363+
printfln!("%?", x);
369364
}
370365
~~~
371366

@@ -392,17 +387,17 @@ underlying iterators are.
392387
let xs = [1, 2, 3, 4, 5];
393388
let ys = ~[7, 9, 11];
394389
let mut it = xs.iter().chain(ys.iter());
395-
println!("{:?}", it.idx(0)); // prints `Some(&1)`
396-
println!("{:?}", it.idx(5)); // prints `Some(&7)`
397-
println!("{:?}", it.idx(7)); // prints `Some(&11)`
398-
println!("{:?}", it.idx(8)); // prints `None`
390+
printfln!("%?", it.idx(0)); // prints `Some(&1)`
391+
printfln!("%?", it.idx(5)); // prints `Some(&7)`
392+
printfln!("%?", it.idx(7)); // prints `Some(&11)`
393+
printfln!("%?", it.idx(8)); // prints `None`
399394
400395
// yield two elements from the beginning, and one from the end
401396
it.next();
402397
it.next();
403398
it.next_back();
404399
405-
println!("{:?}", it.idx(0)); // prints `Some(&3)`
406-
println!("{:?}", it.idx(4)); // prints `Some(&9)`
407-
println!("{:?}", it.idx(6)); // prints `None`
400+
printfln!("%?", it.idx(0)); // prints `Some(&3)`
401+
printfln!("%?", it.idx(4)); // prints `Some(&9)`
402+
printfln!("%?", it.idx(6)); // prints `None`
408403
~~~

branches/try/mk/rt.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ RUNTIME_CXXS_$(1)_$(2) := \
7171
rt/sync/lock_and_signal.cpp \
7272
rt/sync/rust_thread.cpp \
7373
rt/rust_builtin.cpp \
74-
rt/rust_run_program.cpp \
7574
rt/rust_rng.cpp \
7675
rt/rust_upcall.cpp \
7776
rt/rust_uv.cpp \

branches/try/src/libstd/run.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -643,15 +643,28 @@ fn spawn_process_os(prog: &str, args: &[~str],
643643
use libc::funcs::bsd44::getdtablesize;
644644

645645
mod rustrt {
646-
use libc::c_void;
647-
648646
#[abi = "cdecl"]
649647
extern {
650648
pub fn rust_unset_sigprocmask();
651-
pub fn rust_set_environ(envp: *c_void);
652649
}
653650
}
654651

652+
#[cfg(windows)]
653+
unsafe fn set_environ(_envp: *c_void) {}
654+
#[cfg(target_os = "macos")]
655+
unsafe fn set_environ(envp: *c_void) {
656+
externfn!(fn _NSGetEnviron() -> *mut *c_void);
657+
658+
*_NSGetEnviron() = envp;
659+
}
660+
#[cfg(not(target_os = "macos"), not(windows))]
661+
unsafe fn set_environ(envp: *c_void) {
662+
extern {
663+
static mut environ: *c_void;
664+
}
665+
environ = envp;
666+
}
667+
655668
unsafe {
656669

657670
let pid = fork();
@@ -685,7 +698,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
685698

686699
do with_envp(env) |envp| {
687700
if !envp.is_null() {
688-
rustrt::rust_set_environ(envp);
701+
set_environ(envp);
689702
}
690703
do with_argv(prog, args) |argv| {
691704
execvp(*argv, argv);

branches/try/src/libsyntax/ext/bytes.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,43 +30,43 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) -> bas
3030
// string literal, push each byte to vector expression
3131
ast::lit_str(s) => {
3232
for byte in s.byte_iter() {
33-
bytes.push(cx.expr_u8(expr.span, byte));
33+
bytes.push(cx.expr_u8(sp, byte));
3434
}
3535
}
3636

3737
// u8 literal, push to vector expression
3838
ast::lit_uint(v, ast::ty_u8) => {
3939
if v > 0xFF {
40-
cx.span_err(expr.span, "Too large u8 literal in bytes!")
40+
cx.span_err(sp, "Too large u8 literal in bytes!")
4141
} else {
42-
bytes.push(cx.expr_u8(expr.span, v as u8));
42+
bytes.push(cx.expr_u8(sp, v as u8));
4343
}
4444
}
4545

4646
// integer literal, push to vector expression
4747
ast::lit_int_unsuffixed(v) => {
4848
if v > 0xFF {
49-
cx.span_err(expr.span, "Too large integer literal in bytes!")
49+
cx.span_err(sp, "Too large integer literal in bytes!")
5050
} else if v < 0 {
51-
cx.span_err(expr.span, "Negative integer literal in bytes!")
51+
cx.span_err(sp, "Negative integer literal in bytes!")
5252
} else {
53-
bytes.push(cx.expr_u8(expr.span, v as u8));
53+
bytes.push(cx.expr_u8(sp, v as u8));
5454
}
5555
}
5656

5757
// char literal, push to vector expression
5858
ast::lit_char(v) => {
5959
if char::from_u32(v).unwrap().is_ascii() {
60-
bytes.push(cx.expr_u8(expr.span, v as u8));
60+
bytes.push(cx.expr_u8(sp, v as u8));
6161
} else {
62-
cx.span_err(expr.span, "Non-ascii char literal in bytes!")
62+
cx.span_err(sp, "Non-ascii char literal in bytes!")
6363
}
6464
}
6565

66-
_ => cx.span_err(expr.span, "Unsupported literal in bytes!")
66+
_ => cx.span_err(sp, "Unsupported literal in bytes!")
6767
},
6868

69-
_ => cx.span_err(expr.span, "Non-literal in bytes!")
69+
_ => cx.span_err(sp, "Non-literal in bytes!")
7070
}
7171
}
7272

branches/try/src/rt/rust_builtin.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,29 @@ rust_valgrind_stack_deregister(unsigned int id) {
643643
VALGRIND_STACK_DEREGISTER(id);
644644
}
645645

646+
#if defined(__WIN32__)
647+
648+
extern "C" CDECL void
649+
rust_unset_sigprocmask() {
650+
// empty stub for windows to keep linker happy
651+
}
652+
653+
#else
654+
655+
#include <signal.h>
656+
#include <unistd.h>
657+
658+
extern "C" CDECL void
659+
rust_unset_sigprocmask() {
660+
// this can't be safely converted to rust code because the
661+
// representation of sigset_t is platform-dependent
662+
sigset_t sset;
663+
sigemptyset(&sset);
664+
sigprocmask(SIG_SETMASK, &sset, NULL);
665+
}
666+
667+
#endif
668+
646669
//
647670
// Local Variables:
648671
// mode: C++

0 commit comments

Comments
 (0)