What shall Sync mean across an .await?

I think the near to medium term the best solution is for everyone writing async code that is expected to run on a multithreaded executor to always use Sync primitives. This is not a very restrictive limitation in my opinion: use Arc, use futures::Mutex (which you would want to use anyway), don't use Rc, RefCell, Cell, or std::Mutex.

Unfortunately, some libraries have - out of ignorance of this issue or mistake - implemented non-Sync types in their APIs. This will have to be fixed.

In the longer term, I'm not very optimistic that making this analysis more precise will ever be implemented, but I'll make this note:

This problem has a fundamental analogy to the lifetime problems that led us to the current async/await system. Previously, a future containing references of a lifetime 'a can also not exceed that lifetime: now the lifetimes are "closed over" to create futures that are 'static, unless the references came in externally. This problem stems from a desire to similarly "close over" internal non-Sync data. Of course the fact that lifetimes have a built-in escape analysis (fundamentally they are a tool for escape analysis) contributed to making the solution for lifetimes much more straightforward than it would be for the Sync trait.

4 Likes