Rust doesn't have guaranteed TCE, so it's not canonical to write things that way because they tend to stack-overflow in debug. It'll probably happen eventually as an opt-in guarantee; it comes up periodically https://github.com/rust-lang/rfcs/pull/81https://github.com/rust-lang/rfcs/pull/1888 (Of course, LLVM will often to tail call optimization in release mode when it's profitable.)
That said, here's a post I can reuse from a while back: