1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
pub trait Get<T> {
fn get(self) -> T;
}
struct Foo {
x: usize,
}
impl Get<usize> for Foo {
fn get(self) -> usize {
self.x
}
}
fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
where
G: Get<T>,
{
move || {
//~^ ERROR hidden type for `impl FnOnce()` captures lifetime
*dest = g.get();
}
}
// After applying suggestion for `foo`:
fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
where
G: Get<T>,
{
move || {
//~^ ERROR the parameter type `G` may not live long enough
*dest = g.get();
}
}
// After applying suggestion for `bar`:
fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
//~^ ERROR undeclared lifetime name `'a`
where
G: Get<T>,
{
move || {
*dest = g.get();
}
}
// After applying suggestion for `baz`:
fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
where
G: Get<T>,
{
move || {
//~^ ERROR the parameter type `G` may not live long enough
*dest = g.get();
}
}
// Same as above, but show that we pay attention to lifetime names from parent item
impl<'a> Foo {
fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
move || {
//~^ ERROR the parameter type `G` may not live long enough
*dest = g.get();
}
}
}
// After applying suggestion for `qux`:
fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
where
G: Get<T>,
{
move || {
//~^ ERROR the parameter type `G` may not live long enough
//~| ERROR explicit lifetime required
*dest = g.get();
}
}
// Potential incorrect attempt:
fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
where
G: Get<T>,
{
move || {
//~^ ERROR the parameter type `G` may not live long enough
*dest = g.get();
}
}
// We need to tie the lifetime of `G` with the lifetime of `&mut T` and the returned closure:
fn ok<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
where
G: Get<T>,
{
move || {
*dest = g.get();
}
}
// This also works. The `'_` isn't necessary but it's where we arrive to following the suggestions:
fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
where
G: Get<T>,
{
move || {
*dest = g.get();
}
}
fn main() {}
|