Closed
Description
I tried this code:
use std::future::Future;
use std::sync::Mutex;
fn fake_spawn<F: Future + Send + 'static>(f: F) { }
async fn wrong_mutex() {
let m = Mutex::new(1);
{
let mut guard = m.lock().unwrap();
(async { "right"; }).await;
*guard += 1;
}
(async { "wrong"; }).await;
}
fn main() {
fake_spawn(wrong_mutex());
}
I expected to see this happen:
error: future cannot be sent between threads safely
--> src/main.rs:18:3
|
4 | fn fake_spawn<F: Future + Send + 'static>(f: F) { }
| ---------- ---- required by this bound in `fake_spawn`
...
18 | fake_spawn(wrong_mutex());
| ^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
|
= help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, i32>`
note: future is not `Send` as this value is used across an await
--> src/main.rs:14:3
|
9 | let mut guard = m.lock().unwrap();
| --------- has type `std::sync::MutexGuard<'_, i32>`
...
12 | }
| - `mut guard` is later dropped here
9 | let mut guard = m.lock().unwrap();
10 | (async { "right"; }).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `mut guard` maybe used later
error: aborting due to previous error
Instead, this happened:
error: future cannot be sent between threads safely
--> src/main.rs:18:3
|
4 | fn fake_spawn<F: Future + Send + 'static>(f: F) { }
| ---------- ---- required by this bound in `fake_spawn`
...
18 | fake_spawn(wrong_mutex());
| ^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
|
= help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, i32>`
note: future is not `Send` as this value is used across an await
--> src/main.rs:14:3
|
9 | let mut guard = m.lock().unwrap();
| --------- has type `std::sync::MutexGuard<'_, i32>`
...
12 | }
| - `mut guard` is later dropped here
13 |
14 | (async { "wrong"; }).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `mut guard` maybe used later
error: aborting due to previous error
Note that the await pointed to be the error message is wrong.
The code that gets the span for the await is here
. The last span in generator_interior_types is not guaranteed to be the right await point.Meta
rustc --version --verbose
:
rustc 1.42.0 (b8cedc004 2020-03-09)
binary: rustc
commit-hash: b8cedc00407a4c56a3bda1ed605c6fc166655447
commit-date: 2020-03-09
host: x86_64-apple-darwin
release: 1.42.0
LLVM version: 9.0
I also see the same behaviour with:
rustc 1.44.0-nightly (6dee5f112 2020-04-06)
binary: rustc
commit-hash: 6dee5f1126dfd5c9314ee5ae9d9eb010e35ef257
commit-date: 2020-04-06
host: x86_64-apple-darwin
release: 1.44.0-nightly
LLVM version: 9.0
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Done