Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does it mean when we let a trait inherits 'static?

Rust supports trait inheritance, as follows:

pub trait A {}
pub trait B: A {}

B: A means that if some type T implements B, it also needs to implement all the methods in A.

But today I see the following code:

trait Display: 'static {
    fn print(&self);
}

What does it mean? It doesn't seem to be trait inheritance.

like image 522
Searene Avatar asked Dec 23 '22 15:12

Searene


1 Answers

Rust supports trait inheritance, as follows [...] B: A means that if some type T implements B, it also needs to implement all the methods in A.

Technically, that is not inheritance but requirement. It is a trait bound not entirely dissimilar to one you'd have in a function: it constraints the type on which B is implementable to only types on which A is already implemented.

With that change in wording, the second version is much easier to understand: it's a lifetime bound, meaning it constraints the type on which B is implementable to only types with 'static lifetime, meaning if you're trying to implement B on a type, that must either have no lifetime at all, or have a 'static lifetime (or the implementation must have a lifetime bound aka only work for some uses of the type).

You can see that if you try to implement the trait on a lifetime-generic structure:

struct A<'a>(&'a str);
trait Display: 'static {
    fn print(&self);
}

impl <'a>Display for A<'a> {
    fn print(&self) { todo!() }
}

will yield

error[E0478]: lifetime bound not satisfied

That is because 'a can be anything, so implementing Display for A<'a> means it is also implemented for non-'static instances, which is not valid.

By adding the relevant lifetime bound on the impl, and thus limiting the implementation to A<'static> instances:

struct A<'a>(&'a str);
trait Display: 'static {
    fn print(&self);
}

impl <'a: 'static>Display for A<'a> {
    fn print(&self) { todo!() }
}

the requirements of the trait are satisfied, and the impl is valid (nb: the 'a is not necessary here you can just impl ... for A<'static>, I'm showing it for regularity).

And if your struct has no lifetime it works by default, because no lifetime ~ 'static:

struct A(String);
trait Display: 'static {
    fn print(&self);
}

impl Display for A {
    fn print(&self) { todo!() }
}
like image 112
Masklinn Avatar answered Dec 26 '22 00:12

Masklinn