Repository: rust
Issue: Better error message for E0310
Labels: A-diagnostics,A-lifetimes,T-compiler,D-papercut,D-newcomer-roadblock,A-trait-objects

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.

If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes
the problematic output to occur.
-->

Given the following code ([Playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9e9199cccd55eca356c1ffcfed010834)):

```rust
use std::fmt::Display;

fn foo<T: Display>(value: T) -> Box<dyn Display> {
    let result: Box<dyn Display> = Box::new(value);
    result
}
```

The current output is:

```
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> {
  |
```

<!-- The following is not always necessary. -->
Ideally the output should look like:

```
error[E0310]: if the parameter type `T` contains references, variables of this type 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 excluding types with non-static references by adding an explicit lifetime bound...
  |
3 | fn foo<T: Display + 'static>(value: T) -> Box<dyn Display> {
  |
```

## Rationale for the change:

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](https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html) 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.