In Rust you can use #![forbid(unsafe_code)] to totally forbid unsafe code in your codebase. Rust also checks for memory safety at compile time, these are strong guarantees that ensure that if the code compiles it is memory safe.
In Rust you can use #![forbid(unsafe_code)] to totally forbid unsafe code in your codebase. Rust also checks for memory safety at compile time, these are strong guarantees that ensure that if the code compiles it is memory safe.
But unsafe Rust is still far better than C because the unsafe keyword is visible and one can grep it and audit the unsafe parts. Idiomatic Rust also requires that the programmer provides comments as to why that part is unsafe.
The practical memory safety we see in Rust is much more the result of trying hard to avoid memory safety issues and requiring comments for unsafe blocks is part of this culture.
The argument is that while you wouldn't in fact fix the bug by modifying the unsafe code block, the unsafe code block was wrong until you fixed the other code.
For example imagine if a hypothetical typo existed inside RawVec (the implementation details of Vec) causing the growable array to initially believe it has 1 element inside it, not 0 even though no space has been allocated and nothing was stored. That's safe code, and of course the correct fix would be to change it from 1 to 0, easy. But this broken type is arguably broken because the unsafe code would deference a pointer that isn't valid, trying to reach that non-existent value. It would be insane, perhaps even impossible, to modify that code to somehow handle the "We wrote 1 instead of 0" mistake, when you could instead fix the bug - but that is where the theoretical fault lies.