Mike Lynch
Mike Lynch

Reputation: 451

How to put explicit lifetime bound on Self for associated constant?

I have a trait which I want to have an associated constant on, where the constant will be a slice of the type that implements the trait. Something like this:

trait A: Sized {
    const VALUES: &'static [Self];
}

#[derive(Debug)]
struct B {
    b: u8,
}

impl A for B {
    const VALUES: &'static [B] = &[B { b: 1 }];
}

#[derive(Debug)]
struct C {
    c: usize,
}

impl A for C {
    const VALUES: &'static [C] = &[C { c: 4 }];
}

fn main() {
    println!("{:?}", B::VALUES);
    println!("{:?}", C::VALUES);
}

This fails to compile with the error:

error[E0310]: the parameter type `Self` may not live long enough
 --> src/main.rs:2:5
  |
2 |     const VALUES: &'static [Self];
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = help: consider adding an explicit lifetime bound `Self: 'static`...
note: ...so that the reference type `&'static [Self]` does not outlive the data it points at

How is that lifetime bound expressed for an associated constant? If it's relevant, I'm using latest rustc stable (1.42.0), and the 2018 edition.

Upvotes: 2

Views: 454

Answers (1)

trent
trent

Reputation: 28005

In most cases, you probably want to simply add 'static to the supertrait bound on A:

trait A: Sized + 'static {
    const VALUES: &'static [Self];
}

You may instead put the Self: 'static bound only on VALUES:

trait A: Sized {
    const VALUES: &'static [Self] where Self: 'static;
}

This means that you can still implement A for non-'static types, but such types won't have a VALUES associated constant, so it's only practical to do so if the trait A has some other useful property independent of VALUES. (Also, in order to use T::VALUES in generic code, you have to bound T: A + 'static instead of merely T: A.)

Upvotes: 1

Related Questions