Async closures are not allowed to reference all captured lifetimes if one of them is invariant · Issue #123241 · rust-lang/rust (original) (raw)
async fn go<'a>(value: &'a i32) { let closure = async |scope: ScopeRef<'_, 'a>| { let _future1 = scope.spawn(async { let _v = *value; }); }; }
yields
error: lifetime may not live long enough
--> examples/repro.rs:52:63
|
52 | let closure = async |scope: ScopeRef<'_, 'a, i32>| -> i32 {
| ___________________-------------------------------------------_^
| | | |
| | | let's call the lifetime of this reference `'2`
| | lifetime `'1` represents this closure's body
53 | | let _future1 = scope.spawn(async { value });
54 | | 22
55 | | };
| |_____^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
= note: closure implements `Fn`, so references to captured variables can't escape the closure
= note: requirement occurs because of the type `Scope<'_, '_, i32>`, which makes the generic argument `'_` invariant
= note: the struct `Scope<'scope, 'env, R>` is invariant over the parameter `'scope`
closure was supposed to return data with lifetime
'2
('scope
) but it is returning data with lifetime'1
(closure body)
It's reasonable that we would create a lifetime representing the closure body, but naturally, the future should be allowed to reference it. The invariant lifetime must be mucking things up somehow.
(spawn
has no lifetime params so I would not expect there to be a new lifetime created when it is called.)
note: closure implements
Fn
, so references to captured variables can't escape the closure
The closure definitely shouldn't try to implement Fn
in this case, I don't know why it does.
note: requirement occurs because of the type
Scope<'_, '_, i32>
, which makes the generic argument'_
invariant
note: the structScope<'scope, 'env, R>
is invariant over the parameter'scope
It's correct that this lifetime is invariant. We must write to a vec of futures that outlive 'scope
, so any variance would be unsound.