I get that occasionally it's important to know the exact order, and this is where tighter rules and tooling can help. Rust wasn't designed to be an "everything is as explicit as possible" language. (Neither is C, for that matter, ever since compilers stopped paying attention to the "register" keyword…)
That is, it's less about order and more about bookkeeping. The ergonomics directly affect code quality.
Part of the pain would come from conditionals:
if something {
func(val1);
} else {
func(val2);
}
This would be disallowed because the liveness of val1 and val2 can't be statically known after the conditional.This is indeed "pain", but of a good kind (at least it if the error message is decent).
I admit there are harder cases:
if(foo)
func(val1)
else
func(val2)
... do something that doesn't change foo or use val1, val2
...
if(!foo)
func(val1)
else
func(val2)
Is correct, if strange, code which I assume is hard for a compiler to understand. But then it is hard for humans too.That makes the "trivialness" of a destructor part of the interface, which is a price. But then from my experience in C++, we pay that price anyway, because to have any sort of assurance about what you are doing, you need some clue about what the destructor does.
In terms of understanding how the code will execute or testing your app, the implicit, confusing rules are less "ergonomic".
(Yes, GCs require tuning and so forth, and that can be a pain, but so does malloc and free, so that's a wash. In most applications you never need to manually tune a GC.)