Well, the reason you gave are valid, but it also highly depends on the task at hand. You say AAA game engines are the most complex programs you can think of .... I raise you production-grade compilers, and those benefits enormously from complex type systems.
Also, it's sometimes possible to use high-flying type trickeries in a local way that is not directly visible to the outside, but highly increase the safety inside a library.
In all cases, Rust is probably the first language which both has a type system rich enough to start doing advanced type trickery and the capacity for fine-grained control over memory layout. I know they have a fairly vibrant gamedev community but I don't know the details. Do they use all the fancy things such as phantom types, complex traits, and all that?
The most complex program I can think of surely has to be something like Facebook. It’s like a 4 GB executable isn’t it? I don’t think compilers are that large or complicated.
The Facebook mobile application sure is large, but I wager lots of that is assets and repeated code. Even so, there is lots of code there anyway (someone dove into that at some point), but I think that's a "different kind" of complexity than, say, a compiler. There's lots of complex user interfaces to set up and work with, and there's some amount of user state to keep track of; but a compiler has to perform highly complicated operations on a large, intricate state that can often be described effectively with a strong type system.
I'm inclined to believe a compiler is better suited for a type system like Haskell's than e.g. a mobile app or a game engine is, but maybe someone with more domain knowledge might correct me here.
What do you consider to be the minimum for advanced type trickery? I ask to see if Ada might fit that criteria and and what features it might be lacking that would make it competitive with Rust in the type-trickery domain.
As far as I'm concerned, the minimal is sum, products and, most importantly, abstract parametric datatypes. This is sufficient for phantom types, and then the fun starts. More complex parametric types (with ad-hoc polymorphism for example) then extends what you can do.
Also, it's sometimes possible to use high-flying type trickeries in a local way that is not directly visible to the outside, but highly increase the safety inside a library.
In all cases, Rust is probably the first language which both has a type system rich enough to start doing advanced type trickery and the capacity for fine-grained control over memory layout. I know they have a fairly vibrant gamedev community but I don't know the details. Do they use all the fancy things such as phantom types, complex traits, and all that?