Consider this example code:
trait ExampleTrait{}
struct TraitContainer{
trait_object: Box<dyn ExampleTrait>
}
impl TraitContainer{
fn new<T: ExampleTrait>(trait_object: T) -> TraitContainer{
TraitContainer{
trait_object: Box::new(trait_object)
}
}
}
fn main() {
}
This code seems like it should be able to pass the borrow checker because any value that is passed into TraitContainer::new
will be moved into that function, and then into the returned struct, where it then waits until it is moved out or that struct is dropped — there are no references at all that may live longer than their referants. Yet, the borrow checker complains:
error[E0310]: the parameter type `T` may not live long enough
--> src/main.rs:11:27
|
9 | fn new<T: ExampleTrait>(trait_object: T) -> TraitContainer{
| -- help: consider adding an explicit lifetime bound...: `T: 'static +`
10 | TraitContainer{
11 | trait_object: Box::new(trait_object)
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> src/main.rs:11:27
|
11 | trait_object: Box::new(trait_object)
| ^^^^^^^^^^^^^^^^^^^^^^
This complaint (and associated explanation via rustc --explain
or the website) talks about lifetime parameters on a type though, which doesn't make any sense. Lifetime parameters refer to specific sections of memory, but types are a contract for how to use sections of memory. If a trait exists in the code, then it always exists — there is no way that a trait can stop existing during the runtime of a program, so why would it have a lifetime?