What do you mean by "rules out data races"? If I have one piece of code that writes two variables and another that reads them on another thread, there's no way for the compiler to know whether those two changes need to be atomic, serialized, or uncoordinated.