@@ -3,39 +3,70 @@ A lifetime didn't match what was expected.
33Erroneous code example:
44
55``` compile_fail,E0623
6- struct Foo<'a> {
7- x: &'a isize,
8- }
6+ struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>)
7+ where
8+ T: Convert<'a, 'b>;
99
10- fn bar<'short, 'long>(c: Foo<'short>, l: &'long isize) {
11- let _: Foo<'long> = c; // error!
10+ trait Convert<'a, 'b>: Sized {
11+ fn cast(&'a self) -> &'b Self;
12+ }
13+ impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
14+ fn cast(&'long self) -> &'short T {
15+ self
16+ }
17+ }
18+ // error
19+ fn badboi<'in_, 'out, T>(
20+ x: Foo<'in_, 'out, T>,
21+ sadness: &'in_ T
22+ ) -> &'out T {
23+ sadness.cast()
1224}
1325```
1426
1527In this example, we tried to set a value with an incompatible lifetime to
16- another one (` 'long ` is unrelated to ` 'short ` ). We can solve this issue in
28+ another one (` 'in_ ` is unrelated to ` 'out ` ). We can solve this issue in
1729two different ways:
1830
19- Either we make ` 'short ` live at least as long as ` 'long ` :
31+ Either we make ` 'in_ ` live at least as long as ` 'out ` :
2032
2133```
22- struct Foo<'a> {
23- x: &'a isize,
24- }
34+ struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>)
35+ where
36+ T: Convert<'a, 'b>;
2537
26- // we set 'short to live at least as long as 'long
27- fn bar<'short: 'long, 'long>(c: Foo<'short>, l: &'long isize) {
28- let _: Foo<'long> = c; // ok!
38+ trait Convert<'a, 'b>: Sized {
39+ fn cast(&'a self) -> &'b Self;
40+ }
41+ impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
42+ fn cast(&'long self) -> &'short T {
43+ self
44+ }
45+ }
46+ fn badboi<'in_: 'out, 'out, T>(
47+ x: Foo<'in_, 'out, T>,
48+ sadness: &'in_ T
49+ ) -> &'out T {
50+ sadness.cast()
2951}
3052```
3153
3254Or we use only one lifetime:
3355
3456```
35- struct Foo<'a> {
36- x: &'a isize,
57+ struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>)
58+ where
59+ T: Convert<'a, 'b>;
60+
61+ trait Convert<'a, 'b>: Sized {
62+ fn cast(&'a self) -> &'b Self;
63+ }
64+ impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
65+ fn cast(&'long self) -> &'short T {
66+ self
67+ }
3768}
38- fn bar<'short>(c : Foo<'short >, l : &'short isize) {
39- let _: Foo<'short> = c; // ok!
69+ fn badboi<'out, T>(x : Foo<'out, 'out, T >, sadness : &'out T) -> &'out T {
70+ sadness.cast()
4071}
4172```
0 commit comments