Skip to content

Commit d7b044c

Browse files
committed
---
yaml --- r: 85731 b: refs/heads/dist-snap c: 7b5a91f h: refs/heads/master i: 85729: 63f5ce3 85727: ab81f06 v: v3
1 parent 9f95dbd commit d7b044c

File tree

5 files changed

+6
-185
lines changed

5 files changed

+6
-185
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: 0983ebe5310d4eb6d289f636f7ed0536c08bbc0e
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: d468b7c0bfff9e805bd96daf21c1c5a023d12734
9+
refs/heads/dist-snap: 7b5a91f4b346b99b4e9171eb8deb52d9bf2525ea
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/doc/tutorial.md

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,7 +1864,7 @@ so you could not apply `head` to a type
18641864
that does not implement `Clone`.
18651865

18661866
While most traits can be defined and implemented by user code,
1867-
three traits are automatically derived and implemented
1867+
two traits are automatically derived and implemented
18681868
for all applicable types by the compiler,
18691869
and may not be overridden:
18701870

@@ -1877,12 +1877,6 @@ These are types that do not contain anything intrinsically mutable.
18771877
Intrinsically mutable values include `@mut`
18781878
and `Cell` in the standard library.
18791879

1880-
* `'static` - Non-borrowed types.
1881-
These are types that do not contain any data whose lifetime is bound to
1882-
a particular stack frame. These are types that do not contain any
1883-
borrowed pointers, or types where the only contained borrowed pointers
1884-
have the `'static` lifetime.
1885-
18861880
> ***Note:*** These two traits were referred to as 'kinds' in earlier
18871881
> iterations of the language, and often still are.
18881882
@@ -2141,30 +2135,6 @@ select the method to call at runtime.
21412135

21422136
This usage of traits is similar to Java interfaces.
21432137

2144-
By default, each of the three storage classes for traits enforce a
2145-
particular set of built-in kinds that their contents must fulfill in
2146-
order to be packaged up in a trait object of that storage class.
2147-
2148-
* The contents of owned traits (`~Trait`) must fulfill the `Send` bound.
2149-
* The contents of managed traits (`@Trait`) must fulfill the `'static` bound.
2150-
* The contents of borrowed traits (`&Trait`) are not constrained by any bound.
2151-
2152-
Consequently, the trait objects themselves automatically fulfill their
2153-
respective kind bounds. However, this default behavior can be overridden by
2154-
specifying a list of bounds on the trait type, for example, by writing `~Trait:`
2155-
(which indicates that the contents of the owned trait need not fulfill any
2156-
bounds), or by writing `~Trait:Send+Freeze`, which indicates that in addition
2157-
to fulfilling `Send`, contents must also fulfill `Freeze`, and as a consequence,
2158-
the trait itself fulfills `Freeze`.
2159-
2160-
* `~Trait:Send` is equivalent to `~Trait`.
2161-
* `@Trait:'static` is equivalent to `@Trait`.
2162-
* `&Trait:` is equivalent to `&Trait`.
2163-
2164-
Builtin kind bounds can also be specified on closure types in the same way (for
2165-
example, by writing `fn:Freeze()`), and the default behaviours are the same as
2166-
for traits of the same storage class.
2167-
21682138
## Trait inheritance
21692139

21702140
We can write a trait declaration that _inherits_ from other traits, called _supertraits_.

branches/dist-snap/src/librustc/middle/trans/monomorphize.rs

Lines changed: 2 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,13 @@ use middle::trans::type_of;
2626
use middle::trans::type_use;
2727
use middle::trans::intrinsic;
2828
use middle::ty;
29-
use middle::ty::{FnSig};
3029
use middle::typeck;
3130
use util::ppaux::{Repr,ty_to_str};
3231

3332
use syntax::ast;
3433
use syntax::ast_map;
3534
use syntax::ast_map::path_name;
3635
use syntax::ast_util::local_def;
37-
use syntax::opt_vec;
38-
use syntax::abi::AbiSet;
3936

