When programming Ada my thought process is relatively close to C (but with proper modules and generics). From what little Rust I've used, it was more like an ML—specifically more usage of higher-order functions and discriminated unions (which Ada supports, but is 100x less convenient than ML, but still 10x better than C's struct { enum { } what; union { } val; }; pattern).
In general, memory management is more manual in Ada than in Rust as well. Actually, Ada is technically less safe than Rust since you can use Ada.Unchecked_Deallocate to circumvent the accessibility checker and Ada doesn't have an equivalent of the unsafe { } block. But you almost always use RAII and memory pools and Unchecked_Deallocate for C types gets hidden in a RAII wrapper. Additionally, fat pointers are opt-in (though roughly as inconvenient as thin pointers), which can be useful for very low-level code. I believe Rust's pointers are always fat?
Also I went ahead and checked Rust performance again. I didn't realize you'd gotten so fast. Ada, like FORTRAN, does not allow pointer aliasing by default (there's an ‘aliased’ type qualifier though), so theoretically it can generate faster-than-C. Embarrassingly I don't actually know how alias analysis works in Rust, so maybe you have this advantage too.
One thing that you may not realize, talking about HOF and such: LLVM is very good at compiling them down. If you use a closure that doesn't actually close over anything, it will get turned into a regular old function, for example. Which means it can be inlined...
Rust pointers are not always fat. Slices are, but &T is a regular old pointer, as far as the assembly goes.
&mut T automatically gets `restrict` applied to it, basically, we do a lot of aliasing stuff as well.
Thanks for elaborating :) I should spend some time with Ada.
It also has support for hardware interrupts and real time programming.