I think the restriction really has to do with “input” types, right? Still, it seems like eventually we are going to want to permit floating point types (and indeed arbitrary types) as the values of constants. It also seems quite natural to me that we would want a very strict notion of equality when it comes to instantiating impls and so forth.
Note that we can be extra conservative around floating point values, in order to sidestep annoying questions like whether two distinct NaN bitpatterns are equal. In particular, we could require that two floating point values are only considered “equal” if they derive from the same constant.
Actually, this is an interesting question. I’m assuming that if you had
const C: u32 = 0;
const D: u32 = 0;
we would want [T; C] and [T; D] to be the same type, right? This isn’t entirely obvious (since you might not want your code to stop working when D changes value, for example), but I think it’s already true anyhow so we can’t really avoid it.
I guess that puts us in a bit of a bind in that one might expect the same behavior with floating point constants (e.g., Foo<C> and Foo<D> are the same type, where C and D have type f32 instead).
Well, maybe it’s trickier than I thought! Still, I imagine we are going to have to cross this bridge at some point. Personally I think I would be inclined to say that two floating point values are considered equal for our purposes if they are bitwise equal or both are NaN (I’m not a floating point expert, but I think that values like 0 and -0 have a unique bitpattern, right?).