[ty] Ensure that T is disjoint from ~T even when T is a TypeVar (#17922)

Same as https://github.com/astral-sh/ruff/pull/17910 but for
disjointness
This commit is contained in:
Alex Waygood 2025-05-07 18:59:16 +01:00 committed by GitHub
parent 74fe7982ba
commit 895b6161a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 11 additions and 5 deletions

View file

@ -345,11 +345,10 @@ def inter[T: Base, U: (Base, Unrelated)](t: T, u: U) -> None:
static_assert(is_assignable_to(Intersection[U, A], U))
static_assert(is_subtype_of(Intersection[U, A], U))
# TODO: these should pass
static_assert(is_disjoint_from(Not[T], T)) # error: [static-assert-error]
static_assert(is_disjoint_from(T, Not[T])) # error: [static-assert-error]
static_assert(is_disjoint_from(Not[U], U)) # error: [static-assert-error]
static_assert(is_disjoint_from(U, Not[U])) # error: [static-assert-error]
static_assert(is_disjoint_from(Not[T], T))
static_assert(is_disjoint_from(T, Not[T]))
static_assert(is_disjoint_from(Not[U], U))
static_assert(is_disjoint_from(U, Not[U]))
```
## Equivalence

View file

@ -1643,6 +1643,13 @@ impl<'db> Type<'db> {
false
}
(tvar @ Type::TypeVar(_), Type::Intersection(intersection))
| (Type::Intersection(intersection), tvar @ Type::TypeVar(_))
if intersection.negative(db).contains(&tvar) =>
{
true
}
// An unbounded typevar is never disjoint from any other type, since it might be
// specialized to any type. A bounded typevar is not disjoint from its bound, and is
// only disjoint from other types if its bound is. A constrained typevar is disjoint