4 ms·
The situation isn't remotely similar to C++. After you prove an algorithm correct in C++, you can still generally not guarantee that it is used correctly by the
by Jweb_Guru 9y ago
The situation isn't remotely similar to C++. After you prove an algorithm correct in C++, you can still generally not guarantee that it is used correctly by the program--the needed preconditions and postconditions are not expressible in its type system, and code that passes the C++ type checker can easily violate invariants elsewhere. In Rust, after you prove code in an unsafe module correct with respect to its type, you can use the module from any safe block and still preserve memory safety and data race freedom.
The important thing that is different about code proved in Rustbelt is that the guarantees can be made local. Once you prove a semantic type for a particular piece of unsafe code, you do not have to know anything about that unsafe code when you prove some other piece of unsafe code correct, as long as they are independent of each other (including unsafe code that is invoked parametrically). This means that the proof effort does not scale with the size of your overall code, or quadratically with the number of unsafe modules, but linearly with the number of unsafe modules. That's absolutely not true in C++; it works entirely because of Rust's precise accounting of ownership.
Finally: even in Rust that uses a lot (relatively speaking) of unsafe code, only a small percentage of the overall code is unsafe. Typical codebases have many hundreds of lines of safe code per line of unsafe code. This means the proof effort is quite reasonable. Automated proofs about C and C++ programs are not trivial and all known techniques do not scale to real code that is more than a few hundred lines, and proof assistant based techniques generally must either prove things about the entire program, or use restricted subsets and annotate them with information very much like what is in Rust's type system. The sel4 microkernel is one of the largest formally verified C programs, and it took 20 man-years of effort and hundreds of thousands of lines to prove, while the actual C code clocks in at under 10,000 lines. While the sel4 proof effort cared about more than memory safety, a significant amount of it was devoted to that. By contrast, I have personally written 10,000+ line Rust codebases with 4 lines of unsafe in them (and even those could be avoided if I were willing to sacrifice a bit of performance); I used only a few standard library functions, and third party crates like Rayon that have undergone a fair amount of verification effort themselves. Memory safety in Rust actually scales to realistic codebase sizes.
The existing result isn't everything; there is still a lot of work to do to make sure it's accurately capturing all of Rust's semantics. But most of the "hard parts" have been done--we are pretty confident that the encapsulation I'm describing actually works. That is far better than the situation in C++.