| A lifetime didn't match what was expected. |
| |
| Erroneous code example: |
| |
| ```compile_fail,E0623 |
| struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>) |
| where |
| T: Convert<'a, 'b>; |
| |
| trait Convert<'a, 'b>: Sized { |
| fn cast(&'a self) -> &'b Self; |
| } |
| impl<'long: 'short, 'short, T> Convert<'long, 'short> for T { |
| fn cast(&'long self) -> &'short T { |
| self |
| } |
| } |
| // error |
| fn badboi<'in_, 'out, T>( |
| x: Foo<'in_, 'out, T>, |
| sadness: &'in_ T |
| ) -> &'out T { |
| sadness.cast() |
| } |
| ``` |
| |
| In this example, we tried to set a value with an incompatible lifetime to |
| another one (`'in_` is unrelated to `'out`). We can solve this issue in |
| two different ways: |
| |
| Either we make `'in_` live at least as long as `'out`: |
| |
| ``` |
| struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>) |
| where |
| T: Convert<'a, 'b>; |
| |
| trait Convert<'a, 'b>: Sized { |
| fn cast(&'a self) -> &'b Self; |
| } |
| impl<'long: 'short, 'short, T> Convert<'long, 'short> for T { |
| fn cast(&'long self) -> &'short T { |
| self |
| } |
| } |
| fn badboi<'in_: 'out, 'out, T>( |
| x: Foo<'in_, 'out, T>, |
| sadness: &'in_ T |
| ) -> &'out T { |
| sadness.cast() |
| } |
| ``` |
| |
| Or we use only one lifetime: |
| |
| ``` |
| struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>) |
| where |
| T: Convert<'a, 'b>; |
| |
| trait Convert<'a, 'b>: Sized { |
| fn cast(&'a self) -> &'b Self; |
| } |
| impl<'long: 'short, 'short, T> Convert<'long, 'short> for T { |
| fn cast(&'long self) -> &'short T { |
| self |
| } |
| } |
| fn badboi<'out, T>(x: Foo<'out, 'out, T>, sadness: &'out T) -> &'out T { |
| sadness.cast() |
| } |
| ``` |