-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[red-knot] add IntersectionBuilder #12791
Conversation
|
(Have only skimmed so far; will look in more depth over the weekend or next week :-) |
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.
Overall this looks great. I love the builder interfaces.
Thanks for the great review! |
CodSpeed Performance ReportMerging #12791 will not alter performanceComparing Summary
|
1116ce4
to
a49a871
Compare
a49a871
to
106e2d8
Compare
For type narrowing, we'll need intersections (since applying type narrowing is just a type intersection.)
Add
IntersectionBuilder
, along with some tests for it andUnionBuilder
(renamed fromUnionTypeBuilder
).We use smart builders to ensure that we always keep these types in disjunctive normal form (DNF). That means that we never have deeply nested trees of unions and intersections: unions flatten into unions, intersections flatten into intersections, and intersections distribute over unions, so the most complex tree we can ever have is a union of intersections. We also never have a single-element union or a single-positive-element intersection; these both just simplify to the contained type.
Maintaining these invariants means that
UnionBuilder
doesn't necessarily end up building aType::Union
(e.g. if you only add a single type to the union, it'll just return that type instead), andIntersectionBuilder
doesn't necessarily build aType::Intersection
(if you add a union to the intersection, we distribute the intersection over that union, andIntersectionBuilder
will end up returning aType::Union
of intersections).We also simplify intersections by ensuring that if a type and its negation are both in an intersection, they simplify out. (In future this should also respect subtyping, not just type identity, but we don't have subtyping yet.) We do implement subtyping of
Never
as a special case for now.Most of this PR is unused for now until type narrowing lands; I'm just breaking it out to reduce the review fatigue of a single massive PR.