Encoding complex lifetime invariants


#1

I have a struct that that stores strings:

struct StringStorage {
    strings: Vec<String>,
}

During the lifetime of StringStorage I would like to be able to hold references to the strs stored in the Strings and to be able to add new Strings. This is correct behaviour, as far as I can tell, because even though adding a String to the Vec might cause references to the Strings themselves to be invalidated, their contents should be stable.
Is there a way to do this with the lifetime system? I’d like to keep the actual references (as opposed to indices, for example), because it makes debug printing a lot easier – I get the actual string in the message instead of having to reference an additional structure and retrieve the string manually.


#2

There is no way to do this with references. I’d suggest using a Vec<Rc<String>> for your usecase.


#3

Is it possible to have aliasing Rcs? An Rc<str> that references just part of the string, but shares the same lifetime?


#4

I think you might be able to do this with the owning_ref crate. Take a look at the StringRef or RcRef types.


#5

That sounds like it, thanks!


#6

is tied together with amend and delete under mutate.

Assuming String content is stable it could be done with unsafe code. (Not recommended.) Likely would want to keep StringStorage internal private with the Vec wrapped in RefCell. add and access functions would take &self. access function code would work from pointer.


#7

You can make a wrapper struct with a Range/index and an Rc<str> inside and then impl Deref<Target=str> for it to make it look like a str slice semi transparently.