-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[ty] Expansion of enums into unions of literals #19382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
Lint rule | Added | Removed | Changed |
---|---|---|---|
invalid-argument-type |
0 | 6 | 0 |
invalid-return-type |
0 | 2 | 0 |
possibly-unresolved-reference |
0 | 2 | 0 |
Total | 0 | 10 | 0 |
CodSpeed Instrumentation Performance ReportMerging #19382 will not alter performanceComparing Summary
|
07faf92
to
7351142
Compare
9f8c78d
to
d8ada59
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only got to reviewing the tests so far, but the tests look great!
crates/ty_python_semantic/resources/mdtest/type_properties/is_equivalent_to.md
Outdated
Show resolved
Hide resolved
// Note: we manually construct a `UnionType` here instead of going through | ||
// `UnionBuilder` because we would simplify the union to just the enum instance | ||
// and end up in this branch again. | ||
let db = self.db; | ||
self.add_positive(Type::Union(UnionType::new( | ||
db, | ||
enum_member_literals(db, instance.class.class_literal(db).0, None) | ||
.collect::<Box<[_]>>(), | ||
))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, that's clever!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially, I duplicated what the Type::Union
branch does here, but wanted to get rid of that. Fortunately, the wrapping/unwrapping in UnionType
doesn't appear to hurt, performance-wise.
* main: (76 commits) Move fix suggestion to subdiagnostic (#19464) [ty] Implement non-stdlib stub mapping for classes and functions (#19471) [ty] Disallow illegal uses of `ClassVar` (#19483) [ty] Disallow `Final` in function parameter/return-type annotations (#19480) [ty] Extend `Final` test suite (#19476) [ty] Minor change to diagnostic message for invalid Literal uses (#19482) [ty] Detect illegal non-enum attribute accesses in Literal annotation (#19477) [ty] Reduce size of `TypeInference` (#19435) Run MD tests for Markdown-only changes (#19479) Revert "[ty] Detect illegal non-enum attribute accesses in Literal annotation" [ty] Detect illegal non-enum attribute accesses in Literal annotation [ty] Added semantic token support for more identifiers (#19473) [ty] Make tuple subclass constructors sound (#19469) [ty] Pass down specialization to generic dataclass bases (#19472) [ty] Garbage-collect reachability constraints (#19414) [ty] Implicit instance attributes declared `Final` (#19462) [ty] Expansion of enums into unions of literals (#19382) [ty] Avoid rechecking the entire project when changing the opened files (#19463) [ty] Add warning for unknown `TY_MEMORY_REPORT` value (#19465) [ty] Sync vendored typeshed stubs (#19461) ...
Summary
Implement expansion of enums into unions of enum literals (and the reverse operation). For the enum below, this allows us to understand that
Color = Literal[Color.RED, Color.GREEN, Color.BLUE]
, or thatColor & ~Literal[Color.RED] = Literal[Color.GREEN, Color.BLUE]
. This helps in exhaustiveness checking, which is why we see some removedassert_never
false positives. And since exhaustiveness checking also helps with understanding terminal control flow, we also see a few removedinvalid-return-type
andpossibly-unresolved-reference
false positives. This PR also adds expansion of enums in overload resolution and type narrowing constructs.Performance
I avoided an initial regression here for large enums, but the
UnionBuilder
andIntersectionBuilder
parts can certainly still be optimized. We might want to use the same technique that we also use for unions of other literals. I didn't see any problems in our benchmarks so far, so this is not included yet.Test Plan
Many new Markdown tests