Reputation: 2095
I'm trying to get my head around the way that generics and lifetimes interact. Consider:
use std::ops::Add;
struct Gloop<'a, T: Add> {
wumpus: &'a Wumpus<T>,
}
trait Wumpus<T: Add> {
fn fleeb(&self, x: &T) -> bool;
}
struct Mimsy {
jubjub: f64,
}
impl<T: Add> Wumpus<T> for Mimsy {
fn fleeb(&self, x: &T) -> bool {
return (x + x) > 0;
}
}
fn main() {
let a = Mimsy { jubjub: 1. };
let b = Gloop::<i32> { wumpus: &a };
println!("{}", b.fleeb(1));
}
Which yields:
error[E0309]: the parameter type `T` may not live long enough
--> src/main.rs:4:5
|
3 | struct Gloop<'a, T: Add> {
| -- help: consider adding an explicit lifetime bound `T: 'a`...
4 | wumpus: &'a Wumpus<T>,
| ^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'a Wumpus<T> + 'a` does not outlive the data it points at
--> src/main.rs:4:5
|
4 | wumpus: &'a Wumpus<T>,
| ^^^^^^^^^^^^^^^^^^^^^
Which object in my program is the one which may not live long enough? Nowhere in either Gloop
or Mimsy
(or any Wumpus<T>
) is a T
ever stored.
Upvotes: 0
Views: 1192
Reputation: 431599
Note: I answered this, but think the question is actually a duplicate of
"The parameter type `C` may not live long enough", when it doesn't need to
This answer can be deleted if others agree.
Nowhere in either
Gloop
orMimsy
(or anyWumpus<T>
) is aT
ever stored.
Rust doesn't care about what you do, but what you could do. There are no signature differences between these two structs:
struct Alpha<T> {
a: T,
}
struct Beta<T> {
b: fn(&T),
}
Namely, you can't tell the difference between the two and Beta
could become Alpha
without noticeable external changes to a consumer. Once you have a generic type, you need to handle any possibility.
You can either add T: 'static
or add a lifetime and add T: 'a
.
See also:
Upvotes: 2