TypeName is intended to uniquely identify a fully-resolved type, such that it can be used to reliably relate type references within a schema. However, a generic type will have the same type name for all concrete instantiations, violating this requirement.
The correct solution here is to take generic parameters into account in some way. A simple solution would be to include an additional list of the type TypeName values for each generic parameter. This would allow TypeName to be as deeply-nested as needed in order to fully identify the type. For example, TypeName would change to something like:
pub struct TypeName {
pub name: Cow<'static, str>,
pub module: Cow<'static, str>,
pub type_params: Vec<TypeName>,
}
My only reservation with this approach is that getting the TypeName for a type would no longer be a const-compatible operation, since it requires populating a Vec. In practice, though, I don't think we need creating a TypeName value to be a const operation, and none of the places where we currently create a TypeName value would be broken by the change.
In making this change, we will probably need to add a type_name method on the Describe trait. In order to get the fully-resolved name and module for type parameters, we can't just use the type_name! macro since it can't resolve the module of external types.