Creation-time expressions must not overflow.
If we allowed an expression overload, or a builtin overload with mixed abstract and concrete types, then we could end up in a situation where that expression would have to be evaluated at runtime.
Example: 100 << x where x is a runtime i32 value.
If we had an AbstractInt << i32 overload, then the 100 stays as AbstractInt, and we have no idea whether 100 << x would overflow.
So we can't have that overload, and therefore force the 100 to materialize to an 100i value in i32.
Overloads are chosen only by parameter types, so either both operands to << should be abstract, or both operands should be concrete.
There are a few cases in the spec where operands to a builtin are differently constrained, and when adding abstract numeric types we accidentally allowed mixture of abstract and concrete.
This happens with:
Creation-time expressions must not overflow.
If we allowed an expression overload, or a builtin overload with mixed abstract and concrete types, then we could end up in a situation where that expression would have to be evaluated at runtime.
Example:
100 << xwherexis a runtime i32 value.If we had an
AbstractInt << i32overload, then the100stays as AbstractInt, and we have no idea whether100 << xwould overflow.So we can't have that overload, and therefore force the 100 to materialize to an 100i value in i32.
Overloads are chosen only by parameter types, so either both operands to << should be abstract, or both operands should be concrete.
There are a few cases in the spec where operands to a builtin are differently constrained, and when adding abstract numeric types we accidentally allowed mixture of abstract and concrete.
This happens with: