| 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() | |
| } | |
| ``` |