Skip to content

Commit 9f8c78d

Browse files
committed
Fix equality narrowing
1 parent 23d3a74 commit 9f8c78d

File tree

2 files changed

+12
-2
lines changed
  • crates/ty_python_semantic

2 files changed

+12
-2
lines changed

crates/ty_python_semantic/resources/mdtest/narrow/conditionals/eq.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ def _(answer: Answer):
3737
if answer != Answer.NO:
3838
reveal_type(answer) # revealed: Literal[Answer.YES]
3939
else:
40-
# TODO: This should be `Literal[Answer.NO]`
41-
reveal_type(answer) # revealed: Answer
40+
reveal_type(answer) # revealed: Literal[Answer.NO]
4241
```
4342

4443
This narrowing behavior is only safe if the enum has no custom `__eq__`/`__ne__` method:

crates/ty_python_semantic/src/types/narrow.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::semantic_index::place_table;
55
use crate::semantic_index::predicate::{
66
CallableAndCallExpr, PatternPredicate, PatternPredicateKind, Predicate, PredicateNode,
77
};
8+
use crate::types::enums::{enum_member_literals, enum_metadata};
89
use crate::types::function::KnownFunction;
910
use crate::types::infer::infer_same_file_expression_type;
1011
use crate::types::{
@@ -559,6 +560,16 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
559560
.map(|ty| filter_to_cannot_be_equal(db, ty, rhs_ty)),
560561
)
561562
}
563+
// Treat enums as a union of their members.
564+
Type::NominalInstance(instance)
565+
if enum_metadata(db, instance.class.class_literal(db).0).is_some() =>
566+
{
567+
UnionType::from_elements(
568+
db,
569+
enum_member_literals(db, instance.class.class_literal(db).0, None)
570+
.map(|ty| filter_to_cannot_be_equal(db, ty, rhs_ty)),
571+
)
572+
}
562573
_ => {
563574
if ty.is_single_valued(db) && !could_compare_equal(db, ty, rhs_ty) {
564575
ty

0 commit comments

Comments
 (0)