Pointer aliasing by default was a mistake. I won't budge on this one. The borrow checker is a good idea independent of memory safety. In fact, I would say that if you think that the borrow checker is a tool to ensure memory safety and it is getting in the way of flexibility, you probably don't understand the underlying problem.
The memory safety given by Rust is obviously not airtight, because the aliasing case requires either unsafe blocks or reference counting, but you fundamentally give something up by allowing pointer aliasing that you can never get back once the genie is out of the bottle. The painfully constricting flexibility so reminiscent of C that everyone else clings to is not where I want to go back to.
> The borrow checker is a good idea independent of memory safety. In fact, I would say that if you think that the borrow checker is a tool to ensure memory safety and it is getting in the way of flexibility, you probably don't understand the underlying problem.
I don't think that, but I don't think that "the borrow checker is a good idea independent of memory safety" in an unqualified way. I don't doubt its general utility for one second, but I resist adding a lot of useful constructs to the language I have some influence over because I think that every feature hurts the language a bit by adding complexity. So for every feature the tough question isn't "is it useful" but "is it worth the price?" I don't have an answer for the borrow checker (and the answer also depends on the language's intended audience) but I don't think it's an obvious yes.
> The painfully constricting flexibility so reminiscent of C that everyone else clings to is not where I want to go back to.
That's not what I was talking about. When I use a low-level language, I use it not for what I would call flexibility, but for what I would call control. If Rust could give me safety in the parts I'm less interested in for "free", I wouldn't care about using unsafe Rust. The safe part would be pure bonus; not worth a whole lot, but I'll gladly take it. But that's not what's happening. To support safety in the safe subset, Rust is so complicated that I pay the price whether I get to enjoy that safety or not.
I think that for the safe parts, Rust would have been better off using some flavour of non-moving GC because interop between full-control low-level code and non-moving GC isn't too hard (whether tracing or refcounting; it doesn't matter all that much), which would have kept the safe part simpler. Maybe it would have looked more like Swift.