diff --git a/crates/ty_python_semantic/resources/mdtest/binary/booleans.md b/crates/ty_python_semantic/resources/mdtest/binary/booleans.md index 1e62ce8920..6bfca0ecce 100644 --- a/crates/ty_python_semantic/resources/mdtest/binary/booleans.md +++ b/crates/ty_python_semantic/resources/mdtest/binary/booleans.md @@ -45,6 +45,18 @@ reveal_type(a | a) # revealed: Literal[True] reveal_type(a | b) # revealed: Literal[True] reveal_type(b | a) # revealed: Literal[True] reveal_type(b | b) # revealed: Literal[False] + +# bitwise AND +reveal_type(a & a) # revealed: Literal[True] +reveal_type(a & b) # revealed: Literal[False] +reveal_type(b & a) # revealed: Literal[False] +reveal_type(b & b) # revealed: Literal[False] + +# bitwise XOR +reveal_type(a ^ a) # revealed: Literal[False] +reveal_type(a ^ b) # revealed: Literal[True] +reveal_type(b ^ a) # revealed: Literal[True] +reveal_type(b ^ b) # revealed: Literal[False] ``` ## Arithmetic with a variable diff --git a/crates/ty_python_semantic/resources/mdtest/binary/integers.md b/crates/ty_python_semantic/resources/mdtest/binary/integers.md index dcbc180317..d7e920ed0e 100644 --- a/crates/ty_python_semantic/resources/mdtest/binary/integers.md +++ b/crates/ty_python_semantic/resources/mdtest/binary/integers.md @@ -9,6 +9,9 @@ reveal_type(3 * -1) # revealed: Literal[-3] reveal_type(-3 // 3) # revealed: Literal[-1] reveal_type(-3 / 3) # revealed: float reveal_type(5 % 3) # revealed: Literal[2] +reveal_type(3 | 4) # revealed: Literal[7] +reveal_type(5 & 6) # revealed: Literal[4] +reveal_type(7 ^ 2) # revealed: Literal[5] # error: [unsupported-operator] "Operator `+` is unsupported between objects of type `Literal[2]` and `Literal["f"]`" reveal_type(2 + "f") # revealed: Unknown diff --git a/crates/ty_python_semantic/src/types/infer.rs b/crates/ty_python_semantic/src/types/infer.rs index acc379cf85..628d385402 100644 --- a/crates/ty_python_semantic/src/types/infer.rs +++ b/crates/ty_python_semantic/src/types/infer.rs @@ -5773,6 +5773,18 @@ impl<'db> TypeInferenceBuilder<'db> { } }), + (Type::IntLiteral(n), Type::IntLiteral(m), ast::Operator::BitOr) => { + Some(Type::IntLiteral(n | m)) + } + + (Type::IntLiteral(n), Type::IntLiteral(m), ast::Operator::BitAnd) => { + Some(Type::IntLiteral(n & m)) + } + + (Type::IntLiteral(n), Type::IntLiteral(m), ast::Operator::BitXor) => { + Some(Type::IntLiteral(n ^ m)) + } + (Type::BytesLiteral(lhs), Type::BytesLiteral(rhs), ast::Operator::Add) => { let bytes = [&**lhs.value(self.db()), &**rhs.value(self.db())].concat(); Some(Type::bytes_literal(self.db(), &bytes)) @@ -5828,6 +5840,14 @@ impl<'db> TypeInferenceBuilder<'db> { Some(Type::BooleanLiteral(b1 | b2)) } + (Type::BooleanLiteral(b1), Type::BooleanLiteral(b2), ast::Operator::BitAnd) => { + Some(Type::BooleanLiteral(b1 & b2)) + } + + (Type::BooleanLiteral(b1), Type::BooleanLiteral(b2), ast::Operator::BitXor) => { + Some(Type::BooleanLiteral(b1 ^ b2)) + } + (Type::BooleanLiteral(bool_value), right, op) => self.infer_binary_expression_type( node, emitted_division_by_zero_diagnostic,