It's not a bug, that's the expected behavior, let me explain why.
First It doesn't cast in the order you mentioned, from the docs:
- If the type of the right operand can be implicitly converted to the type of the left operand, use the type of the left operand,
- if the type of the left operand can be implicitly converted to the type of the right operand, use the type of the right operand,
- otherwise, the operation is not allowed.
If we apply this to your code,
a is a type of uint16 with max value 65535
, 0.001 ether
has no explicit type, the compiler will implicitly give it the smallest datatype it accepts i.e uint56 with a max value of 72057594037927935
.
Now we have uint16 and uint56 and the value of multiplying 1000
with 0.001 ether
is 1000000000000000000
which is a type of uint64.
Let's back to the docs and see where our case fits,
- (try the left operand type on the right operand ) fails because the result is higher than uint16
- (try the right operand type on the left operand ) fails because the result is higher than uint56
The operation is not allowed so it reverts.