Error E0301 "the parameter type T may not live long enough" could explain where the lifetime requirement comes from

3e7777f
Opened by bluss at 2024-08-11 03:39:41

Error E0301 "the parameter type T may not live long enough" could explain where the lifetime requirement comes from.

Here's some example code where the T: 'static requirement comes implicitly from a Box<Trait> trait object (so 'static is invisible).

playground

trait Funny { }

fn new_funny_handle<T: Funny + Default>() -> Box<Funny> {
    Box::new(T::default())
}
error: the parameter type `T` may not live long enough [--explain E0310]
 --> <anon>:5:5
5 |>     Box::new(T::default())
  |>     ^^^^^^^^^^^^^^^^^^^^^^
help: consider adding an explicit lifetime bound `T: 'static`...
note: ...so that the type `T` will meet its required lifetime bounds
 --> <anon>:5:5
5 |>     Box::new(T::default())
  |>   
  1. cc @jonathandturner

    Alex Crichton at 2016-05-16 17:20:10

  2. Current output:

    
    error[E0310]: the parameter type `T` may not live long enough
     --> src/lib.rs:5:5
      |
    4 | fn new_funny_handle<T: Funny + Default>() -> Box<Funny> {
      |                     -- help: consider adding an explicit lifetime bound `T: 'static`...
    5 |     Box::new(T::default())
      |     ^^^^^^^^^^^^^^^^^^^^^^
      |
    note: ...so that the type `T` will meet its required lifetime bounds
     --> src/lib.rs:5:5
      |
    5 |     Box::new(T::default())
      |     ^^^^^^^^^^^^^^^^^^^^^^
    

    Esteban Kuber at 2019-09-21 22:18:32

  3. Current output:

    error[E0310]: the parameter type `T` may not live long enough
     --> src/lib.rs:4:5
      |
    4 |     Box::new(T::default())
      |     ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
      |
    help: consider adding an explicit lifetime bound...
      |
    3 | fn new_funny_handle<T: Funny + Default + 'static>() -> Box<dyn Funny> {
      |                                        +++++++++
    

    Esteban Kuber at 2023-08-03 19:13:20

  4. I found this one very confusing when I was first playing around with trait objects. I'd attempted something along the lines of:

    struct Hello<'a> {
        value: Box<dyn Any + 'a>,
    }
    
    impl<'a> Hello<'a> {
        fn new<T: 'a>(value: T) -> Self {
            Self { value: Box::new(value) }
        }
    }
    

    with the resulting error:

    error[E0310]: the parameter type `T` may not live long enough
      --> src/lib.rs:88:27
       |
    88 |             Self { value: Box::new(value) }
       |                           ^^^^^^^^^^^^^^^
       |                           |
       |                           the parameter type `T` must be valid for the static lifetime...
       |                           ...so that the type `T` will meet its required lifetime bounds
       |
    help: consider adding an explicit lifetime bound
       |
    87 |         fn new<T: 'a + 'static>(value: T) -> Self {
       |                      +++++++++
    

    which didn't help me understand at all why the bound was needed. Is it (1) Box<T> requiring T: 'static, (2) Any not being compatible with non-'static types, or (3) something inherent to trait objects themselves, requiring that the underlying type is 'static?

    Of course the answer is (2), in that Any is only implemented for 'static types, but not being familiar with this kind of bound at the time I was sent on a wild goose chase trying to read up on trait objects that could have been avoided if the compiler had just pointed me at the following line:

    pub trait Any: 'static {
    

    Arvid Fahlström Myrman at 2024-08-11 03:39:41