ponyc
ponyc copied to clipboard
Lexer can't catch `let x = I64(1) / I64(0)` as divide by zero
let x: I64 = 1 /0 will result in a compilation error but let x = I64(1) / I64(0) and other types will not.
I64(0) is not a special syntax, but really just a constructor call which helps type inference.
Are you suggesting we special case this if the divisor is a primitive constructor? I guess it should be recursive, so that let x = I64(1) / I64(I64(0)) gets caught too.
Special-casing that smells bad to me, tbh.
I'm tempted to argue that the "right" way to fix this inconsistency is to remove the lexer error for let x: I64 = 1 /0 - it's inconsistent that we have a lexer error for some cases that are obvious at compile time, but can't ferret out every case outside of runtime.
It's hard to imagine someone "accidentally" dividing by a literal zero in the source code - so this error feels to me like it's there for vanity reasons and isn't actually being helpful to anyone. On the contrary, it may actually be harmful by lulling users into a false sense of security - the presence of this error may lead them to believe that we can also protect them from non-trivial divide-by-zero cases, which we can't.
Also, for better or worse, the standard division operator is defined as a non-partial function in Pony, and dividing by zero using that operator is a valid operation. It's not clear to me why we'd want a lexer error to outlaw a valid function invocation.
When we add partial arithmetic operators in #2865, that will give users an option to error at runtime for divide-by-zero, which is the only time at which it can be guaranteed to be detected in Pony.