When code aborts, you don't have to reason about it in calling code. When you decide to abort, you are not just suggesting that there might be a problem. You are asserting "nope, there is no reasonable way I can continue here." Which is exactly what task failure is supposed to be used for, incidentally (which is why it was renamed to panic!)--normal, expected error conditions that you can actually do something useful about should be handled through the type system, not propagated through code that might not even be aware of its existence.
In the meantime, abort completely cleans up any in-process state--closing network pipes, deleting temporary files, deallocating mmaped memory, and so on. And what it can't clean up can't be relied on anyway, because programs can always be aborted unexpectedly in other ways. Whether it's the OOM killer, various Rust behavior that triggers abort (panicking during unwinding, for example), stack overflow, power loss, or just SIGKILL, a robust program can never rely on its destructors running anyway (and destructors failing to run is explicitly not part of Rust's definition of unsafe).
So ultimately, the reason abort is easier to reason about is that except in a few special cases (like embedded, where you may have complete control of the hardware--but you likely don't want to be using task failure there), your program already has to be designed to expect an abort at literally any time. Aborting may not always be desired behavior, but it never introduces additional cognitive load, or creates unsafety where it didn't already exist, in the way that exceptions do.
In the meantime, abort completely cleans up any in-process state--closing network pipes, deleting temporary files, deallocating mmaped memory, and so on. And what it can't clean up can't be relied on anyway, because programs can always be aborted unexpectedly in other ways. Whether it's the OOM killer, various Rust behavior that triggers abort (panicking during unwinding, for example), stack overflow, power loss, or just SIGKILL, a robust program can never rely on its destructors running anyway (and destructors failing to run is explicitly not part of Rust's definition of unsafe).
So ultimately, the reason abort is easier to reason about is that except in a few special cases (like embedded, where you may have complete control of the hardware--but you likely don't want to be using task failure there), your program already has to be designed to expect an abort at literally any time. Aborting may not always be desired behavior, but it never introduces additional cognitive load, or creates unsafety where it didn't already exist, in the way that exceptions do.