Idiomatic C++ favors values and copy semantics. Rust favors references and move semantics. C++ has function and method overloading, and Rust does not. There are so many places where Rust chose exactly the opposite of "modern" C++ that calling Rust a codification or formalization of C++ makes no sense at all to me. Rust has some great features, and C++ has a lot of warts, but Rust is definitely not an improved C++.
Rust seems like a reaction to problems in C++, but for many design decisions I think they erred on the side of doing the opposite of C++ and ignored the things C++ does well.
What are you looking for that Rust is missing?
Here's an example that has bitten me several times now. Try and implement the following C++14 code in Rust:
template<class T>
struct Something { T a, b; };
template<class S, class T>
auto operator *(const S& x, const Something<T>& y) {
return Something<decltype(S() * T())> {
x*y.a, x*y.b
};
}
There are ugly workarounds, and I'm certain they have their reasons, but it's so much simpler and cleaner in C++.This is a bold claim, IMO somehow misleading. To "do everything you can do in C++", you have to use the unsafe part of rust, where you essentially lose of the compiler guaranty. Second and maybe ever more importantly, rust never promise the remedy to "nearly all bugs", the universe of bug preventable is a well-defined limited set.
Or, consider Firefox. Firefox's rendering engine will soon be Servo (Rust). I presume that its networking and its Javascript engine will eventually go the same way. Eventually, the only stuff left written in C in the Firefox codebase will be "glue code": business-policy logic that doesn't do heavy lifting, and doesn't need speed. In other words, the exact type of code where Go's "you'll be safer without this" assertion applies. Firefox as Go + Rust: why not?
I would phrase it like this:
• Go is a useful, safe subset of C (with a rather expanded libc.) Go lets you do fewer things than C (e.g. hard real-time things; processor-optimized things) but for most people, they don't need those things, and delving into them was what seeded the bugs into their C/C++ projects in the first place, completely unnecessarily.
• Rust is a formalization/codification of idiomatic C++. It's not a subset; it's a rethink, like Plan 9 is a rethink of Unix. You can do everything in Rust that you can do in C++, and the compiler will catch (nearly) all the bugs you would have left in the equivalent C++ project.
In other words, Go says "you don't need this"; Rust says "if you're so sure you need this, let's ensure you do it right."
For any given piece of code, either Go's assertion or Rust's assertion could be "correct." You either need the things only Rust lets you do, or you don't.
For a large codebase, though, I expect the answer is actually nearly always going to end up somewhere between. Big apps or libraries always have that one part that does heavy lifting and has to go fast, but go fast correctly; and 99% that doesn't.
Thus, I envision the future of many "systems software" codebases to look like this:
1. (1% of LOC) an "engine" library, written in Rust, which compiles to a C-ABI shared object;
2. (3% of LOC) an "engine wrapper" library, written in Go, which imports the "engine" object using Go's C FFI and then exposes a safe Go API to it—and also, the tests for the engine library, written in Go because it's easier;
3. (96% of LOC) the app itself, written in Go, which calls into the "engine wrapper."