Future is not `Send` as this value is used across an await

I've got code which looks like this:

async fn whatever(self) {
   let r: Ref<Foo> = self.foo.borrow();  // tokio::sync::watch::Ref
   // no await here
   drop(r);
   
   some_other_stuff.await;
} 

The compiler assumes r is dropped at the end of the function, not at the drop call and complains r can be used accross await. As if it ignored the call to drop.

If I modify the code to use lexical scope instead of drop, everything works fine:

async fn whatever(self) {
   {
       let r: Ref<Foo> = self.foo.borrow();  // tokio::sync::watch::Ref
       // no await here
   }
   some_other_stuff.await;
} 

Is it by design, or is it a compiler bug?

This issue or similar.

1 Like

Note also that in general, drop is “just a function”; the compiler is not aware that drop discards the value rather than doing something else with it. That doesn't affect this situation, because the compiler does know that the value was definitely moved out of the whatever future, and should be able to make use of that fact, as per the linked issue; but it is something to be aware of in general, and a reason you might need to use a scope rather than drop.

I think this is the same problem as #57478, which I also linked in this thread.

Workaround is to use a block, like the OP here suggested.

It sometimes can make syntax a bit ugly, and I usually add a TODO in my code to fix it in case this issue is resolved some day.


I also found this tracking issue #97331 regarding a corresponding feature gate.

1 Like

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.