Declaring substructural lifetimes


#1

I have some code…

struct Foo<'a> {
    items: Vec<&'a u32>,
}

fn compiles() {
    let n = 123;
    let mut foo = Foo { items: vec![] };
    foo.items.push(&n);
}

fn does_not_compile() {
    let mut foo = Foo { items: vec![] };
    let n = 123;
    foo.items.push(&n);
}

fn main() {}

I know why does_not_compile doesn’t compile: the lifetime of n is shorter than the lifetime of foo, and foo.items can only contain values that live at least as long as foo does.

What I do not understand is how to declare my intent that members of foo.items should live for a shorter period of time than foo itself. It seems similar to the lifetime issues involved with Iterators, but I do not see how to translate those ideas to this situation.

How can I declare the type Foo so that does_not_compile becomes correct?


#2

Pretty sure you can’t. You’re asking how to allow parts of a value to become invalid while the value still exists; Rust very specifically does not let you do this.

I mean, if an element of items doesn’t live as long as items itself does, how does items know which elements are safe to index? How does it clean up after itself? Does it or does it not run drop code on elements?


#3

@DanielKeep ah I see, you’re right. I overcomplicated it and that kept me from understanding.

This code shows it simply:

fn compiles() {
    let n = 123;
    let mut v: Vec<&u32> = vec![];
    v.push(&n);
}

fn does_not_compile() {
    let mut v: Vec<&u32> = vec![];
    let n = 123;
    v.push(&n);
}

fn main() {}

Thanks!