Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[red-knot] add IntersectionBuilder (#12791)
For type narrowing, we'll need intersections (since applying type narrowing is just a type intersection.) Add `IntersectionBuilder`, along with some tests for it and `UnionBuilder` (renamed from `UnionTypeBuilder`). 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 a `Type::Union` (e.g. if you only add a single type to the union, it'll just return that type instead), and `IntersectionBuilder` doesn't necessarily build a `Type::Intersection` (if you add a union to the intersection, we distribute the intersection over that union, and `IntersectionBuilder` will end up returning a `Type::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.
- Loading branch information