[ty] fix panic when attempting to infer the variance of a PEP-695 class that depends on a recursive type aliases and also somehow protocols (#21778)

Fixes https://github.com/astral-sh/ty/issues/1716.

## Test plan

I added a corpus snippet that causes us to panic on `main` (I tested by
running `cargo run -p ty_python_semantic --test=corpus` without the fix
applied).
This commit is contained in:
Alex Waygood 2025-12-03 19:01:42 +00:00 committed by GitHub
parent c722f498fe
commit 0280949000
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 1 deletions

View File

@ -0,0 +1,14 @@
from typing import Protocol
class A(Protocol):
@property
def f(self): ...
type Recursive = int | tuple[Recursive, ...]
class B[T: A]: ...
class C[T: A](A):
x: tuple[Recursive, ...]
class D(B[C]): ...

View File

@ -340,9 +340,18 @@ impl<'db> From<GenericAlias<'db>> for Type<'db> {
} }
} }
fn variance_of_cycle_initial<'db>(
_db: &'db dyn Db,
_id: salsa::Id,
_self: GenericAlias<'db>,
_typevar: BoundTypeVarInstance<'db>,
) -> TypeVarVariance {
TypeVarVariance::Bivariant
}
#[salsa::tracked] #[salsa::tracked]
impl<'db> VarianceInferable<'db> for GenericAlias<'db> { impl<'db> VarianceInferable<'db> for GenericAlias<'db> {
#[salsa::tracked(heap_size=ruff_memory_usage::heap_size)] #[salsa::tracked(heap_size=ruff_memory_usage::heap_size, cycle_initial=variance_of_cycle_initial)]
fn variance_of(self, db: &'db dyn Db, typevar: BoundTypeVarInstance<'db>) -> TypeVarVariance { fn variance_of(self, db: &'db dyn Db, typevar: BoundTypeVarInstance<'db>) -> TypeVarVariance {
let origin = self.origin(db); let origin = self.origin(db);