Otherwise C code can muck with things the rust code considers invariant and "verified". Or if something with a soundness issue is used, maybe safe doesn't quite mean safe.
As a counterpoint unsafe can be safe if the behaviour is well modelled and understood. It just means no checks are applied to the superset features of rust if they are used (outside of unsafe they can't be). The standard library of rust uses unsafe quite a bit.
Probably the best way I can try to put it is that "safe" is a subset of correct where you mean no memory safety issues (spatial or temporal) and rust tries to prove this for you. Except it you type unsafe then it is on you to promise to the compiler that the extra footguns it enables are used correctly. If you include this code in a larger program some of these guarantees are statically assured at compile time for performance including the correctness of the runtime checks rust does. There is no compartmentalisation unless you use OS features (separate processes) for that (or whatever webasm allows for).