-   Notifications  You must be signed in to change notification settings 
- Fork 13.9k
Open
Labels
I-async-nominatedNominated for discussion during an async working group meeting.Nominated for discussion during an async working group meeting.WG-asyncWorking group: Async & awaitWorking group: Async & await
Description
There's probably a bug filed already but this code does not compile, though it really ought to:
use std::sync::Mutex; async fn foo(m: &Mutex<u32>) { let lock = m.lock().unwrap(); if condition(&lock) { drop(lock); return bar().await; } drop(lock); return bar().await; } async fn bar() { } fn is_send<T: Send>(t: T) { } fn condition(x: &u32) -> bool { false } fn main() { let m = Mutex::new(22); is_send(foo(&m)); }I believe the problem is specific to the &lock, which causes the capture analysis to get nervous -- even though lock is dropped. This is distilled from real-world code within Amazon.
Error you get today:
error: future cannot be sent between threads safely --> src/main.rs:26:13 | 26 | is_send(foo(&m)); | ^^^^^^^ future returned by `foo` is not `Send` | = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, u32>`, which is required by `impl Future<Output = ()>: Send` note: future is not `Send` as this value is used across an await --> src/main.rs:9:22 | 6 | let lock = m.lock().unwrap(); | ---- has type `MutexGuard<'_, u32>` which is not `Send` ... 9 | return bar().await; | ^^^^^ await occurs here, with `lock` maybe used later note: required by a bound in `is_send` --> src/main.rs:18:15 | 18 | fn is_send<T: Send>(t: T) { } | ^^^^ required by this bound in `is_send` I'm nominated for async just to get some eyes on this. I'd be interested to discuss fixes, I have a few thoughts, though I'd have to look at the code too.
Metadata
Metadata
Assignees
Labels
I-async-nominatedNominated for discussion during an async working group meeting.Nominated for discussion during an async working group meeting.WG-asyncWorking group: Async & awaitWorking group: Async & await