Perhaps the future of software isn't "rewrite everything in Rust", but instead we end up annotating existing C/C++ with borrow checking information. This would be similar to how there is a push in JavaScript to add TypeScript annotations everywhere. It gives you the flexibility of the existing language and ecosystem while still allowing you to use new techniques in programming languages.
With C++ even if your project follows this, there is no way to <i>enforce</i> this across your project's dependencies & wider eco-system.<p>With Rust, its entire ecosystem (however nascent) is subjected to the same strict rules. This is <i>big</i> plus when Rust eco-system matures functionality wise.
> Once you std::move an object and pass it to someone who takes an rvalue-reference, your local object may very well end up in an invalid state.<p>As far as I remember, move constructors/assignments must leave the moved-from object in a valid state - just that the standard doesn't say anything about what that state is for standard classes.<p>Also, I have seen code where some kind of "result" can be moved from an object and then re-generated from scratch with different inputs. In that case it was perfectly valid to use it after move. But that's nitpicking, anyways.
Looks like a lightweight borrow checker, although I wonder how well it fares in places where lifetimes are difficult to track. Or is there a way to annotate methods with this information as well?
I've been writing C++ for 21 years now (started when I was 14). To be honest, I have never seen a solid case where move semantics provided added value (in terms of code readability and maintainability) over just passing object references as function parameters.<p>That big ugly object that would get copied on function return -- just create it before the function call and pass it in as a reference! No copy required.