Casting to Collection loses the static type info, so you couldn't write foo(bar(set)) if bar returned a Collection but foo accepted a Set.
Not a Rust guy but I think that's the idea.
not only container types, it can be any type that has a consistent context of evaluation for the final value being calculated: "doing async IO", "doing optional presence", "doing potentially erroneous extraction", and so on. In that sense, "doing multiplicity of values" is the context expressing a container type you mentioned as an example.
You could be 100% right (I have no idea, but it sounds reasonable), but this entire question really hits home that Rust has tons of basically incomprehensible design features.
The worst part about features like this are that a few smart people will actually use them (whether because they're powerful features, or just because they feel powerful when using them), and then render their code incomprehensible to the mere mortals who have to support their code in the future.
The KISS principle (https://en.wikipedia.org//wiki/KISS_principle) is sometimes ignored because people don't want to be stupid, and why wouldn't you want to use a new toy(tool) once you've figured it out?
Furthermore, the amount of hand-wringing over this feature is disproportionate to its actual impact. It feels like people see "Haskell" mentioned in the same breath and immediately lose all sense of reason. This feature is not basically incomprehensible, it's a straightforward addition that allows generics to be used with associated types, both of which are features that already exist in the language.
If you're asking yourself, "when would I ever need to use these?", this answer is that you may never find call to use these. Traits are mechanisms for creating abstractions, which are mostly relevant to library authors. If you're not a library author, you may never have a good reason to write a trait. Even for people who are writing traits, they may have no reason to ever use associated types. And even for people who are writing traits with associated types, they may have no reason to ever want to use generics with those associated types.
However, all of these features are extremely useful for the people consuming libraries, and far from making Rust code more complicated, from what I've seen so far it makes Rust code in the wild less complicated.
The question is do we inhibit the wise to protect us from the unwise? The answer might be yes. I enjoy learning about power features so I hope not.
Rust has made it years without needing this (granted, a few things have been less than ideal because of it) because, for the most part, people have not needed to reach for this type of abstraction. But it's really just "Generics in a new place".
Personally, I've accidentally written the GAT syntax years before I ever heard the term GAT because I thought a generic could go there.
For libraries like Hyper, which prioritize being extremely generic (it's split into a ton of reusable crates), which aims to serve as a very low level set of generic primitives for HTTP, yes it will come up.
Hyper is a great example of a use case that 99.99% of developers are not going to be able to relate to because they aren't building a set of completely generic http primitives. It's an important use case, it's just not relatable.
Suppose you have a concrete type like
Regular generics enable you to make the contained type generic, so you have: where T can be i32, u32, String, etc. GATs allow you to make the container generic. So you can have: where T might be Vec, Option, Box, etc.