|
10 | 10 | *
|
11 | 11 | *
|
12 | 12 | *
|
13 |
| -* COPY + SEND = "Unique": no shared substructures or pins, only |
| 13 | +* MOVE + SEND = "Unique": no shared substructures or pins, only |
14 | 14 | * interiors and ~ boxes.
|
15 | 15 | *
|
16 |
| -* COPY + NOSEND = "Shared": structures containing @, fixed to the local |
17 |
| -* task heap/pool. |
| 16 | +* MOVE + NOSEND = "Shared": structures containing @, fixed to the local |
| 17 | +* task heap/pool; or ~ structures pointing to |
| 18 | +* pinned values. |
18 | 19 | *
|
19 |
| -* NOCOPY + NOSEND = "Pinned": structures containing resources or |
| 20 | +* NOMOVE + NOSEND = "Pinned": structures directly containing resources, or |
20 | 21 | * by-alias closures as interior or
|
21 | 22 | * uniquely-boxed members.
|
22 | 23 | *
|
23 |
| -* NOCOPY + SEND = -- : no types are like this. |
| 24 | +* NOMOVE + SEND = -- : no types are like this. |
24 | 25 | *
|
25 | 26 | *
|
26 | 27 | * Since this forms a lattice, we denote the capabilites in terms of a
|
27 |
| -* worst-case requirement. That is, if your function needs to copy-and-send |
28 |
| -* your T, you write fn<~T>(...). If you need to copy but not send, you write |
29 |
| -* fn<@T>(...). And if you need neither -- can work with any sort of pinned |
30 |
| -* data at all -- then you write fn<T>(...). |
| 28 | +* worst-case requirement. That is, if your function needs to move-and-send |
| 29 | +* (or copy) your T, you write fn<~T>(...). If you need to copy but not send, |
| 30 | +* you write fn<@T>(...). And if you need neither -- can work with any sort of |
| 31 | +* pinned data at all -- then you write fn<T>(...). |
31 | 32 | *
|
32 | 33 | *
|
33 | 34 | * Most types are unique or shared. Other possible name combinations for these
|
|
54 | 55 | * A copy is made any time you pass-by-value or execute the = operator in a
|
55 | 56 | * non-init expression.
|
56 | 57 | *
|
57 |
| -* ~ copies deep |
58 |
| -* @ copies shallow |
| 58 | +* @ copies shallow, is always legal |
| 59 | +* ~ copies deep, is only legal if pointee is unique. |
59 | 60 | * pinned values (pinned resources, alias-closures) can't be copied
|
60 |
| -* all other interiors copy shallow |
| 61 | +* all other unique (eg. interior) values copy shallow |
| 62 | +* |
| 63 | +* Note this means that only type parameters constrained to ~T can be copied. |
61 | 64 | *
|
62 | 65 | * MOVING:
|
63 | 66 | * -------
|
64 | 67 | *
|
65 | 68 | * A move is made any time you pass-by-move (that is, with 'move' mode) or
|
66 | 69 | * execute the <- operator.
|
67 | 70 | *
|
68 |
| -* Anything you can copy, you can move. Move is (semantically) just |
69 |
| -* shallow-copy + deinit. Note that: ~ moves shallow even though it copies |
70 |
| -* deep. Move is the operator that lets ~ copy shallow: by pairing it with a |
71 |
| -* deinit. |
72 |
| -* |
73 | 71 | */
|
74 | 72 |
|
75 | 73 |
|
@@ -101,11 +99,47 @@ fn kind_to_str(k: kind) -> str {
|
101 | 99 | }
|
102 | 100 | }
|
103 | 101 |
|
104 |
| -fn check_expr(tcx: &ty::ctxt, e: &@ast::expr) { |
| 102 | +fn type_and_kind(tcx: &ty::ctxt, e: &@ast::expr) |
| 103 | + -> {ty: ty::t, kind: ast::kind} { |
105 | 104 | let t = ty::expr_ty(tcx, e);
|
106 | 105 | let k = ty::type_kind(tcx, t);
|
107 |
| - log #fmt("%s type: %s", kind_to_str(k), |
108 |
| - util::ppaux::ty_to_str(tcx, t)); |
| 106 | + {ty: t, kind: k} |
| 107 | +} |
| 108 | + |
| 109 | +fn need_expr_kind(tcx: &ty::ctxt, e: &@ast::expr, |
| 110 | + k_need: ast::kind, descr: &str) { |
| 111 | + let tk = type_and_kind(tcx, e); |
| 112 | + log #fmt("for %s: want %s type, got %s type %s", |
| 113 | + descr, |
| 114 | + kind_to_str(k_need), |
| 115 | + kind_to_str(tk.kind), |
| 116 | + util::ppaux::ty_to_str(tcx, tk.ty)); |
| 117 | + |
| 118 | + if ! kind_lteq(k_need, tk.kind) { |
| 119 | + let s = |
| 120 | + #fmt("mismatched kinds for %s: needed %s type, got %s type %s", |
| 121 | + descr, |
| 122 | + kind_to_str(k_need), |
| 123 | + kind_to_str(tk.kind), |
| 124 | + util::ppaux::ty_to_str(tcx, tk.ty)); |
| 125 | + tcx.sess.span_err(e.span, s); |
| 126 | + } |
| 127 | +} |
| 128 | + |
| 129 | +fn need_shared_lhs_rhs(tcx: &ty::ctxt, |
| 130 | + a: &@ast::expr, b: &@ast::expr, |
| 131 | + op: &str) { |
| 132 | + need_expr_kind(tcx, a, ast::kind_shared, op + " lhs"); |
| 133 | + need_expr_kind(tcx, b, ast::kind_shared, op + " rhs"); |
| 134 | +} |
| 135 | + |
| 136 | +fn check_expr(tcx: &ty::ctxt, e: &@ast::expr) { |
| 137 | + alt e.node { |
| 138 | + ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, "<-"); } |
| 139 | + ast::expr_assign(a, b) { need_shared_lhs_rhs(tcx, a, b, "="); } |
| 140 | + ast::expr_swap(a, b) { need_shared_lhs_rhs(tcx, a, b, "<->"); } |
| 141 | + _ { } |
| 142 | + } |
109 | 143 | }
|
110 | 144 |
|
111 | 145 | fn check_crate(tcx: &ty::ctxt, crate: &@ast::crate) {
|
|
0 commit comments