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

Comments

Projects
None yet
4 participants
@tirr-c
Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

commented Jun 19, 2019

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

@cramertj

This comment has been minimized.

Copy link
Member

commented Jun 19, 2019

Closing as a duplicate.

@cramertj cramertj closed this Jun 19, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.