4 ms·
Well yes but this seems more complicated. If the code was executed on a single thread it would be correct. The compiler somehow knows that await might move the
by Spivak 1y ago
Well yes but this seems
more complicated. If the code was executed on a single thread it would be correct. The compiler somehow knows that await might move the work to another thread in which the code would still be correct if it weren't for the pesky undefined behavior. At all points it seems like it would be single access and yet it catches this.
- 0x1ceb00da 1y agoAn async function call returns a future which is an object holding the state of the async computation. Multithreaded runtimes like tokio require this future to be `Send`, which means it can be moved from one thread to another. The future generated by the compiler is not Send if there is a local variable crossing an await boundary that is not `Send`.
- ViewTrick1002 1y agoThat comes from the where the tokio task is spawned annotating the future with send. https://docs.rs/tokio/latest/tokio/task/fn.spawn.html https://docs.rs/tokio/latest/tokio/task/fn.spawn.html If you want to run everything on the same thread then localset enables that. See how the spawn function does not include the send bound. https://docs.rs/tokio/latest/tokio/task/struct.LocalSet.html https://docs.rs/tokio/latest/tokio/task/struct.LocalSet.html
- veber-alex 1y agoThe compiler doesn't know anything about threads. The compiler knows the Future doesn't implement the Send trait because MutexGuard is not Send and it crosses await points. Then, tokio the aysnc runtime requires that futures that it runs are Send because it can move them to another thread. This is how Rust safety works. The internals of std, tokio and other low level libraries are unsafe but they expose interfaces that are impossible to misuse.