I'm suggesting rephrasing the error message for E0310 in order to make it more accessible. Consider the following contrived example:
use std::fmt::Display;
fn foo<T: Display>(value: T) -> Box<dyn Display> {
let result: Box<dyn Display> = Box::new(value); // Error!
result
}
Compilation of this code fails with the following error:
error[E0310]: the parameter type `T` may not live long enough
--> src/lib.rs:4:36
|
4 | let result: Box<dyn Display> = Box::new(value);
| ^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
3 | fn foo<T: Display + 'static>(value: T) -> Box<dyn Display> {
| +++++++++
I'm fairly new to Rust. When I first encountered this errors, there were three things about this message I didn't understand:
Do types have a lifetime?
The error message states that "the parameter type T
may not live long enough". In non-generic code, Rust's error messages talk about the lifetimes of concrete variables, not the lifetimes of types. My understanding is that there is that types themselves always exist and that there is no such thing as the lifetime of a type, only the lifetime of a variable of that type. So I guess "the parameter type T
may not live long enough" is just shorthand for "variables of type T
may not live long enough". The latter would have made the error message clearer to me.
How can value
not live long enough?
The only variable of type T
is value
. This variable is passed by value, not by reference, and thus moved. I just couldn't think of a scenario where this variable might not live long enough.
The answer, as I now realize, is that T
may be a struct containing references, which in turn may have a limited lifetime. Given that this is the only problematic case, it would have helped me if the error message had explicitly mentioned it.
Must I really limit my function to arguments with static lifetime?
The error message suggests adding the explicit lifetime bound 'static
to T
. When I first came across this message, I didn't realize that "static" as a trait bound has a different meaning to "static" as a reference lifetime. I assumed that adding the trait bound 'static
to T
would allow only arguments with a static lifetime to be passed, making the function useless. This is not the case. It would have helped me if the suggestion had mentioned this in some way.
Suggestion
I realize that much of my initial confusion comes from the fact that I'm rather new to Rust. But given that everybody starts as a newbie, I thought the error message could be extended a bit to make it easier to understand. Maybe something like this?
if the parameter type
T
contains references, variables of this type may not live long enough
...so that typeT
will meet its required lifetime bounds
help: consider excluding types with non-static references by adding an explicit lifetime bound...