I have the following code failing to compile. giving
::: /home/zylthinking/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/tokio-1.11.0/src/task/spawn.rs:127:21
|
127 | T: Future + Send + 'static,
| ---- required by this bound in `tokio::spawn`
|
= help: within `impl Future`, the trait `Send` is not implemented for `std::sync::MutexGuard<'_, Box<ListHead>>`
= note: required because it appears within the type `for<'r, 's, 't0, 't1, 't2> {ResumeTy, &'r Autex, Result<i32, i32>, autex::autex<'s>, std::sync::MutexGuard<'t0, Box<ListHead>>, &'t1 mut autex::autex<'t2>, ()}`
= note: required because it appears within the type `[static generator@Autex::lock::{closure#0} for<'r, 's, 't0, 't1, 't2> {ResumeTy, &'r Autex, Result<i32, i32>, autex::autex<'s>, std::sync::MutexGuard<'t0, Box<ListHead>>, &'t1 mut autex::autex<'t2>, ()}]`
= note: required because it appears within the type `from_generator::GenFuture<[static generator@Autex::lock::{closure#0} for<'r, 's, 't0, 't1, 't2> {ResumeTy, &'r Autex, Result<i32, i32>, autex::autex<'s>, std::sync::MutexGuard<'t0, Box<ListHead>>, &'t1 mut autex::autex<'t2>, ()}]>`
= note: required because it appears within the type `impl Future`
= note: required because it appears within the type `impl Future`
= note: required because it appears within the type `for<'r, 's, 't0> {ResumeTy, &'r Autex, Autex, impl Future, (), Guard<'t0>, u64, Duration, Sleep}`
= note: required because it appears within the type `[static generator@tests/tokio.rs:8:20: 17:6 for<'r, 's, 't0> {ResumeTy, &'r Autex, Autex, impl Future, (), Guard<'t0>, u64, Duration, Sleep}]`
= note: required because it appears within the type `from_generator::GenFuture<[static generator@tests/tokio.rs:8:20: 17:6 for<'r, 's, 't0> {ResumeTy, &'r Autex, Autex, impl Future, (), Guard<'t0>, u64, Duration, Sleep}]>`
= note: required because it appears within the type `impl Future`
It seems the auto generated future put a MutexGuard into it's generic parameter, which is dropped before await.
Just for a try, I put the code into another fn a(); this time, it compiles.
So, this is a compiler bug or there some reasonable things I don't know?
fn a(&self, autx: &mut autex) {
let mut g0 = self.mux.lock().unwrap();
unsafe {
g0.list_add_tail(&mut autx.ent);
}
drop(g0);
}
pub async fn lock<'a>(&'a self) -> Guard<'a> {
let r = self
.hold
.atomic_compare_exchange(0, 1, Ordering::Relaxed, Ordering::Relaxed);
if r.is_ok() {
return Guard(self);
}
let mut autx = autex::new(self);
// this line will compiles
self.a(&mut autx);
// but the following is not
// let mut g0 = self.mux.lock().unwrap();
// unsafe {
// g0.list_add_tail(&mut autx.ent);
// }
// drop(g0);
let g1 = (&mut autx).await;
let g2 = self.mux.lock().unwrap();
unsafe {
autx.ent.list_del();
}
drop(g2);
g1
}