- deterministic memory management
- actual generics. :P
- an advanced type system (vs. java/c++)
- design choices taken towards efficiency
- default-immutable memory
The elevator pitch is "Speed of C++, safety of ML, concurrency of Erlang."
Did you mean something other than combinators?
For example, above, you mention how TCO lets you use first-class functions to help you eliminate mutability. It's the elimination of mutability that's the safety here. Rust allows you to eliminate mutability through other means.
So support for tail calls is not about safety but expressiveness, and Rust chooses to express iterative algorithms through other means, such as the iteration protocol that's built on top of higher-order functions.
EDIT: Maybe I'm misreading you and you only mean the imperative nature of loops forces you to use mutation. Rust does not eschew mutation altogether. Even as a functional programmer myself, I'd argue pretty emphatically that mutation, particularly of local variables, is not a grave safety concern.
(Is concision really what you lose when you need explicit looping constructs? Maybe "abstraction capability"?)
For some use cases (games, web browsers, etc) the first goal is much more important than the second.