Reputation: 451
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
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