Skip to content

async/await regression regarding borrows across yields #65436

Closed
@valff

Description

@valff

The following code was working in nightly-2019-09-05, but no longer works in nightly-2019-10-15. The workaround is not quite intuitive.

struct Foo(*const u8);

unsafe impl Send for Foo {}

async fn bar(_: Foo) {}

fn assert_send<T: Send>(_: T) {}

fn main() {
    assert_send(async {
        // This works in nightly-2019-09-05, but no longer works in nightly-2019-10-15:
        bar(Foo(std::ptr::null())).await;
        // This way it does work in nightly-2019-10-15:
        //let foo = Foo(std::ptr::null());
        //bar(foo).await;
    })
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0277]: `*const u8` cannot be sent between threads safely
  --> src/main.rs:10:5
   |
7  | fn assert_send<T: Send>(_: T) {}
   |    -----------    ---- required by this bound in `assert_send`
...
10 |     assert_send(async {
   |     ^^^^^^^^^^^ `*const u8` cannot be sent between threads safely
   |
   = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*const u8`
   = note: required because it appears within the type `{fn(Foo) -> impl std::future::Future {bar}, fn(*const u8) -> Foo {Foo}, fn() -> *const u8 {std::ptr::null::<u8>}, *const u8, Foo, impl std::future::Future, impl std::future::Future, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:10:23: 16:6 {fn(Foo) -> impl std::future::Future {bar}, fn(*const u8) -> Foo {Foo}, fn() -> *const u8 {std::ptr::null::<u8>}, *const u8, Foo, impl std::future::Future, impl std::future::Future, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:10:23: 16:6 {fn(Foo) -> impl std::future::Future {bar}, fn(*const u8) -> Foo {Foo}, fn() -> *const u8 {std::ptr::null::<u8>}, *const u8, Foo, impl std::future::Future, impl std::future::Future, ()}]>`
   = note: required because it appears within the type `impl std::future::Future`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Metadata

Metadata

Assignees

Labels

A-async-awaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.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