[red-knot] Ensure differently ordered unions are considered equivalent when they appear inside tuples inside top-level intersections (#15743)

This commit is contained in:
Alex Waygood
2025-01-25 18:19:28 +00:00
committed by GitHub
parent f85ea1bf46
commit c824140fa8
2 changed files with 34 additions and 4 deletions

View File

@@ -106,4 +106,16 @@ static_assert(
)
```
## Intersections containing tuples containing unions
```py
from knot_extensions import is_equivalent_to, static_assert, Intersection
class P: ...
class Q: ...
class R: ...
static_assert(is_equivalent_to(Intersection[tuple[P | Q], R], Intersection[tuple[Q | P], R]))
```
[the equivalence relation]: https://typing.readthedocs.io/en/latest/spec/glossary.html#term-equivalent

View File

@@ -4516,21 +4516,33 @@ impl<'db> IntersectionType<'db> {
}
let self_positive = self.positive(db);
if !all_fully_static(db, self_positive) {
return false;
}
let self_negative = self.negative(db);
if !all_fully_static(db, self_negative) {
let other_positive = other.positive(db);
if self_positive.len() != other_positive.len() {
return false;
}
let other_positive = other.positive(db);
if !all_fully_static(db, other_positive) {
return false;
}
let self_negative = self.negative(db);
if !all_fully_static(db, self_negative) {
return false;
}
let other_negative = other.negative(db);
if self_negative.len() != other_negative.len() {
return false;
}
if !all_fully_static(db, other_negative) {
return false;
}
@@ -4539,7 +4551,13 @@ impl<'db> IntersectionType<'db> {
return true;
}
self_positive.set_eq(other_positive) && self_negative.set_eq(other_negative)
let sorted_self = self.to_sorted_intersection(db);
if sorted_self == other {
return true;
}
sorted_self == other.to_sorted_intersection(db)
}
/// Return `true` if `self` has exactly the same set of possible static materializations as `other`