[red-knot] don't emit divide-by-zero error if we can't be sure (#13799)

If the LHS is just `int` or `float` type, that type includes custom
subclasses which can arbitrarily override division behavior, so we
shouldn't emit a divide-by-zero error in those cases.

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Carl Meyer 2024-10-17 10:11:07 -07:00 committed by GitHub
parent 5e6de4e0c6
commit 5c537b6dbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 13 additions and 5 deletions

View file

@ -21,12 +21,23 @@ reveal_type(f) # revealed: Literal[2]
## Division by Zero
```py
class MyInt(int):
def __truediv__(self, other):
return 100
def returns_int() -> int:
return MyInt(3)
# TODO: `a` should be `int` and `e` should be `float` once we support inference.
a = 1 / 0 # error: "Cannot divide object of type `Literal[1]` by zero"
b = 2 // 0 # error: "Cannot floor divide object of type `Literal[2]` by zero"
c = 3 % 0 # error: "Cannot reduce object of type `Literal[3]` modulo zero"
d = int() / 0 # error: "Cannot divide object of type `int` by zero"
e = 1.0 / 0 # error: "Cannot divide object of type `float` by zero"
# even `int` type could be a subclass of `int` with custom behavior; no error
d = returns_int() / 0
# this could be flagged as an error, if we had an ExactFloat or ExactInstance
# type, but given only a `float` type we can't issue an error for the same
# reason: could be a custom float subclass
e = 1.0 / 0
reveal_type(a) # revealed: float
reveal_type(b) # revealed: int

View file

@ -540,9 +540,6 @@ impl<'db> TypeInferenceBuilder<'db> {
fn check_division_by_zero(&mut self, expr: &ast::ExprBinOp, left: Type<'db>) {
match left {
Type::IntLiteral(_) => {}
Type::Instance(cls)
if cls.is_known(self.db, KnownClass::Float)
|| cls.is_known(self.db, KnownClass::Int) => {}
_ => return,
};