Perhaps, after you've been programming as long as I have-- (since 1979 when I coded z80 assembler on my TRS-80 I got after painting my parents' cottage, lol)-- you learn what you thought was abnormal at one time can surprise you in its normality once you run into the problems that make it the elegant solution. I tend to believe it is the problems you solve that dictate normality, not the strategies you use to solve them.
A point where you make a call into a deeply recursive function where it is known that only stack allocations (i.e. not heap) will occur represents a point in the code to which it may be desirable to return control when a certain condition is met and at an arbitrary depth in the recursive call tree. And you may need to do so as efficiently as possible, and avoid the overhead of a return and frame adjustment at each call point. Hypothetically speaking now, as a formal part of the language, it's possible that an artifact could be introduced (analogous to lifetimes) with which the compiler could make use for generating an optimal execution path. (I'm not proposing this, but I introduce it as just a thought experiment to illustrate an idea.)
To gain some historical perspective it's useful to consider Lisp, which has been around longer than C and many constructs that modern languages like to boast as their best features were first implemented in Lisp. To that end we find that common Lisp (CL) has a longjmp like construct called "tag-body and throw" which solves the problem I mention elegantly. Having to unwind the stack in order to restore (or rollback) the execution flow is a real problem, worth solving and optimizing for, and is far more than what you are characterizing as the "mother of all gotos."
That said, Prolog, as a fundamental part of the language has a built-in feature called back tracking which automatically generates "return points" to which execution must resume more efficiently than an unwind of each call would be desirable. This is, again, because it solves a problem produced by deep recursion.
Rust declares itself as a systems programming language and that says to me (for good or bad) that I would ideally like to use it to replace C in all cases. Therefore the problem landscape is very coarse and offers many hurdles to which the best solution, you may, at first glance, deem abnormal, but later a reasonable one.
I may be wrong of course, but if in doubt I would prefer to do what I can do in C rather than some other-- perhaps more "normally" viewed conventional approach that could be more expensive performance-wise. My current focus is Genetic Programming, after than I hope to create a WAM (Prolog abstract machine) in Rust and ejecting stack accumulated artifacts more efficiently than a call-by-call rewiind will likely be a "problem" to solve at some point.