Though arguably you shouldn't be accessing the same allocation from concurrent threads at the same time anyways, because that requires mutexes, which are ugly. Rust requires you to transfer ownership of objects when passing them between threads, which both enforces mutex-free programming and makes RAII work. Only one thread owns an object at a time, and that's the only thread that can use the object, and is also the thread that is responsible for freeing it when it goes out of scope.
Mutexes are only ugly because few languages properly support them. It is not difficult to ensure at the language level that no object is accessed without owning the the lock associated with that object (read/write locks can be a bit trickier), but for some reason hardly any language implements something along these lines.
It's not fundamentally different from having bound checks for array indices. You can either do that pretty easily at runtime or use a simple type system to do it at compile time (e.g., Boyapati's [1] or Flanagan's [2] work). It's been done, e.g. for Cyclone [3]. This is decades old stuff, not rocket science. Honestly, Monitors had the basic idea right in the 1970s, except as Per Brinch Hansen lamented [4], language designers keep screwing it up.
This implies that an object will be unavailable while it is being passsed between threads. How fast is that? With a mutex, it's as fast as shared memory.
Message passing is a couple of atomic operations, and there are also L4-esque optimizations that allow a message send to be optimized into a direct context switch without a pass through the scheduler.
Also, you can use shared memory in Rust. If you do, the type system ensures there can be no data races: either the data is immutable or you must take the lock before you mutate the data.
Under the hood, you still use shared memory in this style of programming. But the programmer never uses shared memory directly. Instead he passes references to the shared memory to other threads, and the act of passing a reference clears the reference in the sending thread so the sending thread can no longer access it.
In Rust, this style is enforced by the language. In C++11 you can enforce it by the convention of using std::unique_ptr and passing those between threads via a shared data structure like a blocking queue.