|
30 | 30 | * you write fn<@T>(...). And if you need neither -- can work with any sort of
|
31 | 31 | * pinned data at all -- then you write fn<T>(...).
|
32 | 32 | *
|
33 |
| -* |
34 | 33 | * Most types are unique or shared. Other possible name combinations for these
|
35 | 34 | * two: (tree, graph; pruned, pooled; message, local; owned, common) are
|
36 | 35 | * plausible but nothing stands out as completely pithy-and-obvious.
|
37 | 36 | *
|
38 |
| -* Resources cannot be copied or sent; they're pinned. They can't be copied |
39 |
| -* because it would interfere with destruction (multiple destruction?) They |
40 |
| -* cannot be sent because we don't want to oblige the communication system to |
41 |
| -* run destructors in some weird limbo context of messages-in-transit. It |
42 |
| -* should always be ok to just free messages it's dropping. |
| 37 | +* Pinned values arise in 2 contexts: resources and &-closures (blocks). The |
| 38 | +* latter absolutely must not be moved, since they could escape to the heap; |
| 39 | +* the former must not be copied, since they'd then be multiply-destructed. |
| 40 | +* We achieve the no-copy restriction by recycling the no-move restriction |
| 41 | +* in place on pinned kinds for &-closures; and as a benefit we can guarantee |
| 42 | +* that a resource passed by reference to C will never move during its life, |
| 43 | +* occasionally useful for FFI-code. |
| 44 | +* |
| 45 | +* Resources cannot be sent because we don't want to oblige the communication |
| 46 | +* system to run destructors in some weird limbo context of |
| 47 | +* messages-in-transit. It should always be ok to just free messages it's |
| 48 | +* dropping. Even if you wanted to send them, you'd need a new sigil for the |
| 49 | +* NOMOVE + SEND combination, and you couldn't use the move-mode library |
| 50 | +* interface to chan.send in that case (NOMOVE after all), so the whole thing |
| 51 | +* wouldn't really work as minimally as the encoding we have here. |
43 | 52 | *
|
44 | 53 | * Note that obj~ and fn~ -- those that capture a unique environment -- can be
|
45 |
| -* sent, so satisfy ~T. So can plain obj and fn. |
46 |
| -* |
| 54 | +* sent, so satisfy ~T. So can plain obj and fn. They can all also be copied. |
47 | 55 | *
|
48 | 56 | * Further notes on copying and moving; sending is accomplished by calling a
|
49 | 57 | * move-in operator on something constrained to a unique type ~T.
|
|
53 | 61 | * --------
|
54 | 62 | *
|
55 | 63 | * A copy is made any time you pass-by-value or execute the = operator in a
|
56 |
| -* non-init expression. |
| 64 | +* non-init expression. Copying requires discriminating on type constructor. |
| 65 | +* |
| 66 | +* @-boxes copy shallow, copying is always legal. |
| 67 | +* |
| 68 | +* ~-boxes copy deep, copying is only legal if pointee is unique-kind. |
57 | 69 | *
|
58 |
| -* @ copies shallow, is always legal |
59 |
| -* ~ copies deep, is only legal if pointee is unique. |
60 |
| -* pinned values (pinned resources, alias-closures) can't be copied |
61 |
| -* all other unique (eg. interior) values copy shallow |
| 70 | +* Pinned-kind values (resources, &-closures) can't be copied. All other |
| 71 | +* unique-kind (eg. interior) values can be copied, and copy shallow. |
| 72 | +* |
| 73 | +* Note: If you have no type constructor -- only an opaque typaram -- then |
| 74 | +* you can only copy if the typaram is constrained to ~T; this is because @T |
| 75 | +* might be a "~resource" box, and making a copy would cause a deep |
| 76 | +* resource-copy. |
62 | 77 | *
|
63 |
| -* Note this means that only type parameters constrained to ~T can be copied. |
64 | 78 | *
|
65 | 79 | * MOVING:
|
66 | 80 | * -------
|
67 | 81 | *
|
68 |
| -* A move is made any time you pass-by-move (that is, with 'move' mode) or |
69 |
| -* execute the <- operator. |
| 82 | +* A move is made any time you pass-by-move (that is, with move mode '-') or |
| 83 | +* execute the move ('<-') or swap ('<->') operators. |
70 | 84 | *
|
71 | 85 | */
|
72 | 86 |
|
@@ -124,6 +138,12 @@ fn need_shared_lhs_rhs(tcx: ty::ctxt, a: @ast::expr, b: @ast::expr, op: str) {
|
124 | 138 |
|
125 | 139 | fn check_expr(tcx: ty::ctxt, e: @ast::expr) {
|
126 | 140 | alt e.node {
|
| 141 | + |
| 142 | + // FIXME: These rules do not implement the copy type-constructor |
| 143 | + // discrimination described by the block comment at the top of |
| 144 | + // this file. This code is wrong; it lets you copy anything |
| 145 | + // shared-kind. |
| 146 | + |
127 | 147 | ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, "<-"); }
|
128 | 148 | ast::expr_assign(a, b) { need_shared_lhs_rhs(tcx, a, b, "="); }
|
129 | 149 | ast::expr_assign_op(_, a, b) { need_shared_lhs_rhs(tcx, a, b, "op="); }
|
|
0 commit comments