Of course unsafe code can generate unsoundness in safe code. The main difference is that unsoundness would be more bounded somewhere between unsafe blocks as you’ve written which improves code review and the speed with with issues are found.
I’ll also note that the +=1 is also potentially unsound in release builds since Rust doesn’t do overflow checks at runtime (although since it presumably originates from a valid address that’s not possible in practice). It’s the one practical tradeoff Rust chose to make to allow UB in sounds code so that code wasn’t overly verbose while retaining good performance at runtime.
You're confusing it with overflow of signed integers.
No - I guess I should have been more clear but I don't think `unsafe` demarcates the boundary between sound and unsound. I think what happens in unsafe are things that potentially memory unsafe or thread unsafe. Pointer casts are not included in that - I feel that would only provide a false sense of safety.
As for false sense of safety or not, that’s a value judgement whereas we can actually derive metrics about it (eg. build a version of the compiler that require it be annotated unsafe and then investigate now illegal call sites to count how many errors per instance there turned out to be).
That said, I think `as` is generally a code smell and the one large professional Rust project I’ve worked on banned it in CI via clippy.
I don't think this is true in general. Unsafe is used pretty frequently for things that are themselves memory safe but may violate invariants which can cause memory unsoundness in other places. An example would be `std::str::from_utf8_unchecked` which is not itself memory unsafe. But various safe methods on `str` are memory safe ONLY if the str contains valid UTF8
As I understand it, unsafe pretty much says "what you are doing here may violate memory safety". Casting doesn't do that, only dereferencing. If you'd like to increase the scope to also include "things that might violate memory safety for another code block", then shouldn't compile either:
the mutation of foo is also "unsafe" under this definition, and the compiler shouldn't let you modify pointers in any manner.