Every time I implement an interpreter with recursion, I regret it.
As soon as I want TCO, or userland control of stack limits, or resumable exceptions, I need my own stack.
This is awkward because it's an upfront design decision. Changing the stack model is a big refactoring.
Most of the code I write is in a garbage collected language.
I'm often surprised how much extra performance I can get when I can control allocations. I saved ~10% runtime in difftastic by moving to a zero-allocation colour library (owo_colours)!
Adding LLVM control flow integrity to make exploits harder is coming to Rust:
https://rcvalle.com/docs/rust-cfi-design-doc.pdf
The primary use case is mixing C/C++ with Rust: you have weaker memory safety guarantees and hardening is still necessary. You don't want a partial Rust port to reduce security!