There should be an easy way for users to control where panics may or may not happen. Being a Systems Language™, some of Rust’s use cases simply cannot afford panic at all.
What if it was simply
#[no_panic]
fn main() { ... }
C++11 has noexcept, meaning no exception will bubble up from the call. Since panics cannot be caught, this would be recursive for Rust.
There are performance considerations as well. Scott Meyers, Effective Modern C++:
The difference between unwinding the call stack and possibly unwinding it has a surprisingly large impact on code generation. In a noexcept function, optimizers need not keep the runtime stack in an unwindable state if an exception would propagate out of the function, nor must they ensure that objects in a noexcept function are destroyed in the inverse order of construction should an exception leave the function.
unsafe should be allowed, a recursive restriction would not be useful without it. (The verdict for purity was kill it with fire). As always, unsafe means the compiler cannot prove the code’s correctness, it should be looked at early and often, don’t use it if you don’t want to crash etc.
We might end up with two sets of functions for everything, but in this case, I don’t see that as a bad thing.