Presuming syntax for “unsafe” that gracefully degrades in non-aware compilers, why couldn’t a particular compiler start doing it right now, starting with a very trivial safety checker than can be iteratively improved upon once the framework is in place?
I feel like D has gone this route of incrementally adding features (like borrow checking) to the language that, in principle, improve safety.
I wonder if anyone here has more experience to know how well it has worked?
One massive advantage of Rust is that they started with borrow checking from the beginning. I think one thing that often gets understated in these discussions is how much it matters to have your entire ecosystem using a set of safe abstractions. This is a major drag for C++, and I suspect that even if the language went a route like D they'd still have gaping safety holes in practical, everyday usage.
It still hasn't, that has been unfortunely a common theme in D's evolution, chasing the next big idea that will this time bring folks into D, while leaving the previous ones half implemented with bugs.
So now there is GC and @nogc, lifetimes but not quite, scoped pointers, scoped references,... while Phobos and ecosystem aren't in a state to fully work across all those variations.
It is easy to say add unsafe. However the details are very complex. I've read a few of the papers proposing something like this, and they spend a lot of time discussing some nasty details that are important to get right.