> logic bugs outside "unsafe" can cause bugs unsafe.
This is the wrong understanding of Rust's unsafety encapsulation. For example, no logic bug outside of `unsafe` can cause undefined behavior of Rust std's `Vec` abstraction, which is using underlying unsafe to build.
The point that "because unsafe is used so the entire Rust program is also unsafe" is a real major myth. It's as absurd as saying "because Java runtime using unsafe underlying to build so Java is also unsafe".
Why was the fix to this unsafe memory safety bug [0] only changes to code outside of unsafe Rust blocks?[1][2]
Why does the Rustonomicon[3] say the following?
> This code is 100% Safe Rust but it is also completely unsound. Changing the capacity violates the invariants of Vec (that cap reflects the allocated space in the Vec). This is not something the rest of Vec can guard against. It has to trust the capacity field because there's no way to verify it.
> Because it relies on invariants of a struct field, this unsafe code does more than pollute a whole function: it pollutes a whole module. Generally, the only bullet-proof way to limit the scope of unsafe code is at the module boundary with privacy.
If a logic bug inside Vec and outside any unsafe blocks inside Vec happens, and that logic bug violates any invariants and requirements of the unsafe blocks, that can cause memory unsafety.
That would be the unsoundness of `Vec` itself, but if the abstraction of `Vec` is sound, there would be no way to use `Vec` outside of `unsafe` that can cause memory unsafety.
The point coming back to abstraction and responsibility, in Rust, you can build abstraction that is sound and guarantee memory safety from there. There can be soundness bug inside your abstraction, but it will be a massively smaller surface for auditing and expert required to write such abstraction. Also, when soundness bug appears, the responsibility is solely on the abstraction writer, not the user.
Whereas in C, without those safe abstraction, the surface of doing thing right to avoid memory safety issue is your entire codebase, and responsibility of "holding the knife correctly" is on the user.
> There can be soundness bug inside your abstraction, but it will be a massively smaller surface for auditing and expert required to write such abstraction.
If all of the Vec has to be "audited", or checked and reviewed, including all the code that is not inside unsafe blocks, how would the surface be any smaller?
> The point coming back to abstraction and responsibility, in Rust, you can build abstraction that is sound and guarantee memory safety from there.
Isn't it normal for programming languages to support building abstractions that can help with not only memory safety, but general correctness? C is a bit barebones, but lots of other programming languages, like C#, C++, Haskell and Scala support building abstractions that are harder to misuse.
All of `Vec` is much smaller than all of the place using Vec. IIRC, Vec is around 3k LoC. And for even low level code like Oxide & Android core, they are observed less than 4% of their code is inside or related to unsafe, that’s a massive improvement.
Yes, Rust is not new in term of allow building hard to misuse abstraction, it’s just allow abstraction over memory safety without relying on GC or runtime checks.
Rust achieve this by adding capability to enforce shared XOR mutability with its borrowck which C++ couldn’t.
If the only way of triggering spatial memory unsafety in C++ was vector[i] and that operation was defined to always interrupt execution, then yes, C++ would be considered memory safe. But that is not the case.
The equivalent of vector[i] in Rust is Vex::get_unchecked, which is marked as unsafe, not the default that people reach for normally.
We are, however, talking in this subthread about the compiler inserting bounds checks and (incorrectly) calling the process "static checking".
I refuted that point by pointing out that the same process, if done manually in C++, would not be considered "static analysis that provides memory safety for array access".
Without a borrowck, inside your mutable block, another variable can reference to the mutable version of your x or items, and be mutated outside of that block.
> no company anywhere would just shrug something like this off as "the cost of doing business".
Fox News did, they lost 10 times as much money and is more successful than ever BECAUSE they did it, so for them it's just "the cost of doing business" or even an "investment".
People are already appreciate the accessibility to low level native libraries like duckdb, sqlite, imagemagick, ffmpeg… allowed by wasm. Or high performance games/canvas based applications (figma).
But CRUD developers don’t know/care about those, I guess.