My code is here:
use std::future::Future;
use std::rc::Rc;
enum Error {}
#[derive(Default)]
struct Foo {
rc: Rc<()>,
}
fn take_foo<'a>() -> &'a Foo { todo!() }
async fn bar() {}
async fn foo_guard<F, O>(f: F) -> Result<O, Error>
where
F: FnOnce(&Foo) -> Result<O, Error> {
let foo = Foo::default();
match f(&foo) {
Ok(v) => {
drop(foo);
Ok(v)
}
Err(err) => {
drop(foo);
bar().await;
Err(err)
}
}
}
fn block_on<F: Future + Send + Sync + 'static>(f: F) {}
pub fn run() {
block_on(async {
foo_guard(|foo| -> Result<bool, Error> {
Ok(false)
}).await;
});
}
Errors:
Compiling playground v0.0.1 (/playground)
error: future cannot be sent between threads safely
--> src/lib.rs:35:14
|
35 | block_on(async {
| ______________^
36 | | foo_guard(|foo| -> Result<bool, Error> {
37 | | Ok(false)
38 | | }).await;
39 | | });
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
note: future is not `Send` as this value is used across an await
--> src/lib.rs:26:18
|
18 | let foo = Foo::default();
| --- has type `Foo` which is not `Send`
...
26 | bar().await;
| ^^^^^^ await occurs here, with `foo` maybe used later
...
30 | }
| - `foo` is later dropped here
note: required by a bound in `block_on`
--> src/lib.rs:32:25
|
32 | fn block_on<F: Future + Send + Sync + 'static>(f: F) {}
| ^^^^ required by this bound in `block_on`
error: future cannot be shared between threads safely
--> src/lib.rs:35:14
|
35 | block_on(async {
| ______________^
36 | | foo_guard(|foo| -> Result<bool, Error> {
37 | | Ok(false)
38 | | }).await;
39 | | });
| |_____^ future created by async block is not `Sync`
|
= help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Rc<()>`
note: future is not `Sync` as this value is used across an await
--> src/lib.rs:26:18
|
18 | let foo = Foo::default();
| --- has type `Foo` which is not `Sync`
...
26 | bar().await;
| ^^^^^^ await occurs here, with `foo` maybe used later
...
30 | }
| - `foo` is later dropped here
note: required by a bound in `block_on`
--> src/lib.rs:32:32
|
32 | fn block_on<F: Future + Send + Sync + 'static>(f: F) {}
| ^^^^ required by this bound in `block_on`
error: could not compile `playground` due to 2 previous errors
I think that if a variable is dropped early, then it won't be available in later stages, then it shouldn't be considered to cross the .await point, but the compiler explains:
drop(foo);
bar().await;
| ^^^^^^ await occurs here, with `foo` maybe used later
Is my understanding wrong? Are there any keywords to search for?