There's a nice Kevlin Henney talk where he lays out this diagram:
|
non-shared mutable state | shared mutable state
|
----------------------------+------------------------
|
non-shared immutable state | shared immutable state
|
Each quadrant is safe, except the one in the top right: shared mutable state.
Functional languages are great at the bottom two, since they strongly encourage immutable state. Message-passing based concurrency strongly encourages non-shared state, the safe two on the left.
Rust is the only language I've seen which encourages all three safe quadrants, while making the fourth a compile-time error.