But I'd rather have 50 lines of nuclear fissile code that needs to be correct than say the whole software.
The danger of Rust it that you twist yourself into a bretzel in order to avoid unsafe, while you should have in fact made a exceptionally well tested and designed unsafe block that is surrounded by code that the compiler checks for you.
I am still convinced that the naming choice for unsafe has some effects that were not intended. Mentally whenever you see unsafe fill in a "trust me" or a "manual override" or whatever. Something that tells you that the programmer had a reason to override the borrow-checker. If they are cool they tell you why the thing they did is indeed safe and sound code.
Obviously, there are some cases where it makes sense to use an unsafe block. However, I think there might be fewer cases then people might think.
As an example, both the popular generic self-referencing crates ouroboros and self_cell have had memory safety bugs in them in the past. (links at the end) Both of them were carefully reviewed by experienced rust developers before their first public release, and yet they still ended up with such bugs. Admittedly, part of the issue is that both crates are trying to be more generic, so they have to be correct over a larger range of circumstances.
But still, these crates have one job, are both less than 1500 LOC, and they were carefully reviewed to ensure they did that one job before their public releases, and they still ended up having issues that were not caught. They might still have issues.
Thus, while it might be fine to use unsafe to state that your array of zeros is a valid utf-8 string without a runtime check, it's probably a good idea to twist yourself into a pretzel if the invariants are not trivial to prove and the overhead to maintenance/runtime isn't too high.
`unsafe` is the part where the compiler trusts you to uphold your own invariants, necessary to prevent Unsoundness. For example:
- unsafe fn get_unchecked(index) - compiler believes you will ensure index < length.
- unsafe fn set_capacity(capacity) - compiler trusts you will not set capacity to value that will cause UB. Even if its code boils essentially to set a field - which is safe according to Rust, but may invalidate other invariants preserving soundness.
The danger of Rust it that you twist yourself into a bretzel in order to avoid unsafe, while you should have in fact made a exceptionally well tested and designed unsafe block that is surrounded by code that the compiler checks for you.
I am still convinced that the naming choice for unsafe has some effects that were not intended. Mentally whenever you see unsafe fill in a "trust me" or a "manual override" or whatever. Something that tells you that the programmer had a reason to override the borrow-checker. If they are cool they tell you why the thing they did is indeed safe and sound code.