From 93f0e9bac36b3487a2359a939a84bd9b35df8660 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Sun, 25 Sep 2011 12:42:39 -0700 Subject: [PATCH] Refine notes in kind.rs some more. Add a fixme to ty.rs. Kinds are still pretty wobbly. See thread starting at https://mail.mozilla.org/pipermail/rust-dev/2011-September/000807.html --- src/comp/middle/kind.rs | 52 ++++++++++++++++++++++++++++------------- src/comp/middle/ty.rs | 5 ++++ 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/comp/middle/kind.rs b/src/comp/middle/kind.rs index 4e7ed2fd959..3d37b302f3c 100644 --- a/src/comp/middle/kind.rs +++ b/src/comp/middle/kind.rs @@ -30,20 +30,28 @@ * you write fn<@T>(...). And if you need neither -- can work with any sort of * pinned data at all -- then you write fn(...). * -* * Most types are unique or shared. Other possible name combinations for these * two: (tree, graph; pruned, pooled; message, local; owned, common) are * plausible but nothing stands out as completely pithy-and-obvious. * -* Resources cannot be copied or sent; they're pinned. They can't be copied -* because it would interfere with destruction (multiple destruction?) They -* cannot be sent because we don't want to oblige the communication system to -* run destructors in some weird limbo context of messages-in-transit. It -* should always be ok to just free messages it's dropping. +* Pinned values arise in 2 contexts: resources and &-closures (blocks). The +* latter absolutely must not be moved, since they could escape to the heap; +* the former must not be copied, since they'd then be multiply-destructed. +* We achieve the no-copy restriction by recycling the no-move restriction +* in place on pinned kinds for &-closures; and as a benefit we can guarantee +* that a resource passed by reference to C will never move during its life, +* occasionally useful for FFI-code. +* +* Resources cannot be sent because we don't want to oblige the communication +* system to run destructors in some weird limbo context of +* messages-in-transit. It should always be ok to just free messages it's +* dropping. Even if you wanted to send them, you'd need a new sigil for the +* NOMOVE + SEND combination, and you couldn't use the move-mode library +* interface to chan.send in that case (NOMOVE after all), so the whole thing +* wouldn't really work as minimally as the encoding we have here. * * Note that obj~ and fn~ -- those that capture a unique environment -- can be -* sent, so satisfy ~T. So can plain obj and fn. -* +* sent, so satisfy ~T. So can plain obj and fn. They can all also be copied. * * Further notes on copying and moving; sending is accomplished by calling a * move-in operator on something constrained to a unique type ~T. @@ -53,20 +61,26 @@ * -------- * * A copy is made any time you pass-by-value or execute the = operator in a -* non-init expression. +* non-init expression. Copying requires discriminating on type constructor. * -* @ copies shallow, is always legal -* ~ copies deep, is only legal if pointee is unique. -* pinned values (pinned resources, alias-closures) can't be copied -* all other unique (eg. interior) values copy shallow +* @-boxes copy shallow, copying is always legal. +* +* ~-boxes copy deep, copying is only legal if pointee is unique-kind. +* +* Pinned-kind values (resources, &-closures) can't be copied. All other +* unique-kind (eg. interior) values can be copied, and copy shallow. +* +* Note: If you have no type constructor -- only an opaque typaram -- then +* you can only copy if the typaram is constrained to ~T; this is because @T +* might be a "~resource" box, and making a copy would cause a deep +* resource-copy. * -* Note this means that only type parameters constrained to ~T can be copied. * * MOVING: * ------- * -* A move is made any time you pass-by-move (that is, with 'move' mode) or -* execute the <- operator. +* A move is made any time you pass-by-move (that is, with move mode '-') or +* execute the move ('<-') or swap ('<->') operators. * */ @@ -124,6 +138,12 @@ fn need_shared_lhs_rhs(tcx: ty::ctxt, a: @ast::expr, b: @ast::expr, op: str) { fn check_expr(tcx: ty::ctxt, e: @ast::expr) { alt e.node { + + // FIXME: These rules do not implement the copy type-constructor + // discrimination described by the block comment at the top of + // this file. This code is wrong; it lets you copy anything + // shared-kind. + ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, "<-"); } ast::expr_assign(a, b) { need_shared_lhs_rhs(tcx, a, b, "="); } ast::expr_assign_op(_, a, b) { need_shared_lhs_rhs(tcx, a, b, "op="); } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 1f3b58c00ce..c274191aff4 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1026,6 +1026,11 @@ fn type_kind(cx: ctxt, ty: t) -> ast::kind { result = kind::lower_kind(result, k); } // Unique containers pass through their pointee kind. + // + // FIXME: These rules do not implement the ~ rules given in + // the block comment describing the kind system in kind.rs. + // This code is wrong; it makes ~resource into ~-kind, not + // @-kind as it should be. ty_vec(tm) | ty_uniq(tm) { let k = type_kind(cx, tm.ty); result = kind::lower_kind(result, k);