Question about Trait Object lifetime

Hi,

I am new to Rust. I have a question about trait object and its lifetime. Given that:

struct Parent {
   child: Box<dyn OtherTrait>,
}

My understanding is that Rust automatically treat the trait object as having a static lifetime. So it would be something like this:

struct Parent {
   child: Box<dyn OtherTrait + 'static>,
}

My question is does this means that the object assigned to child will live throughout the entire program and will never get freed?

Now given this:

struct Parent<'a> {
   child: Box<dyn OtherTrait +'a>,
}

Does this mean that the child now will live at least as long as the Parent, and will eventually get freed?

If my interpretation is correct, it seems odd that Rust chooses 'static as the default lifetime for trait objects.

Thanks.

Henry

Fortunately no. Lifetimes are boundaries and express relative dependencies between objects. So they might say "This (Parent in your case) can't outlive That (child)."

The fact that the contents of the box are 'static means that the Parent can live as long as it needs to. But Parent still has ownership of the box, so when it's dropped, Parent and everything it contains including the box and its contents will be dropped (and freed) also.

A non-static lifetime on the contents of the box means that the box's contents are bounded by something else, and by extension the box is bounded, and therefore Parent is also bounded. For example, if the box contained a reference to something outside. Or some other objects or structs that contain references, for example, Ref<>. Then Parent couldn't live longer than the thing it's referencing or you would have a dangling pointer.

Caveat: I'm relatively new to Rust myself and my understanding isn't as nuanced as some other folks on this forum. So apologies in advance if what I say isn't quite right.

5 Likes

Thanks for the reply. It makes more sense now.

So, am I correct to assume that static lifetime essentially means unbounded lifetime? Thus, when I require a parameter that has a static lifetime, that means I want an exclusive right to that parameter's lifetime?

Correct.

It means that nothing from the outside can shorten the time that object is valid. So a String type can have a 'static lifetime because all the memory it needs is internal to the String object. But an &str may have a non-static lifetime, because it's a pointer into a buffer somewhere.

(&str is a slightly confusing example because string leterals have 'static lifetimes because the buffer they're stored in is loaded with the program's code... but general &strs point into a buffer that may be owned by a String or something, somewhere, where it can be freed. Sorry about the bad example.)

2 Likes

Thanks again for the reply. I learn something new today.

One thing to realize is that lifetimes in Rust are never talking about the lifetime of a value, instead they are upper bounds on how long a value can live. If a type is annotated with a lifetime, then it must go out of scope before that lifetime ends, but there's no requirement that it lives for the entire lifetime.

2 Likes

Right. I had a different assumption earlier. I suppose the word "static" conjured up a different image in my mind.

The short way to express the meaning of T : 'a (such as in T = dyn ... + 'a), is that:

A type T meets the : 'a bound if any instance of type T can be held / owned arbitrarily long within that lifetime 'a.

This comes up in practice with the case 'a = 'static (the infinitely long lifetime):

See also: Why does this "impl + 'static" code compile?

1 Like