It does via memory pools, RAII (aka controlled types) and dynamic stack allocation.
It isn't truly safe like Rust, as Ada can still have dangling pointers laying around, the free function is called "Unchecked_Deallocation", not sure if newer Ada has any mechanisms for better ownership semantics.
Kinda sorta cheating. ;)