Incorrect error about lifetimes with Send bound on AsyncFnMut::CallRefFuture
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
This program builds fine (playground):
/// Provides zero to an async function.
fn provide_zero<'a, F>(f: &'a mut F) -> impl Future<Output = ()> + 'a
where
F: AsyncFnMut(i32),
{
async { f(0).await }
}
/// Builds a vector containing zero in a really silly way.
async fn foo() -> Vec<i32> {
let mut v = Vec::new();
provide_zero(&mut async |n| v.push(n)).await;
v
}
However, if you change provide_zero to require that the closure it accepts returns a future that can be polled in a multi-threaded environment, it stops compiling, with an incorrect error about v not living long enough in foo (playground):
fn provide_zero<'a, F>(f: &'a mut F) -> impl Future<Output = ()> + 'a
where
F: AsyncFnMut(i32),
for<'b> F::CallRefFuture<'b>: Send,
{
async { f(0).await }
}
Compiling playground v0.0.1 (/playground)
error[E0597]: `v` does not live long enough
--> src/lib.rs:18:23
|
18 | provide_zero(&mut async |n| v.push(n)).await;
| ------------------^^^^^^^^^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `v` is borrowed for `'static`
19 | v
20 | }
| - `v` dropped here while still borrowed
|
note: due to a current limitation of the type system, this implies a `'static` lifetime
--> src/lib.rs:10:5
|
10 | for<'b> F::CallRefFuture<'b>: Send,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
From the note it seems clear this is a consequence of some known issue. But what known issue? What are the prospects for resolving it? (Googling the note only turns up #150081, which doesn't really tell me the answer.)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing both nightly examples in the linked Rust Playground, comparing the versions of provide_zero and the AsyncFnMut::CallRefFuture Send bound. Trace the compiler limitation described in the diagnostic and determine which known issue it relates to; done means documenting the cause and realistic prospects for resolution.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100