Struct containing reference to own field


#1

Hi, I’ve come accross a small problem. I need a boxed struct that contains an array and a tree that contains references into this array. My intuition is that there shouldn’t be any problem with lifetimes here, but I can’t get it to work. I have simplified it to this: http://is.gd/pQQ4Nh

Why is a lifetime of &res.value only in the block suffix followint res assignment? Shouldn’t it be the same as lifetime of the box?


#2

(It’s a flyweight pattern. The array contains the shared heavy parts (less than 100) and the tree has only references to save space (thousands))


#3

Unfortunately you can’t do this as is; see the following questions:


There’s a problem with destruction order where the array could be destroyed before the references to elements of the array, in case your struct implemented Drop. Thus Rust cannot guarantee memory safety.

A first, easy alternative would be to use shared pointers std::rc::Rc to implement safely your flyweight pattern. The only drawback is runtime overhead. I wouldn’t mind finding another more complicated, possibly unsafe pattern, unless profiling explicitly blames the shared pointer design as a source of slowness.

Alternatively, you could replace references by indices to refer to elements in the array. Not very idiomatic Rust, but could be made to work easily. Drawbacks are: can panic if invalid index; runtime overhead of bounds checking (if you disable bound checking, this drawback morphs into “memory safety no longer guaranteed”).

I would go with Rc if possible.


How to create struct with references to it's own items
#4

It’s not super unidiomatic, it certainly is used in places. Also, bounds checking is almost never a concern. Especially not in cases where you would use optional reference, something like Option<&T> – the is-valid-index check becomes the equivalent of is-not-none.


#5

Thank you, I will probably go with Rc for now. Might be interesting to measure performance difference between this, regular aray indices (it should make my flyweights smaller, but complicate alignment and add one indirection) and unchecked array indices … oh well, another item on the todo list :slight_smile: