Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async function using non-across-yield non-Send value is Send only if the usage is inside curly brackets #61950

Closed
tirr-c opened this issue Jun 19, 2019 · 2 comments
Labels
A-async-await Area: Async & Await

Comments

@tirr-c
Copy link
Contributor

tirr-c commented Jun 19, 2019

The title might be confusing, but here is my test code:

#![feature(async_await)]
use std::sync::{Arc, Mutex};

async fn div2(x: usize) -> usize {
    x / 2
}

async fn foo_pass(m: Arc<Mutex<usize>>) -> usize {
    let y = {
        let x = m.lock().unwrap(); // x: !Send
        *x + 1
    }; // x is dropped here
    div2(y).await
}

async fn foo_fail(m: Arc<Mutex<usize>>) -> usize {
    let x = m.lock().unwrap(); // x: !Send
    let y = *x + 1;
    drop(x); // x is dropped here (maybe)
    div2(y).await
}

struct CheckSend<T: Send>(T);

pub fn pass() {
    let m = Arc::new(Mutex::new(5));
    let _ = CheckSend(foo_pass(m.clone()));
}

pub fn fail() {
    let m = Arc::new(Mutex::new(5));
    let _ = CheckSend(foo_fail(m.clone()));
}

Playground

error[E0277]: `std::sync::MutexGuard<'_, usize>` cannot be sent between threads safely
  --> src/lib.rs:32:13
   |
32 |     let _ = CheckSend(foo_fail(m.clone()));
   |             ^^^^^^^^^ `std::sync::MutexGuard<'_, usize>` cannot be sent between threads safely
   |
   = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, usize>`
   = note: required because it appears within the type `for<'r> {std::sync::Arc<std::sync::Mutex<usize>>, std::sync::MutexGuard<'r, usize>, usize, impl std::future::Future, ()}`
   = note: required because it appears within the type `[static generator@src/lib.rs:16:50: 21:2 m:std::sync::Arc<std::sync::Mutex<usize>> for<'r> {std::sync::Arc<std::sync::Mutex<usize>>, std::sync::MutexGuard<'r, usize>, usize, impl std::future::Future, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/lib.rs:16:50: 21:2 m:std::sync::Arc<std::sync::Mutex<usize>> for<'r> {std::sync::Arc<std::sync::Mutex<usize>>, std::sync::MutexGuard<'r, usize>, usize, impl std::future::Future, ()}]>`
   = note: required because it appears within the type `impl std::future::Future`
   = note: required because it appears within the type `impl std::future::Future`
note: required by `CheckSend`
  --> src/lib.rs:23:1
   |
23 | struct CheckSend<T: Send>(T);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: `std::sync::MutexGuard<'_, usize>` cannot be sent between threads safely
  --> src/lib.rs:32:13
   |
32 |     let _ = CheckSend(foo_fail(m.clone()));
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::sync::MutexGuard<'_, usize>` cannot be sent between threads safely
   |
   = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, usize>`
   = note: required because it appears within the type `for<'r> {std::sync::Arc<std::sync::Mutex<usize>>, std::sync::MutexGuard<'r, usize>, usize, impl std::future::Future, ()}`
   = note: required because it appears within the type `[static generator@src/lib.rs:16:50: 21:2 m:std::sync::Arc<std::sync::Mutex<usize>> for<'r> {std::sync::Arc<std::sync::Mutex<usize>>, std::sync::MutexGuard<'r, usize>, usize, impl std::future::Future, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/lib.rs:16:50: 21:2 m:std::sync::Arc<std::sync::Mutex<usize>> for<'r> {std::sync::Arc<std::sync::Mutex<usize>>, std::sync::MutexGuard<'r, usize>, usize, impl std::future::Future, ()}]>`
   = note: required because it appears within the type `impl std::future::Future`
   = note: required because it appears within the type `impl std::future::Future`
note: required by `CheckSend`
  --> src/lib.rs:23:1
   |
23 | struct CheckSend<T: Send>(T);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@taiki-e
Copy link
Member

taiki-e commented Jun 19, 2019

I think this is a dup of #57017 and #57478

@Centril Centril added the A-async-await Area: Async & Await label Jun 19, 2019
@cramertj
Copy link
Member

Closing as a duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await
Projects
None yet
Development

No branches or pull requests

4 participants