4037
pub fn monomorphic_fn(ccx: @mut CrateContext,
4138
fn_id: ast::def_id,
@@ -61,17 +58,10 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
6158
let _icx = push_ctxt("monomorphic_fn");
6259
let mut must_cast = false;
6360

64-
let do_normalize = |t: &ty::t| {
65-
match normalize_for_monomorphization(ccx.tcx, *t) {
66-
Some(t) => { must_cast = true; t }
67-
None => *t
68-
}
69-
};
70-
7161
let psubsts = @param_substs {
72-
tys: real_substs.tps.map(|x| do_normalize(x)),
62+
tys: real_substs.tps.to_owned(),
7363
vtables: vtables,
74-
self_ty: real_substs.self_ty.map(|x| do_normalize(x)),
64+
self_ty: real_substs.self_ty.clone(),
7565
self_vtables: self_vtables
7666
};
7767

@@ -305,61 +295,6 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
305295
(lldecl, must_cast)
306296
}
307297

308-
pub fn normalize_for_monomorphization(tcx: ty::ctxt,
309-
ty: ty::t) -> Option<ty::t> {
310-
// FIXME[mono] could do this recursively. is that worthwhile? (#2529)
311-
return match ty::get(ty).sty {
312-
ty::ty_box(*) => {
313-
Some(ty::mk_opaque_box(tcx))
314-
}
315-
ty::ty_bare_fn(_) => {
316-
Some(ty::mk_bare_fn(
317-
tcx,
318-
ty::BareFnTy {
319-
purity: ast::impure_fn,
320-
abis: AbiSet::Rust(),
321-
sig: FnSig {bound_lifetime_names: opt_vec::Empty,
322-
inputs: ~[],
323-
output: ty::mk_nil()}}))
324-
}
325-
ty::ty_closure(ref fty) => {
326-
Some(normalized_closure_ty(tcx, fty.sigil))
327-
}
328-
ty::ty_trait(_, _, ref store, _, _) => {
329-
let sigil = match *store {
330-
ty::UniqTraitStore => ast::OwnedSigil,
331-
ty::BoxTraitStore => ast::ManagedSigil,
332-
ty::RegionTraitStore(_) => ast::BorrowedSigil,
333-
};
334-
335-
// Traits have the same runtime representation as closures.
336-
Some(normalized_closure_ty(tcx, sigil))
337-
}
338-
ty::ty_ptr(_) => {
339-
Some(ty::mk_uint())
340-
}
341-
_ => {
342-
None
343-
}
344-
};
345-
346-
fn normalized_closure_ty(tcx: ty::ctxt,
347-
sigil: ast::Sigil) -> ty::t
348-
{
349-
ty::mk_closure(
350-
tcx,
351-
ty::ClosureTy {
352-
purity: ast::impure_fn,
353-
sigil: sigil,
354-
onceness: ast::Many,
355-
region: ty::re_static,
356-
bounds: ty::EmptyBuiltinBounds(),
357-
sig: ty::FnSig {bound_lifetime_names: opt_vec::Empty,
358-
inputs: ~[],
359-
output: ty::mk_nil()}})
360-
}
361-
}
362-
363298
pub fn make_mono_id(ccx: @mut CrateContext,
364299
item: ast::def_id,
365300
substs: &param_substs,

branches/dist-snap/src/libstd/repr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ fn test_repr() {
590590
exact_test(&(~"he\u10f3llo"), "~\"he\\u10f3llo\"");
591591

592592
exact_test(&(@10), "@10");
593-
exact_test(&(@mut 10), "@10"); // FIXME: #4210: incorrect
593+
exact_test(&(@mut 10), "@mut 10");
594594
exact_test(&((@mut 10, 2)), "(@mut 10, 2)");
595595
exact_test(&(~10), "~10");
596596
exact_test(&(&10), "&10");

branches/dist-snap/src/libstd/rt/kill.rs

Lines changed: 1 addition & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ observed by the parent of a task::try task that itself spawns child tasks
2020
(such as any #[test] function). In both cases the data structures live in
2121
KillHandle.
2222
23-
2423
I. Task killing.
2524
2625
The model for killing involves two atomic flags, the "kill flag" and the
@@ -61,92 +60,9 @@ killer does perform both writes, it means it saw a KILL_RUNNING in the
6160
unkillable flag, which means an unkillable task will see KILL_KILLED and fail
6261
immediately (rendering the subsequent write to the kill flag unnecessary).
6362
64-
6563
II. Exit code propagation.
6664
67-
The basic model for exit code propagation, which is used with the "watched"
68-
spawn mode (on by default for linked spawns, off for supervised and unlinked
69-
spawns), is that a parent will wait for all its watched children to exit
70-
before reporting whether it succeeded or failed. A watching parent will only
71-
report success if it succeeded and all its children also reported success;
72-
otherwise, it will report failure. This is most useful for writing test cases:
73-
74-
~~~
75-
#[test]
76-
fn test_something_in_another_task {
77-
do spawn {
78-
assert!(collatz_conjecture_is_false());
79-
}
80-
}
81-
~~~
82-
83-
Here, as the child task will certainly outlive the parent task, we might miss
84-
the failure of the child when deciding whether or not the test case passed.
85-
The watched spawn mode avoids this problem.
86-
87-
In order to propagate exit codes from children to their parents, any
88-
'watching' parent must wait for all of its children to exit before it can
89-
report its final exit status. We achieve this by using an UnsafeArc, using the
90-
reference counting to track how many children are still alive, and using the
91-
unwrap() operation in the parent's exit path to wait for all children to exit.
92-
The UnsafeArc referred to here is actually the KillHandle itself.
93-
94-
This also works transitively, as if a "middle" watched child task is itself
95-
watching a grandchild task, the "middle" task will do unwrap() on its own
96-
KillHandle (thereby waiting for the grandchild to exit) before dropping its
97-
reference to its watching parent (which will alert the parent).
98-
99-
While UnsafeArc::unwrap() accomplishes the synchronization, there remains the
100-
matter of reporting the exit codes themselves. This is easiest when an exiting
101-
watched task has no watched children of its own:
102-
103-
- If the task with no watched children exits successfully, it need do nothing.
104-
- If the task with no watched children has failed, it sets a flag in the
105-
parent's KillHandle ("any_child_failed") to false. It then stays false forever.
106-
107-
However, if a "middle" watched task with watched children of its own exits
108-
before its child exits, we need to ensure that the grandparent task may still
109-
see a failure from the grandchild task. While we could achieve this by having
110-
each intermediate task block on its handle, this keeps around the other resources
111-
the task was using. To be more efficient, this is accomplished via "tombstones".
112-
113-
A tombstone is a closure, ~fn() -> bool, which will perform any waiting necessary
114-
to collect the exit code of descendant tasks. In its environment is captured
115-
the KillHandle of whichever task created the tombstone, and perhaps also any
116-
tombstones that that task itself had, and finally also another tombstone,
117-
effectively creating a lazy-list of heap closures.
118-
119-
When a child wishes to exit early and leave tombstones behind for its parent,
120-
it must use a LittleLock (pthread mutex) to synchronize with any possible
121-
sibling tasks which are trying to do the same thing with the same parent.
122-
However, on the other side, when the parent is ready to pull on the tombstones,
123-
it need not use this lock, because the unwrap() serves as a barrier that ensures
124-
no children will remain with references to the handle.
125-
126-
The main logic for creating and assigning tombstones can be found in the
127-
function reparent_children_to() in the impl for KillHandle.
128-
129-
130-
IIA. Issues with exit code propagation.
131-
132-
There are two known issues with the current scheme for exit code propagation.
133-
134-
- As documented in issue #8136, the structure mandates the possibility for stack
135-
overflow when collecting tombstones that are very deeply nested. This cannot
136-
be avoided with the closure representation, as tombstones end up structured in
137-
a sort of tree. However, notably, the tombstones do not actually need to be
138-
collected in any particular order, and so a doubly-linked list may be used.
139-
However we do not do this yet because DList is in libextra.
140-
141-
- A discussion with Graydon made me realize that if we decoupled the exit code
142-
propagation from the parents-waiting action, this could result in a simpler
143-
implementation as the exit codes themselves would not have to be propagated,
144-
and could instead be propagated implicitly through the taskgroup mechanism
145-
that we already have. The tombstoning scheme would still be required. I have
146-
not implemented this because currently we can't receive a linked failure kill
147-
signal during the task cleanup activity, as that is currently "unkillable",
148-
and occurs outside the task's unwinder's "try" block, so would require some
149-
restructuring.
65+
FIXME(#7544): Decide on the ultimate model for this and document it.
15066
15167
*/
15268

0 commit comments

Comments
 (0)