Skip to content

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

Closed
@jonhoo

Description

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.

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, 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