It doesn’t. The issue here seems like a more vanilla logical data race + object reuse that Rust can’t really do anything about. Rust only makes sure that only one thread at a time writes and other reads don’t race that write. It can’t make guarantees that the relative ordering of reads and wires makes sense for your use-case.
It can simplify certain abstractions of course so that you can provide easier tools for devs to avoid footguns.
What rust would do for this particular situation is make it painful to share an object like this across threads and make it obvious that such a share is happening. That wouldn't prevent this problem, but it would make it harder to stumble into.
Maybe, maybe not. A claim like that is definitely in the realm of "people think race condition bugs are solved by switching to Rust". I don't know Rust well enough to evaluate your claim but that feels like an incorrect statement - sharing data between threads should be as easy as wrapping something in Arc & Mutex to get similar semantics I think.
Even if that particular bug is actually harder to stumble into, there's no guarantee the space of thread synchronization issues one might stumble into is inherently smaller for Rust than for Ruby, so all you're doing is exchanging one class of failure modes for another.
As I said, they aren't solved but they are hard to do unknowingly.
In most other languages, sharing mutable data across threads is unprotected. You are lucky if you get a compiler warning. Rust disallows that completely. You cannot share mutable data across threads without first wrapping that data in thread safety constructs.
That's what happened here. A mutable variable was shared between threads and updated from different threads. Rust makes it obvious that this variable is accessed from multiple threads even if it doesn't prevent 2 threads from writing to the variable at wrong times. That's where it is a partial solution to the problem.
Sharing is as easy as wrapping the thing in a Mutex, and if you are a programmer that sees something wrapped in a mutex you should immediately start thinking of the thread implications. You don't have to, but you should.
That mutex follows the variable around anywhere you want to start changing it.
In a language like C or Ruby, that's not something that is patently obvious. Shared variables aren't wrapped with anything. It's perfectly understandable for someone to not realize this bit of shared state is mutated across threads.