Something can only live (exclusively) in the type system if everything about it can be reified away. It's the same trade-off as in polymorphic container types: Either the type is tracked at runtime (a-la Java), or the code is instantiated per-type (a-la C++).
In the context of allocators, Zig essentially requires that the programmer perform per-allocator instantiation while writing the code. Odin does the opposite, and requires that the information is held by the allocated object. I am unfamiliar with Rust's approach, but it will be either via runtime tracking, or via instantiation.