# Manual drop of !Send value doesn't make async block sendable

**URL:** <https://users.rust-lang.org/t/manual-drop-of-send-value-doesnt-make-async-block-sendable/66968>\
**Category:** help\
**Created:** [November 7, 2021, 9:23am UTC](https://users.rust-lang.org/t/manual-drop-of-send-value-doesnt-make-async-block-sendable/66968 "2021-11-07T09:23:53Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbe](https://avatars.discourse-cdn.com/v4/letter/j/f6c823/32.png) [@jbe](https://users.rust-lang.org/u/jbe)\
**Post date:** [November 7, 2021, 9:23am UTC](https://users.rust-lang.org/t/manual-drop-of-send-value-doesnt-make-async-block-sendable/66968/1 "2021-11-07T09:23:53Z")

</div>

Context:  
I need to use [`Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html)es (or even better: [`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html)s if that was possible) in some async closures, blocks, or functions. I would like the resulting [`Future`](https://doc.rust-lang.org/std/future/trait.Future.html)s to be [`Send`](https://doc.rust-lang.org/std/marker/trait.Send.html). The locking (or borrowing, respectively) will only be necessary for a short time while no async operations are executed.

Problem:  
If I use a [block expression](https://doc.rust-lang.org/reference/expressions/block-expr.html) to limit the scope of the [`MutexGuard`](https://doc.rust-lang.org/std/sync/struct.MutexGuard.html) (or [mutable borrow](https://doc.rust-lang.org/std/cell/struct.RefMut.html), respectively), I can make the `Future` (named "`_sendable_future`") be `Send`. But it won't work with the "`_nonsend_future`" below. The only difference is that in the latter case, I use a manual [`drop`](https://doc.rust-lang.org/std/mem/fn.drop.html) instead of making an extra [block expression](https://doc.rust-lang.org/reference/expressions/block-expr.html) and letting the `guard` (or `borrow`, respectively) drop because their [drop scope](https://doc.rust-lang.org/reference/destructors.html#drop-scopes) ends.

Question:  
Why do these two cases behave differently? Is that because the compiler doesn't "notice" that the values are dropped when constructing the `Future` from the [`async` block](https://doc.rust-lang.org/reference/expressions/block-expr.html#async-blocks)?

Thanks for your help, I include a playground example below:

```rust
use std::cell::RefCell;
use std::future::Future;
use std::pin::Pin;
use std::sync::Mutex;

async fn some_func() {}

fn main() {
    // This works fine:
    let cell1 = RefCell::new(0);
    let mutex1 = Mutex::new(0);
    let _sendable_future: Pin<Box<dyn Future<Output = ()> + Send>> =
        Box::pin(async move {
            {
                let mut borrow = cell1.borrow_mut();
                let mut guard = mutex1.lock().unwrap();
                *borrow += 1;
                *guard += 1;
            }
            some_func().await;
        });

    // But this doesn't work:
    let cell2 = RefCell::new(0);
    let mutex2 = Mutex::new(0);
    // (unless we remove the `Send` bound)
    let _nonsend_future: Pin<Box<dyn Future<Output = ()> + Send>> =
    //let _nonsend_future: Pin<Box<dyn Future<Output = ()>>> =
        Box::pin(async move {
            let mut borrow = cell2.borrow_mut();
            let mut guard = mutex2.lock().unwrap();
            *borrow += 1;
            *guard += 1;
            drop(borrow);
            drop(guard);
            some_func().await;
        });
}

```

([Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b0c94ba8b9da9ded0ceb9194e8777464))

_(Edit: Formatting only)_

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/skifire13/32/17959_2.png) [@SkiFire13](https://users.rust-lang.org/u/SkiFire13)\
**Post date:** [November 7, 2021, 10:18am UTC](https://users.rust-lang.org/t/manual-drop-of-send-value-doesnt-make-async-block-sendable/66968/2 "2021-11-07T10:18:08Z")

</div>

This looks like an instance of [Tracking issue for more precise generator captures · Issue #69663 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/issues/69663)

Looks like this is a consequence of how the compiler decides which types are captured in the future, and that's by looking at the locals in scope at await points, ignoring whether they can be alive or not. This is a bit tricky to fix because the future's type is computed in an earlier stage than the one where liveness is known.

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [February 5, 2022, 10:19am UTC](https://users.rust-lang.org/t/manual-drop-of-send-value-doesnt-make-async-block-sendable/66968/3 "2022-02-05T10:19:02Z")

</div>

Closed on February 5, 2022, 10:19am UTC

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
