Skip to content

Async Borrowing Issue #128096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mingyang91 opened this issue Jul 23, 2024 · 1 comment
Closed

Async Borrowing Issue #128096

mingyang91 opened this issue Jul 23, 2024 · 1 comment
Labels
C-bug Category: This is a bug.

Comments

@mingyang91
Copy link

I tried this code:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5203de66797e0725271a464be3604d0c

#![allow(unused)]

struct NotSend(std::marker::PhantomData<*mut ()>);

impl NotSend {
    fn new() -> Self {
        Self(std::marker::PhantomData)
    }
}

unsafe impl Sync for NotSend {}

#[derive(Clone)]
struct WatchRecv;

impl WatchRecv {
    fn borrow(&self) -> Ref<'_> {
        Ref(self, NotSend::new())
    }
}

struct Ref<'a>(&'a WatchRecv, NotSend);

fn assert_send<F: std::future::Future + Send>(f: F) -> F { f }

impl Ref<'_> {
    fn len(&self) -> usize { 0 }
}

async fn another_future() {
    loop {}
}

async fn real_main() {
    let rx = WatchRecv;
    let mut binding = rx.clone();
    assert_send(async move {

        // This doesn't work.
        let value = binding.borrow();
        let len = value.len();
        drop(value);
        println!("len: {len}");

        /*
        // This works.
        let len = {
            let value = binding.borrow();
            value.len()
        };
        */
        another_future().await;
    }).await;
    println!("{:?}", rx.borrow().len());
}

I expected to see this happen: pass compile

Instead, this happened: error

   Compiling playground v0.0.1 (/playground)
error: future cannot be sent between threads safely
  --> src/lib.rs:37:5
   |
37 | /     assert_send(async move {
38 | |
39 | |         // This doesn't work.
40 | |         let value = binding.borrow();
...  |
52 | |         another_future().await;
53 | |     }).await;
   | |______^ future created by async block is not `Send`
   |
   = help: within `{async block@src/lib.rs:37:17: 53:6}`, the trait `Send` is not implemented for `*mut ()`, which is required by `{async block@src/lib.rs:37:17: 53:6}: Send`
note: future is not `Send` as this value is used across an await
  --> src/lib.rs:52:26
   |
40 |         let value = binding.borrow();
   |             ----- has type `Ref<'_>` which is not `Send`
...
52 |         another_future().await;
   |                          ^^^^^ await occurs here, with `value` maybe used later
note: required by a bound in `assert_send`
  --> src/lib.rs:24:41
   |
24 | fn assert_send<F: std::future::Future + Send>(f: F) -> F { f }
   |                                         ^^^^ required by this bound in `assert_send`

error: could not compile `playground` (lib) due to 1 previous error

but if I use the following code:

let len = {
    let value = binding.borrow();
    value.len()
};

it will pass compile.

Meta

rustc --version --verbose:

rustc --version --verbose
rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: aarch64-apple-darwin
release: 1.79.0
LLVM version: 18.1.7

And rust online playground.

@mingyang91 mingyang91 added the C-bug Category: This is a bug. label Jul 23, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 23, 2024
@mingyang91
Copy link
Author

duplicate with #128095

@fmease fmease removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants