Drop on `await` point

Hello, what do you think about potentially adding a language feature that will allow forcing synchronous drop at the await boundary, with an error if value is used afterwards? There exists lots of data structures that rely on the fact that they are not being held across await point, and that might help with it.

can you expand on what that would look like ?

can you name some ? currently there is no way to ensure one is not held across an await point afaik.

i guess a way that could work is a recursive auto trait that is mutually exclusive with Future ? that's a bit strange. should it cover Coroutines as well ?

i guess a way that could work is a recursive auto trait that is mutually exclusive with Future ? that's a bit strange. should it cover Coroutine s as well ?

I currently don't propose any implementation path, but as a general idea. And yes, Coroutine as well.

can you name some ? currently there is no way to ensure one is not held across an await point afaik

Mostly mutexes do rely on the fact that they are not held across await points, to prevent deadlocks. Clippy even has lints against it, like Clippy Lints .

i suppose this is semantics, but i find "rely on" to be innacurate, as MutexGuard and RefCell::Ref do nothing to prevent being held across an awaitpoint, and work perfectly fine when being held across one (as long as one doesn't deadlock them).

but it is true there are lints against doing so and they are good lints, because await points do strongly increase the chance of deadlocks.

i really liked this on the subject of mutexes and await points, though it is technically more about cancel safety.

i do agree with your goal, but i personally feel it should be more of a warning, like must_use

2 Likes

So this sounds like a sort of "space between two yield points is a sort of scope".

I wonder if you can get part way there by using this sort of a pattern:

async {
  {
    let guard = mutex.lock();
    //...sync operations...
  }
  foo().await;
  {
    //...more sync ops
  }  
}
3 Likes

You might find the #[must_not_suspend] attribute interesting. Tracking issue: Tracking Issue for `must_not_suspend` lint (RFC #3014) · Issue #83310 · rust-lang/rust · GitHub

3 Likes