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

Reply via email to