On 24/09/2011 5:36 PM, Brian Anderson wrote:

Hi Graydon. Sorry for pulling you out of your vacation on day one! Sadly
I don't understand kinds.

No problem. Still kinda on semi-vacation; haven't left yet, still doing chores and prep.

My motivation for lowering uniques kinds containing pinned kinds to
pinned was an intuition that shared kinds are copyable, but on further
review of the comments in kind.rs, copyability doesn't seem to be a
direct property of a type's kind.

Yeah. Copy is the complicated one that I think has to discriminate by constructor. Because it has a deep/shallow question to answer. That doesn't occur with move or swap, thankfully.

I realize that "~resource" doesn't "look shared" in an intuitive
sense, but it's a bit of a corner case and I think it's the right
rule; other rules involve having move/swap/copy discriminate by type
constructor first ("is this a box? if so, look at content-kind, else
look at total-kind") which feels clunkier.

I think that according to guidance in kind.rs that copy rules do have to
discriminate by type constructor:

* A copy is made any time you pass-by-value or execute the = operator in a
* non-init expression.
*
* @ 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
*
* Note this means that only type parameters constrained to ~T can be
copied.

Sigh. Looks like that comment is a bit unclear still (also unclear whether it means ~ boxes or ~ kinds). Actually the whole comment block seems like it needs a bit of improvement. Sorry :(

I'll revise and expand the comment-block momentarily. This is important stuff to get right (also sadly requires revising a ton of library code when you perturb it). I notice a lot lot lot of our libraries assume that you can copy @-kind typarams. This is wrong; the kind checker gets it wrong (see next paragraph in reply).

So, the ability to copy a unique box is based on the kind in the box,
regardless of the unique box's kind. A unique box of resource (shared
kind) is not copyable; a unique box of int (unique kind) is copyable.

Yes. I notice that the rules in the kind checker don't actually do this discrimination; shame on me, sorry. They permit copying anything shared-kind. That's too loose; permits copying ~resource deeply. Dammit.

ty::type_kind calculates the kind of ~resource incorrectly too. Yuck all around. This is not going to be fun to fix. Might require algorithmic changes to much of the code in std::vec to avoid copies it thinks it can get away with.

The comments in kind.rs frame the kind system in terms of move and send.
I have a hard time understanding the role that send plays here, since
send is not a concept in the rust language. There is a definition of
send as 'sending is accomplished by calling a move-in operator on
something constrained to a unique type ~T' (and I assume this should
read 'unique kind ~T'). This seems sort of tautological as send is used
in defining what a unique kind is.

"Send" is a concept *expressed by* the kind system. IOW it's not that the kind system is defined solely in terms of "some other operator"; the kind system exists in order to *encode* a few concepts that are not otherwise linguistically encoded: no-send and no-move. Despite the fact that no "language level" constructs correspond to these motivations, there are *very real* pragmatic safety considerations requiring us to prohibit those in 2 cases:

  - no-send is required to prohibit data racing between tasks; tasks
    don't exist at a language level but they very much do exist in
    the runtime and in the minds of every user looking at the language.

  - no-move is required to prohibit &-closures (blocks) from
    escaping to the heap, thus pointing to dead stack frames.

Copying seems to be a big concern here and I feel like the kind system
would be easier to grasp if it were defined in terms of move and copy
instead of move and send.

I tried this; it really doesn't work since we're trying to encode something that is orthogonal to copy-ability. Copy-ability is a subset of move-ability but neither adequately encodes send-ability.

I also don't understand why resources can't be moved, and to me it seems
like the key property of pinned things is that they can't be copied.

Because &-closures are pinned and they must not escape to the heap.

Also, as a minor (but potentially very important) corner case, often when you interface with C you need stable pointers to a value you reuse. Being sure that a resource hasn't moved to a new address is helpful in these cases.

Finally, argument from minimality: you can prohibit copy by prohibiting move -- which you have to do anyways for &-closures -- and your kind system winds up with fewer moving parts if you only have 2 bits.

I realize all this is quite subtle, and apologize for that. I did a lot of napkin-drawing and hair-tearing-out to get it reduced to the size that it is there while still covering (I think) all the important parts. Apparently I didn't actually get the notes expressed properly in code. This makes me feel awful as I'm not sure it will hold together after all. I apologize. Please give the rules as-described in the comment a try before giving up.

If you need to revise it, be really really careful, make lots of notes, try to make sure you enumerate all important cases.

-Graydon
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to