Skip to content

Variables not always moved into async move block #78633

@Ploppz

Description

@Ploppz

Playground:

use std::cell::UnsafeCell;
use std::sync::{Arc, Mutex};

#[tokio::main]
async fn main() {
    let arena = 0;
    let mut track = Vec::new();
    async move { track.push(&arena) }.await;
}

rustc v1.47.0 stable

Error:

error[E0597]: `arena` does not live long enough
 --> src/main.rs:8:29
  |
7 |     let mut track = Vec::new();
  |         --------- lifetime `'1` appears in the type of `track`
8 |     async move { track.push(&arena) }.await;
  |                  -----------^^^^^^- - `arena` dropped here while still borrowed
  |                  |          |
  |                  |          borrowed value does not live long enough
  |                  argument requires that `arena` is borrowed for `'1`

error: aborting due to previous error; 2 warnings emitted

Which is because track is captured by reference and not by value, while arena is captured by value.

By submitting this issue, I assume that the intended semantics for move is:

move value(s) into the closure/block, even if the closure/block only seems to need to store reference(s)

which would make this a bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-borrow-checkerArea: The borrow checkerA-closuresArea: Closures (`|…| { … }`)AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions