not familiar with compiler internals, so i'm not sure how feasible this is, but i realized that with a single magic macro we could make rust generics basically as powerful as zig comptime.
the argument would be a const expression that evaluates to a TypeId, and it would expand to a magic type expression corresponding to the type of a TypeId.
this would be a huge extension to the rust language, but it would be interesting as a compiler experiment.
TypeId is currently a one directional 128-bit hash of type information. However, the compiler does maintain a map of generated TypeIds to ensure no accidental collisions happen (within a statically linked unit), so it would be theoretically possible to go from TypeId back to type. I don't see how it helps the expressive power of generics, though. Namely, a significant part of the expressive power of Zig's comptime is that they're syntactic templates that do name resolution after substitution of the comptime arguments, whereas Rust generics, even if we extend const generics to allow TypeId, are checked before instantiation and must be well formed for any and all instantiation that satisfies the trait bounds.
The compiler does not store any tables of type ids today, collisions are prevented by using a 128-bit hash.
Adding such a table wouldn't necessarily be impossible, but it would quite tricky to do with the compilers query structure I think.
When I was looking into compile time macros. What I did was create a derive macro that for a given T: Reflect will invoke a (const) method on that type, and that TypeInfo will contain all the info needed to construct a full descriptor of value. But to achieve that, I ran into problems:
You can't define a (although you can resort to type hackery and make a impl Foo { const fn typeinfo() -> TypeInfo {...} })
trait Reflect {
const fn reflect() -> TypeInfo
}
making it non-composable.
It's not possible to construct an enum from Discriminant, even if it's possible to extract.
If I recall correctly, there were some issues with functions being essentially variable argument generics, i.e. heterogeneous lists, while having no way to express that in code.
I think this could be done for associated types and consts, basically turning a TypeId const into the output type. Though it'd require a mono-time error if the computed type doesn't fulfill the bounds.
for example, a Vec type with an opaque capacity could remove the capacity and heap pointer fields altogether when instantiated with a ZST, and just track the length field.