mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 21:34:57 +00:00
[ty] add support for cyclic legacy generic protocols (#20125)
## Summary Just add the necessary Salsa cycle handling. ## Test Plan Added mdtest.
This commit is contained in:
parent
f4362b95d7
commit
9363eeca26
2 changed files with 41 additions and 1 deletions
|
@ -2339,6 +2339,28 @@ class Bar(Protocol[S]):
|
||||||
z: S | Bar[S]
|
z: S | Bar[S]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Recursive legacy generic protocol
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing import Generic, TypeVar, Protocol
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
class P(Protocol[T]):
|
||||||
|
attr: "P[T] | T"
|
||||||
|
|
||||||
|
class A(Generic[T]):
|
||||||
|
attr: T
|
||||||
|
|
||||||
|
class B(A[P[int]]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def f(b: B):
|
||||||
|
reveal_type(b) # revealed: B
|
||||||
|
reveal_type(b.attr) # revealed: P[int]
|
||||||
|
reveal_type(b.attr.attr) # revealed: P[int] | int
|
||||||
|
```
|
||||||
|
|
||||||
### Recursive generic protocols with property members
|
### Recursive generic protocols with property members
|
||||||
|
|
||||||
An early version of <https://github.com/astral-sh/ruff/pull/19936> caused stack overflows on this
|
An early version of <https://github.com/astral-sh/ruff/pull/19936> caused stack overflows on this
|
||||||
|
|
|
@ -5964,7 +5964,7 @@ impl<'db> Type<'db> {
|
||||||
/// Note that this does not specialize generic classes, functions, or type aliases! That is a
|
/// Note that this does not specialize generic classes, functions, or type aliases! That is a
|
||||||
/// different operation that is performed explicitly (via a subscript operation), or implicitly
|
/// different operation that is performed explicitly (via a subscript operation), or implicitly
|
||||||
/// via a call to the generic object.
|
/// via a call to the generic object.
|
||||||
#[salsa::tracked(heap_size=ruff_memory_usage::heap_size)]
|
#[salsa::tracked(heap_size=ruff_memory_usage::heap_size, cycle_fn=apply_specialization_cycle_recover, cycle_initial=apply_specialization_cycle_initial)]
|
||||||
pub(crate) fn apply_specialization(
|
pub(crate) fn apply_specialization(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
|
@ -6610,6 +6610,24 @@ impl<'db> VarianceInferable<'db> for Type<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn apply_specialization_cycle_recover<'db>(
|
||||||
|
_db: &'db dyn Db,
|
||||||
|
_value: &Type<'db>,
|
||||||
|
_count: u32,
|
||||||
|
_self: Type<'db>,
|
||||||
|
_specialization: Specialization<'db>,
|
||||||
|
) -> salsa::CycleRecoveryAction<Type<'db>> {
|
||||||
|
salsa::CycleRecoveryAction::Iterate
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_specialization_cycle_initial<'db>(
|
||||||
|
_db: &'db dyn Db,
|
||||||
|
_self: Type<'db>,
|
||||||
|
_specialization: Specialization<'db>,
|
||||||
|
) -> Type<'db> {
|
||||||
|
Type::Never
|
||||||
|
}
|
||||||
|
|
||||||
/// A mapping that can be applied to a type, producing another type. This is applied inductively to
|
/// A mapping that can be applied to a type, producing another type. This is applied inductively to
|
||||||
/// the components of complex types.
|
/// the components of complex types.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue