Skip to content

Commit 86531cb

Browse files
committed
---
yaml --- r: 146803 b: refs/heads/try2 c: acca9e3 h: refs/heads/master i: 146801: 2370538 146799: 87d8465 v: v3
1 parent 6c8a603 commit 86531cb

File tree

98 files changed

+1490
-4392
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+1490
-4392
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: ca3274336e9d61b29f6862b4706a2a105a208f0a
8+
refs/heads/try2: acca9e3834842ee8d8104abe9b8b9bb88861793c
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/configure

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -520,20 +520,14 @@ then
520520
fi
521521
fi
522522

523-
BIN_SUF=
524-
if [ $CFG_OSTYPE = "pc-mingw32" ]
525-
then
526-
BIN_SUF=.exe
527-
fi
528-
529523
if [ ! -z "$CFG_ENABLE_LOCAL_RUST" ]
530524
then
531-
if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} ]
525+
if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc ]
532526
then
533527
err "no local rust to use"
534528
else
535-
LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} --version`
536-
step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
529+
LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc --version`
530+
step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: " $LRV
537531
fi
538532
fi
539533

branches/try2/doc/rust.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,8 +1131,9 @@ block.
11311131
let fptr: extern "C" fn() -> ~[int] = new_vec;
11321132
~~~~
11331133

1134-
Extern functions may be called directly from Rust code as Rust uses large,
1135-
contiguous stack segments like C.
1134+
Extern functions may be called from Rust code, but
1135+
caution must be taken with respect to the size of the stack
1136+
segment, just as when calling an extern function normally.
11361137

11371138
### Type definitions
11381139

@@ -2349,9 +2350,9 @@ Indices are zero-based, and may be of any integral type. Vector access
23492350
is bounds-checked at run-time. When the check fails, it will put the
23502351
task in a _failing state_.
23512352

2352-
~~~~
2353+
~~~~ {.xfail-test}
23532354
# use std::task;
2354-
# do task::spawn_unlinked {
2355+
# do task::spawn {
23552356
23562357
([1, 2, 3, 4])[0];
23572358
(["a", "b"])[10]; // fails
@@ -3596,9 +3597,9 @@ and releases them back to its environment when they are no longer needed.
35963597
The default implementation of the service-provider interface
35973598
consists of the C runtime functions `malloc` and `free`.
35983599

3599-
The runtime memory-management system, in turn, supplies Rust tasks with
3600-
facilities for allocating releasing stacks, as well as allocating and freeing
3601-
heap data.
3600+
The runtime memory-management system, in turn, supplies Rust tasks
3601+
with facilities for allocating, extending and releasing stacks,
3602+
as well as allocating and freeing heap data.
36023603

36033604
### Built in types
36043605

@@ -3761,6 +3762,7 @@ have come and gone during the course of Rust's development:
37613762

37623763
Additional specific influences can be seen from the following languages:
37633764

3765+
* The stack-growth implementation of Go.
37643766
* The structural algebraic types and compilation manager of SML.
37653767
* The attribute and assembly systems of C#.
37663768
* The references and deterministic destructor system of C++.

branches/try2/doc/tutorial-tasks.md

Lines changed: 1 addition & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -402,22 +402,6 @@ freeing memory along the way---and then exits. Unlike exceptions in C++,
402402
exceptions in Rust are unrecoverable within a single task: once a task fails,
403403
there is no way to "catch" the exception.
404404

405-
All tasks are, by default, _linked_ to each other. That means that the fates
406-
of all tasks are intertwined: if one fails, so do all the others.
407-
408-
~~~{.xfail-test .linked-failure}
409-
# use std::task::spawn;
410-
# use std::task;
411-
# fn do_some_work() { loop { task::yield() } }
412-
# do task::try {
413-
// Create a child task that fails
414-
do spawn { fail!() }
415-
416-
// This will also fail because the task we spawned failed
417-
do_some_work();
418-
# };
419-
~~~
420-
421405
While it isn't possible for a task to recover from failure, tasks may notify
422406
each other of failure. The simplest way of handling task failure is with the
423407
`try` function, which is similar to `spawn`, but immediately blocks waiting
@@ -464,101 +448,7 @@ it trips, indicates an unrecoverable logic error); in other cases you
464448
might want to contain the failure at a certain boundary (perhaps a
465449
small piece of input from the outside world, which you happen to be
466450
processing in parallel, is malformed and its processing task can't
467-
proceed). Hence, you will need different _linked failure modes_.
468-
469-
## Failure modes
470-
471-
By default, task failure is _bidirectionally linked_, which means that if
472-
either task fails, it kills the other one.
473-
474-
~~~{.xfail-test .linked-failure}
475-
# use std::task;
476-
# use std::comm::oneshot;
477-
# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }
478-
# do task::try {
479-
do spawn {
480-
do spawn {
481-
fail!(); // All three tasks will fail.
482-
}
483-
sleep_forever(); // Will get woken up by force, then fail
484-
}
485-
sleep_forever(); // Will get woken up by force, then fail
486-
# };
487-
~~~
488-
489-
If you want parent tasks to be able to kill their children, but do not want a
490-
parent to fail automatically if one of its child task fails, you can call
491-
`task::spawn_supervised` for _unidirectionally linked_ failure. The
492-
function `task::try`, which we saw previously, uses `spawn_supervised`
493-
internally, with additional logic to wait for the child task to finish
494-
before returning. Hence:
495-
496-
~~~{.xfail-test .linked-failure}
497-
# use std::comm::{stream, Chan, Port};
498-
# use std::comm::oneshot;
499-
# use std::task::{spawn, try};
500-
# use std::task;
501-
# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }
502-
# do task::try {
503-
let (receiver, sender): (Port<int>, Chan<int>) = stream();
504-
do spawn { // Bidirectionally linked
505-
// Wait for the supervised child task to exist.
506-
let message = receiver.recv();
507-
// Kill both it and the parent task.
508-
assert!(message != 42);
509-
}
510-
do try { // Unidirectionally linked
511-
sender.send(42);
512-
sleep_forever(); // Will get woken up by force
513-
}
514-
// Flow never reaches here -- parent task was killed too.
515-
# };
516-
~~~
517-
518-
Supervised failure is useful in any situation where one task manages
519-
multiple fallible child tasks, and the parent task can recover
520-
if any child fails. On the other hand, if the _parent_ (supervisor) fails,
521-
then there is nothing the children can do to recover, so they should
522-
also fail.
523-
524-
Supervised task failure propagates across multiple generations even if
525-
an intermediate generation has already exited:
526-
527-
~~~{.xfail-test .linked-failure}
528-
# use std::task;
529-
# use std::comm::oneshot;
530-
# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }
531-
# fn wait_for_a_while() { for _ in range(0, 1000u) { task::yield() } }
532-
# do task::try::<int> {
533-
do task::spawn_supervised {
534-
do task::spawn_supervised {
535-
sleep_forever(); // Will get woken up by force, then fail
536-
}
537-
// Intermediate task immediately exits
538-
}
539-
wait_for_a_while();
540-
fail!(); // Will kill grandchild even if child has already exited
541-
# };
542-
~~~
543-
544-
Finally, tasks can be configured to not propagate failure to each
545-
other at all, using `task::spawn_unlinked` for _isolated failure_.
546-
547-
~~~{.xfail-test .linked-failure}
548-
# use std::task;
549-
# fn random() -> uint { 100 }
550-
# fn sleep_for(i: uint) { for _ in range(0, i) { task::yield() } }
551-
# do task::try::<()> {
552-
let (time1, time2) = (random(), random());
553-
do task::spawn_unlinked {
554-
sleep_for(time2); // Won't get forced awake
555-
fail!();
556-
}
557-
sleep_for(time1); // Won't get forced awake
558-
fail!();
559-
// It will take MAX(time1,time2) for the program to finish.
560-
# };
561-
~~~
451+
proceed).
562452

563453
## Creating a task with a bi-directional communication path
564454

branches/try2/doc/tutorial.md

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,9 @@ calling the destructor, and the owner determines whether the object is mutable.
890890

891891
Ownership is recursive, so mutability is inherited recursively and a destructor
892892
destroys the contained tree of owned objects. Variables are top-level owners
893-
and destroy the contained object when they go out of scope.
893+
and destroy the contained object when they go out of scope. A box managed by
894+
the garbage collector starts a new ownership tree, and the destructor is called
895+
when it is collected.
894896

895897
~~~~
896898
// the struct owns the objects contained in the `x` and `y` fields
@@ -1007,6 +1009,51 @@ let mut s = r; // box becomes mutable
10071009
let t = s; // box becomes immutable
10081010
~~~~
10091011

1012+
# Managed boxes
1013+
1014+
A managed box (`@`) is a heap allocation with the lifetime managed by a
1015+
task-local garbage collector. It will be destroyed at some point after there
1016+
are no references left to the box, no later than the end of the task. Managed
1017+
boxes lack an owner, so they start a new ownership tree and don't inherit
1018+
mutability. They do own the contained object, and mutability is defined by the
1019+
type of the managed box (`@` or `@mut`). An object containing a managed box is
1020+
not `Owned`, and can't be sent between tasks.
1021+
1022+
~~~~
1023+
let a = @5; // immutable
1024+
1025+
let mut b = @5; // mutable variable, immutable box
1026+
b = @10;
1027+
1028+
let c = @mut 5; // immutable variable, mutable box
1029+
*c = 10;
1030+
1031+
let mut d = @mut 5; // mutable variable, mutable box
1032+
*d += 5;
1033+
d = @mut 15;
1034+
~~~~
1035+
1036+
A mutable variable and an immutable variable can refer to the same box, given
1037+
that their types are compatible. Mutability of a box is a property of its type,
1038+
however, so for example a mutable handle to an immutable box cannot be
1039+
assigned a reference to a mutable box.
1040+
1041+
~~~~
1042+
let a = @1; // immutable box
1043+
let b = @mut 2; // mutable box
1044+
1045+
let mut c : @int; // declare a variable with type managed immutable int
1046+
let mut d : @mut int; // and one of type managed mutable int
1047+
1048+
c = a; // box type is the same, okay
1049+
d = b; // box type is the same, okay
1050+
~~~~
1051+
1052+
~~~~ {.xfail-test}
1053+
// but b cannot be assigned to c, or a to d
1054+
c = b; // error
1055+
~~~~
1056+
10101057
# Borrowed pointers
10111058

10121059
Rust's borrowed pointers are a general purpose reference type. In contrast with
@@ -1300,53 +1347,6 @@ defined in [`std::vec`] and [`std::str`].
13001347
[`std::vec`]: std/vec/index.html
13011348
[`std::str`]: std/str/index.html
13021349
1303-
# Ownership escape hatches
1304-
1305-
Ownership can cleanly describe tree-like data structures, and borrowed pointers provide non-owning
1306-
references. However, more flexibility is often desired and Rust provides ways to escape from strict
1307-
single parent ownership.
1308-
1309-
The standard library provides the `std::rc::Rc` pointer type to express *shared ownership* over a
1310-
reference counted box. As soon as all of the `Rc` pointers go out of scope, the box and the
1311-
contained value are destroyed.
1312-
1313-
~~~
1314-
use std::rc::Rc;
1315-
1316-
// A fixed-size array allocated in a reference-counted box
1317-
let x = Rc::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1318-
let y = x.clone(); // a new owner
1319-
let z = x; // this moves `x` into `z`, rather than creating a new owner
1320-
1321-
assert_eq!(*z.borrow(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1322-
1323-
// the variable is mutable, but not the contents of the box
1324-
let mut a = Rc::new([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);
1325-
a = z;
1326-
~~~
1327-
1328-
A garbage collected pointer is provided via `std::gc::Gc`, with a task-local garbage collector
1329-
having ownership of the box. It allows the creation of cycles, and the individual `Gc` pointers do
1330-
not have a destructor.
1331-
1332-
~~~
1333-
use std::gc::Gc;
1334-
1335-
// A fixed-size array allocated in a garbage-collected box
1336-
let x = Gc::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1337-
let y = x; // does not perform a move, unlike with `Rc`
1338-
let z = x;
1339-
1340-
assert_eq!(*z.borrow(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1341-
~~~
1342-
1343-
With shared ownership, mutability cannot be inherited so the boxes are always immutable. However,
1344-
it's possible to use *dynamic* mutability via types like `std::cell::Cell` where freezing is handled
1345-
via dynamic checks and can fail at runtime.
1346-
1347-
The `Rc` and `Gc` types are not sendable, so they cannot be used to share memory between tasks. Safe
1348-
immutable and mutable shared memory is provided by the `extra::arc` module.
1349-
13501350
# Closures
13511351
13521352
Named functions, like those we've seen so far, may not refer to local

0 commit comments

Comments
 (0)