This is a good summary of the situation. There's one more twist to it though; I not only want both ownership and aliasing, I also want send-ability. That is, it should be possible to send the whole arena to another task.
I think this rules out option 1 (though I don't know enough about lifetimes to be sure). It leaves option 2 on the table, though. The main problem with option 2 is that if one borrows a mutable pointer to `root.poolOfSomeObjects[someIndex]` then the whole `root` is now considered to be borrowed-as-mutable, disallowing borrowing a mutable pointer to `root.poolOfOtherObjects[otherIndex]`. I'm tempted to say that the type system "should" be smart enough to allow this, but I'm not 100% certain it is actually safe to do so without some run-time support. For now I am going with (3) which is using an UnsafePtr struct and scary comments :-( On Fri, Oct 25, 2013 at 7:05 PM, Niko Matsakis <[email protected]> wrote: > On Mon, Sep 30, 2013 at 08:10:45PM +0300, Oren Ben-Kiki wrote: > > That's good! But there remains the fact that there's no way to say "my > > lifetime is the same as the struct that contains me". If 'self > specialness > > goes away, perhaps it can be re-introduced to mean that (or a different > > name can be given to it). > > So, I have had this thread on a "must read" list of e-mails for a while, > but didn't get around to it until just now. Sorry about that. > > It is true that there is no way to have a lifetime that means "as long > as the current struct" -- at least not in a type definition. The > reason for this is that this is not a well-defined thing; structs can > be moved, for example. The only place you can get a lifetime like that > is in a method: > > fn foo<'a>(&'a mut self, ...) > > Here, 'a is the lifetime you are looking for (the current lifetime of > the struct itself). > > We do have a way to express the notion of memory that moves with a > struct and is freed when the struct is freed: ownership. That's what a > `~` pointer is for. But of course the `~` pointer is designed for > recursive ownership and transfers and thus prevents aliasing, which > may not be what you need. > > Sometimes you want ownership and aliasability: basically you want to > be able to create a subcomponent tied to a struct that will never > itself be "moved out" of the struct into some other container. You can > imagine doing this by having an arena that moves with the struct, and > pointers that live as long as that arena. I had originally hoped to > support this (that was indeed the origin of the 'self name) but it's > quite complex to do so; that lifetime is a kind of "existential" > lifetime and we don't really have a good way to capture it. > > In the meantime, you have two options: > > 1. Parameterize the struct with a lifetime, and have it contain the > arena that way. This technique works when there is ultimately some > master stack frame that the struct will not outlive; this master > frame owns the arena, and the struct just borrows it. You can see > an example in this (yet to be landed) code. [1] > > 2. Have the struct own a vector or other data structure, and replace > pointers with indices. This works best when the struct will be > moved around. You can see an example in this Graph data > structure. [2] > > While I know that neither technique feels perfect, they are quite > workable, and I have used both with much rejoicing. > > > > Niko > > [1] https://gist.github.com/nikomatsakis/7157110 > [2] > https://github.com/mozilla/rust/blob/master/src/librustc/middle/graph.rs >
_______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
