Is this can be explained reasonably?

The code fails to compile:

    pub async fn lock(&self) -> Guard {
        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, context.await);

        let mut g1 = self.mux.lock().unwrap();
        unsafe {
            g1.list_add_tail(&mut autx.ent);
        }
        drop(g1);

        let g = (&mut autx).await;
        self.wait_leave(&mut autx);
        g
    }

reporting:

   --> src/syna/cutex.rs:98:28
    |
92  |         let mut g1 = self.mux.lock().unwrap();
    |             ------ has type `std::sync::MutexGuard<'_, Box<list_head::ListHead>>` which is not `Send`
...
98  |         let g = (&mut autx).await;
    |                            ^^^^^^ await occurs here, with `mut g1` maybe used later
...
101 |     }
    |     - `mut g1` is later dropped here

I know how to make it working, just moves 5 lines including g1 into another function, all will be fine:

    fn wait_enter(&self, autx: &mut autex) {
        let mut g1 = self.mux.lock().unwrap();
        unsafe {
            g1.list_add_tail(&mut autx.ent);
        }
        drop(g1);
    }

Well, currently I want to get the thing explained reasonably, I can't explain it, to me, it seems a BUG.

drop(g1) unfortunately is not taken into account. That's a bug/limitation of the async analysis. If you wrap use of g1 in a block, it will work. It doesn't have to be a function, just any other scope.

1 Like

Yes, it does. wait_enter is my final solution, that makes code more beautiful

See also Future is not Send as this value is used across an await and my comment there: