Most of the other criticisms are pretty disappointing, though.
> The following example is a famous illustration of how it can't properly reason across branches, either:
Except that function body would have been better rewritten as map.entry(key).or_default() -- which passes the borrow checker just fine and is more performant as it avoids multiple lookups. I suspect many other examples would benefit from being re-written into higher-level primitives that can be easier to borrow-check in this manner.
> But what's the point of the rules in this case, though? Here, the ownership rules does not prevent use after free, or double free, or data races, or any other bug. It's perfectly clear to a human that this code is fine and doesn't have any actual ownership issues.
What if Id represents a file descriptor that ought to be closed when the value ceases to exist? Or some other type of handle? This is an ownership problem: these are not limited to memory safety issues. For very good API stability reasons, without an explicit #[derive(Clone,Copy)] the compiler is not free to assume the type represents pure information that can be copied at will, but can only treat it as one potentially containing owned resources, that just happens not to include any at this time.
> References to temporary values, e.g. values created in a closure, are forbidden even though it's obvious to a human that the solution is simply to extend the lifetime of the value to its use outside the closure.
Which is to say, to what? The type signature does not say whether a closure will be called immediately or in another thread after two hours. And in which stack frame should the value be stored, the soon-to-be-exiting closure's?