The compiler enforces rules that when followed mean that your code should not have any concurrency bugs. Those rules enforce a subset of behavior that is
actually safe. There are other ways of structuring the data and processing that are also safe that Rust doesn't allow because it's not smart enough to reason about (and to be clear many people aren't smart enough to easily reason about either). In those cases, you can wrap the code in in question an unsafe block, which tells Rust to relax certain rules for the scope of that block, and gives you control somewhat analogous to what you get in C. The benefit is that when used sparingly and concisely (if at all), this allows certain bugs to be reduced to originating in very limited parts of the code base.
As an example, if you have a data structure or algorithm that you know is safe when implemented correctly, you can implement it in an unsafe black and expose it through a safe API/function. To my understanding, a lot of Rust's standard library core containers do exactly this. It's not guaranteed to be bug free, but it does provide quite a bit more assurance.