I\'m having issues understanding the lifetime bound requirements when I use a trait in a type definition. For instance:
trait Kind { /* ... */ }
type Collect
You really have two orthogonal cases . I'll tackle the easier one first, the difference of #2 and #3. Comments are inline with what I hope is a representative example:
trait Kind {
fn trait_fn(&self) -> u8 { 0 }
}
type CollectionOfKind1<'a> = Vec<&'a (dyn Kind + 'static)>;
type CollectionOfKind2<'a> = Vec<&'a (dyn Kind + 'a)>;
struct Alpha;
impl Kind for Alpha {}
struct Beta<'b> {
name: &'b str,
}
impl<'a> Kind for Beta<'a> {}
fn main() {
let name = "world".to_string();
// Doesn't need/have it's own lifetime.
let a = Alpha;
// Has a reference to something with the 'static lifetime.
let b1 = Beta { name: "hello" };
// Has a reference to something with the lifetime of `name`,
// which is less than 'static.
let b2 = Beta { name: &name[..] };
// Our vector is composed of references to
// things that *might* have a reference themselves!
let mut c1: CollectionOfKind1 = Vec::new();
c1.push(&a);
c1.push(&b1);
// c1.push(&b2); // error: `name` does not live long enough
let mut c2: CollectionOfKind2 = Vec::new();
c2.push(&a);
c2.push(&b1);
c2.push(&b2); // Hooray
}
Of note here is that the lifetimes don't have to be the same! You could have written:
type CollectionOfKind2<'a, 'b> = Vec<&'a (dyn Kind + 'b)>;
The second thing is the meaning of trait Foo : 'static
. I'm less sure here, but I wrote this small example:
trait Foo : 'static {}
fn x(a: &Foo) {}
fn main() {
x(&3u8);
}
This errors during compilation with
the trait
Foo
must be implemented for the cast to the object typeFoo + 'static
Based on that, I think that Foo : 'static
is just another way of writing Foo + 'static
. The main difference I can think of is that it restricts the trait from ever being implemented on a struct with non-'static
lifetimes:
struct B<'a> {
b: &'a str,
}
impl<'a> Foo for B<'a> {}
Has the error
declared lifetime bound not satisfied [...] but lifetime parameter must outlive the static lifetime
I see you've found this out already, but you may want to update your version of Rust. If I compile your code on the Playpen, I get a suggestion on how to fix it:
error: expected a path on the left-hand side of `+`, not `&'a Kind` [E0178]
type CollectionOfKind<'a> = Vec<&'a Kind + 'a>;
^~~~~~~~
note: perhaps you meant `&'a (Kind + 'a)`? (per RFC 438)
type CollectionOfKind<'a> = Vec<&'a Kind + 'a>;
^~~~~~~~
That references RFC 438, Precedence of Plus.