@@ -3,39 +3,70 @@ A lifetime didn't match what was expected.
3
3
Erroneous code example:
4
4
5
5
``` 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>;
9
9
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()
12
24
}
13
25
```
14
26
15
27
In 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
17
29
two different ways:
18
30
19
- Either we make ` 'short ` live at least as long as ` 'long ` :
31
+ Either we make ` 'in_ ` live at least as long as ` 'out ` :
20
32
21
33
```
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>;
25
37
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()
29
51
}
30
52
```
31
53
32
54
Or we use only one lifetime:
33
55
34
56
```
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
+ }
37
68
}
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()
40
71
}
41
72
```
0 commit comments