Skip to content

Cannot await in scope that contains call to format! #64960

Description

@jonhoo

As part of #64477, it was identified that the following code no longer compiles (#64477 (comment)):

async fn foo(_: String) {
}

fn bar() -> impl Send {
    async move {
        foo(format!("{}:{}", 1, 2)).await;
    }
}

This is as a result of this issue, and @nikomatsakis goes into some more detail as to why the borrow checker rejects the code in #64477 (comment). Basically, the code ends up creating temporaries that refer to the arguments of format!, and those temporaries are dropped only at the end of the current scope, which is after .await. And so, those temporaries must live across a yield point, which in turn prevents the resulting generator from being Send with the error:

error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
 --> src/lib.rs:4:13
  |
4 | fn bar() -> impl Send {
  |             ^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
  |

This pattern (I have found at least) is quite common, and so having the code rejected is unfortunate given that in these cases ew only need the returned String before the yield point.

@Nemo157 proposed a fix in #64477 (comment), which is implemented in #64856, but it changes the drop order of the argument to format!, which may have unintended consequences. In #64856 (comment), @nikomatsakis suggested that we may be able to solve this with changes to the analysis, which prompted the opening of this issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions