mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 05:14:52 +00:00
[ty] add cycle detection for find_legacy_typevars (#20124)
## Summary Add cycle detection to the `find_legacy_typevars` type method. ## Test Plan Added mdtest that stack overflowed without this.
This commit is contained in:
parent
f703536977
commit
f4362b95d7
11 changed files with 188 additions and 102 deletions
|
@ -217,6 +217,26 @@ def f(x: IntOr, y: OrInt):
|
||||||
reveal_type(y) # revealed: Never
|
reveal_type(y) # revealed: Never
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### With legacy generic
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
type Alias = list["Alias"] | int
|
||||||
|
|
||||||
|
class A(Generic[T]):
|
||||||
|
attr: T
|
||||||
|
|
||||||
|
class B(A[Alias]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def f(b: B):
|
||||||
|
reveal_type(b) # revealed: B
|
||||||
|
reveal_type(b.attr) # revealed: list[Alias] | int
|
||||||
|
```
|
||||||
|
|
||||||
### Mutually recursive
|
### Mutually recursive
|
||||||
|
|
||||||
```py
|
```py
|
||||||
|
|
|
@ -19,7 +19,7 @@ use ruff_text_size::{Ranged, TextRange};
|
||||||
use type_ordering::union_or_intersection_elements_ordering;
|
use type_ordering::union_or_intersection_elements_ordering;
|
||||||
|
|
||||||
pub(crate) use self::builder::{IntersectionBuilder, UnionBuilder};
|
pub(crate) use self::builder::{IntersectionBuilder, UnionBuilder};
|
||||||
pub(crate) use self::cyclic::{PairVisitor, TypeTransformer};
|
pub(crate) use self::cyclic::{CycleDetector, PairVisitor, TypeTransformer};
|
||||||
pub use self::diagnostic::TypeCheckDiagnostics;
|
pub use self::diagnostic::TypeCheckDiagnostics;
|
||||||
pub(crate) use self::diagnostic::register_lints;
|
pub(crate) use self::diagnostic::register_lints;
|
||||||
pub(crate) use self::infer::{
|
pub(crate) use self::infer::{
|
||||||
|
@ -191,6 +191,10 @@ pub(crate) struct IsDisjoint;
|
||||||
pub(crate) type IsEquivalentVisitor<'db, C> = PairVisitor<'db, IsEquivalent, C>;
|
pub(crate) type IsEquivalentVisitor<'db, C> = PairVisitor<'db, IsEquivalent, C>;
|
||||||
pub(crate) struct IsEquivalent;
|
pub(crate) struct IsEquivalent;
|
||||||
|
|
||||||
|
/// A [`CycleDetector`] for `find_legacy_typevars` methods.
|
||||||
|
pub(crate) type FindLegacyTypeVarsVisitor<'db> = CycleDetector<FindLegacyTypeVars, Type<'db>, ()>;
|
||||||
|
pub(crate) struct FindLegacyTypeVars;
|
||||||
|
|
||||||
/// A [`TypeTransformer`] that is used in `normalized` methods.
|
/// A [`TypeTransformer`] that is used in `normalized` methods.
|
||||||
pub(crate) type NormalizedVisitor<'db> = TypeTransformer<'db, Normalized>;
|
pub(crate) type NormalizedVisitor<'db> = TypeTransformer<'db, Normalized>;
|
||||||
pub(crate) struct Normalized;
|
pub(crate) struct Normalized;
|
||||||
|
@ -503,17 +507,18 @@ impl<'db> PropertyInstanceType<'db> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_legacy_typevars(
|
fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
if let Some(ty) = self.getter(db) {
|
if let Some(ty) = self.getter(db) {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
if let Some(ty) = self.setter(db) {
|
if let Some(ty) = self.setter(db) {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6157,6 +6162,21 @@ impl<'db> Type<'db> {
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
) {
|
||||||
|
self.find_legacy_typevars_impl(
|
||||||
|
db,
|
||||||
|
binding_context,
|
||||||
|
typevars,
|
||||||
|
&FindLegacyTypeVarsVisitor::default(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn find_legacy_typevars_impl(
|
||||||
|
self,
|
||||||
|
db: &'db dyn Db,
|
||||||
|
binding_context: Option<Definition<'db>>,
|
||||||
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
Type::NonInferableTypeVar(bound_typevar) | Type::TypeVar(bound_typevar) => {
|
Type::NonInferableTypeVar(bound_typevar) | Type::TypeVar(bound_typevar) => {
|
||||||
|
@ -6171,80 +6191,94 @@ impl<'db> Type<'db> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::FunctionLiteral(function) => {
|
Type::FunctionLiteral(function) => {
|
||||||
function.find_legacy_typevars(db, binding_context, typevars);
|
function.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::BoundMethod(method) => {
|
Type::BoundMethod(method) => {
|
||||||
method
|
method.self_instance(db).find_legacy_typevars_impl(
|
||||||
.self_instance(db)
|
db,
|
||||||
.find_legacy_typevars(db, binding_context, typevars);
|
binding_context,
|
||||||
method
|
typevars,
|
||||||
.function(db)
|
visitor,
|
||||||
.find_legacy_typevars(db, binding_context, typevars);
|
);
|
||||||
|
method.function(db).find_legacy_typevars_impl(
|
||||||
|
db,
|
||||||
|
binding_context,
|
||||||
|
typevars,
|
||||||
|
visitor,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::MethodWrapper(
|
Type::MethodWrapper(
|
||||||
MethodWrapperKind::FunctionTypeDunderGet(function)
|
MethodWrapperKind::FunctionTypeDunderGet(function)
|
||||||
| MethodWrapperKind::FunctionTypeDunderCall(function),
|
| MethodWrapperKind::FunctionTypeDunderCall(function),
|
||||||
) => {
|
) => {
|
||||||
function.find_legacy_typevars(db, binding_context, typevars);
|
function.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::MethodWrapper(
|
Type::MethodWrapper(
|
||||||
MethodWrapperKind::PropertyDunderGet(property)
|
MethodWrapperKind::PropertyDunderGet(property)
|
||||||
| MethodWrapperKind::PropertyDunderSet(property),
|
| MethodWrapperKind::PropertyDunderSet(property),
|
||||||
) => {
|
) => {
|
||||||
property.find_legacy_typevars(db, binding_context, typevars);
|
property.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Callable(callable) => {
|
Type::Callable(callable) => {
|
||||||
callable.find_legacy_typevars(db, binding_context, typevars);
|
callable.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::PropertyInstance(property) => {
|
Type::PropertyInstance(property) => {
|
||||||
property.find_legacy_typevars(db, binding_context, typevars);
|
property.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Union(union) => {
|
Type::Union(union) => {
|
||||||
for element in union.elements(db) {
|
for element in union.elements(db) {
|
||||||
element.find_legacy_typevars(db, binding_context, typevars);
|
element.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Type::Intersection(intersection) => {
|
Type::Intersection(intersection) => {
|
||||||
for positive in intersection.positive(db) {
|
for positive in intersection.positive(db) {
|
||||||
positive.find_legacy_typevars(db, binding_context, typevars);
|
positive.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
for negative in intersection.negative(db) {
|
for negative in intersection.negative(db) {
|
||||||
negative.find_legacy_typevars(db, binding_context, typevars);
|
negative.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::GenericAlias(alias) => {
|
Type::GenericAlias(alias) => {
|
||||||
alias.find_legacy_typevars(db, binding_context, typevars);
|
alias.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::NominalInstance(instance) => {
|
Type::NominalInstance(instance) => {
|
||||||
instance.find_legacy_typevars(db, binding_context, typevars);
|
instance.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::ProtocolInstance(instance) => {
|
Type::ProtocolInstance(instance) => {
|
||||||
instance.find_legacy_typevars(db, binding_context, typevars);
|
instance.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::SubclassOf(subclass_of) => {
|
Type::SubclassOf(subclass_of) => {
|
||||||
subclass_of.find_legacy_typevars(db, binding_context, typevars);
|
subclass_of.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::TypeIs(type_is) => {
|
Type::TypeIs(type_is) => {
|
||||||
type_is
|
type_is.return_type(db).find_legacy_typevars_impl(
|
||||||
.return_type(db)
|
db,
|
||||||
.find_legacy_typevars(db, binding_context, typevars);
|
binding_context,
|
||||||
|
typevars,
|
||||||
|
visitor,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::TypeAlias(alias) => {
|
Type::TypeAlias(alias) => {
|
||||||
alias
|
visitor.visit(self, || {
|
||||||
.value_type(db)
|
alias.value_type(db).find_legacy_typevars_impl(
|
||||||
.find_legacy_typevars(db, binding_context, typevars);
|
db,
|
||||||
|
binding_context,
|
||||||
|
typevars,
|
||||||
|
visitor,
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Dynamic(_)
|
Type::Dynamic(_)
|
||||||
|
@ -8907,14 +8941,15 @@ impl<'db> CallableType<'db> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_legacy_typevars(
|
fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
self.signatures(db)
|
self.signatures(db)
|
||||||
.find_legacy_typevars(db, binding_context, typevars);
|
.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check whether this callable type has the given relation to another callable type.
|
/// Check whether this callable type has the given relation to another callable type.
|
||||||
|
|
|
@ -30,11 +30,11 @@ use crate::types::tuple::{TupleSpec, TupleType};
|
||||||
use crate::types::typed_dict::typed_dict_params_from_class_def;
|
use crate::types::typed_dict::typed_dict_params_from_class_def;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
ApplyTypeMappingVisitor, Binding, BoundSuperError, BoundSuperType, CallableType,
|
ApplyTypeMappingVisitor, Binding, BoundSuperError, BoundSuperType, CallableType,
|
||||||
DataclassParams, DeprecatedInstance, HasRelationToVisitor, IsEquivalentVisitor,
|
DataclassParams, DeprecatedInstance, FindLegacyTypeVarsVisitor, HasRelationToVisitor,
|
||||||
KnownInstanceType, ManualPEP695TypeAliasType, MaterializationKind, NormalizedVisitor,
|
IsEquivalentVisitor, KnownInstanceType, ManualPEP695TypeAliasType, MaterializationKind,
|
||||||
PropertyInstanceType, StringLiteralType, TypeAliasType, TypeMapping, TypeRelation,
|
NormalizedVisitor, PropertyInstanceType, StringLiteralType, TypeAliasType, TypeMapping,
|
||||||
TypeVarBoundOrConstraints, TypeVarInstance, TypeVarKind, TypedDictParams, VarianceInferable,
|
TypeRelation, TypeVarBoundOrConstraints, TypeVarInstance, TypeVarKind, TypedDictParams,
|
||||||
declaration_type, infer_definition_types, todo_type,
|
VarianceInferable, declaration_type, infer_definition_types, todo_type,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
Db, FxIndexMap, FxOrderSet, Program,
|
Db, FxIndexMap, FxOrderSet, Program,
|
||||||
|
@ -303,14 +303,15 @@ impl<'db> GenericAlias<'db> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn find_legacy_typevars(
|
pub(super) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
self.specialization(db)
|
self.specialization(db)
|
||||||
.find_legacy_typevars(db, binding_context, typevars);
|
.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn is_typed_dict(self, db: &'db dyn Db) -> bool {
|
pub(super) fn is_typed_dict(self, db: &'db dyn Db) -> bool {
|
||||||
|
@ -503,15 +504,18 @@ impl<'db> ClassType<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn find_legacy_typevars(
|
pub(super) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
Self::NonGeneric(_) => {}
|
Self::NonGeneric(_) => {}
|
||||||
Self::Generic(generic) => generic.find_legacy_typevars(db, binding_context, typevars),
|
Self::Generic(generic) => {
|
||||||
|
generic.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,3 +90,9 @@ impl<Tag, T: Hash + Eq + Clone, R: Clone> CycleDetector<Tag, T, R> {
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Tag, T: Hash + Eq + Clone, R: Default + Clone> Default for CycleDetector<Tag, T, R> {
|
||||||
|
fn default() -> Self {
|
||||||
|
CycleDetector::new(R::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -78,9 +78,9 @@ use crate::types::signatures::{CallableSignature, Signature};
|
||||||
use crate::types::visitor::any_over_type;
|
use crate::types::visitor::any_over_type;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
BoundMethodType, BoundTypeVarInstance, CallableType, ClassBase, ClassLiteral, ClassType,
|
BoundMethodType, BoundTypeVarInstance, CallableType, ClassBase, ClassLiteral, ClassType,
|
||||||
DeprecatedInstance, DynamicType, HasRelationToVisitor, IsEquivalentVisitor, KnownClass,
|
DeprecatedInstance, DynamicType, FindLegacyTypeVarsVisitor, HasRelationToVisitor,
|
||||||
NormalizedVisitor, SpecialFormType, Truthiness, Type, TypeMapping, TypeRelation, UnionBuilder,
|
IsEquivalentVisitor, KnownClass, NormalizedVisitor, SpecialFormType, Truthiness, Type,
|
||||||
all_members, walk_type_mapping,
|
TypeMapping, TypeRelation, UnionBuilder, all_members, walk_type_mapping,
|
||||||
};
|
};
|
||||||
use crate::{Db, FxOrderSet, ModuleName, resolve_module};
|
use crate::{Db, FxOrderSet, ModuleName, resolve_module};
|
||||||
|
|
||||||
|
@ -915,15 +915,16 @@ impl<'db> FunctionType<'db> {
|
||||||
self_signature.is_equivalent_to_impl(db, other_signature, visitor)
|
self_signature.is_equivalent_to_impl(db, other_signature, visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn find_legacy_typevars(
|
pub(crate) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
let signatures = self.signature(db);
|
let signatures = self.signature(db);
|
||||||
for signature in &signatures.overloads {
|
for signature in &signatures.overloads {
|
||||||
signature.find_legacy_typevars(db, binding_context, typevars);
|
signature.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,10 @@ use crate::types::instance::{Protocol, ProtocolInstanceType};
|
||||||
use crate::types::signatures::{Parameter, Parameters, Signature};
|
use crate::types::signatures::{Parameter, Parameters, Signature};
|
||||||
use crate::types::tuple::{TupleSpec, TupleType, walk_tuple_type};
|
use crate::types::tuple::{TupleSpec, TupleType, walk_tuple_type};
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
ApplyTypeMappingVisitor, BoundTypeVarInstance, HasRelationToVisitor, IsEquivalentVisitor,
|
ApplyTypeMappingVisitor, BoundTypeVarInstance, FindLegacyTypeVarsVisitor, HasRelationToVisitor,
|
||||||
KnownClass, KnownInstanceType, MaterializationKind, NormalizedVisitor, Type, TypeMapping,
|
IsEquivalentVisitor, KnownClass, KnownInstanceType, MaterializationKind, NormalizedVisitor,
|
||||||
TypeRelation, TypeVarBoundOrConstraints, TypeVarInstance, TypeVarVariance, UnionType,
|
Type, TypeMapping, TypeRelation, TypeVarBoundOrConstraints, TypeVarInstance, TypeVarVariance,
|
||||||
binding_type, declaration_type,
|
UnionType, binding_type, declaration_type,
|
||||||
};
|
};
|
||||||
use crate::{Db, FxOrderSet};
|
use crate::{Db, FxOrderSet};
|
||||||
|
|
||||||
|
@ -888,14 +888,15 @@ impl<'db> Specialization<'db> {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn find_legacy_typevars(
|
pub(crate) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
for ty in self.types(db) {
|
for ty in self.types(db) {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
// A tuple's specialization will include all of its element types, so we don't need to also
|
// A tuple's specialization will include all of its element types, so we don't need to also
|
||||||
// look in `self.tuple`.
|
// look in `self.tuple`.
|
||||||
|
|
|
@ -12,9 +12,9 @@ use crate::types::enums::is_single_member_enum;
|
||||||
use crate::types::protocol_class::walk_protocol_interface;
|
use crate::types::protocol_class::walk_protocol_interface;
|
||||||
use crate::types::tuple::{TupleSpec, TupleType};
|
use crate::types::tuple::{TupleSpec, TupleType};
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
ApplyTypeMappingVisitor, ClassBase, HasRelationToVisitor, IsDisjointVisitor,
|
ApplyTypeMappingVisitor, ClassBase, FindLegacyTypeVarsVisitor, HasRelationToVisitor,
|
||||||
IsEquivalentVisitor, MaterializationKind, NormalizedVisitor, TypeMapping, TypeRelation,
|
IsDisjointVisitor, IsEquivalentVisitor, MaterializationKind, NormalizedVisitor, TypeMapping,
|
||||||
VarianceInferable,
|
TypeRelation, VarianceInferable,
|
||||||
};
|
};
|
||||||
use crate::{Db, FxOrderSet};
|
use crate::{Db, FxOrderSet};
|
||||||
|
|
||||||
|
@ -380,18 +380,19 @@ impl<'db> NominalInstanceType<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn find_legacy_typevars(
|
pub(super) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
NominalInstanceInner::ExactTuple(tuple) => {
|
NominalInstanceInner::ExactTuple(tuple) => {
|
||||||
tuple.find_legacy_typevars(db, binding_context, typevars);
|
tuple.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
NominalInstanceInner::NonTuple(class) => {
|
NominalInstanceInner::NonTuple(class) => {
|
||||||
class.find_legacy_typevars(db, binding_context, typevars);
|
class.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,18 +615,19 @@ impl<'db> ProtocolInstanceType<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn find_legacy_typevars(
|
pub(super) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
Protocol::FromClass(class) => {
|
Protocol::FromClass(class) => {
|
||||||
class.find_legacy_typevars(db, binding_context, typevars);
|
class.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
Protocol::Synthesized(synthesized) => {
|
Protocol::Synthesized(synthesized) => {
|
||||||
synthesized.find_legacy_typevars(db, binding_context, typevars);
|
synthesized.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -679,8 +681,8 @@ mod synthesized_protocol {
|
||||||
use crate::semantic_index::definition::Definition;
|
use crate::semantic_index::definition::Definition;
|
||||||
use crate::types::protocol_class::ProtocolInterface;
|
use crate::types::protocol_class::ProtocolInterface;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
ApplyTypeMappingVisitor, BoundTypeVarInstance, MaterializationKind, NormalizedVisitor,
|
ApplyTypeMappingVisitor, BoundTypeVarInstance, FindLegacyTypeVarsVisitor,
|
||||||
TypeMapping, TypeVarVariance, VarianceInferable,
|
MaterializationKind, NormalizedVisitor, TypeMapping, TypeVarVariance, VarianceInferable,
|
||||||
};
|
};
|
||||||
use crate::{Db, FxOrderSet};
|
use crate::{Db, FxOrderSet};
|
||||||
|
|
||||||
|
@ -724,13 +726,15 @@ mod synthesized_protocol {
|
||||||
Self(self.0.specialized_and_normalized(db, type_mapping))
|
Self(self.0.specialized_and_normalized(db, type_mapping))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn find_legacy_typevars(
|
pub(super) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
self.0.find_legacy_typevars(db, binding_context, typevars);
|
self.0
|
||||||
|
.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(in crate::types) fn interface(self) -> ProtocolInterface<'db> {
|
pub(in crate::types) fn interface(self) -> ProtocolInterface<'db> {
|
||||||
|
|
|
@ -17,10 +17,10 @@ use crate::{
|
||||||
place::{Boundness, Place, PlaceAndQualifiers, place_from_bindings, place_from_declarations},
|
place::{Boundness, Place, PlaceAndQualifiers, place_from_bindings, place_from_declarations},
|
||||||
semantic_index::{definition::Definition, use_def_map},
|
semantic_index::{definition::Definition, use_def_map},
|
||||||
types::{
|
types::{
|
||||||
BoundTypeVarInstance, CallableType, ClassBase, ClassLiteral, HasRelationToVisitor,
|
BoundTypeVarInstance, CallableType, ClassBase, ClassLiteral, FindLegacyTypeVarsVisitor,
|
||||||
IsDisjointVisitor, KnownFunction, MaterializationKind, NormalizedVisitor,
|
HasRelationToVisitor, IsDisjointVisitor, KnownFunction, MaterializationKind,
|
||||||
PropertyInstanceType, Signature, Type, TypeMapping, TypeQualifiers, TypeRelation,
|
NormalizedVisitor, PropertyInstanceType, Signature, Type, TypeMapping, TypeQualifiers,
|
||||||
VarianceInferable,
|
TypeRelation, VarianceInferable,
|
||||||
constraints::{Constraints, IteratorConstraintsExtension},
|
constraints::{Constraints, IteratorConstraintsExtension},
|
||||||
signatures::{Parameter, Parameters},
|
signatures::{Parameter, Parameters},
|
||||||
},
|
},
|
||||||
|
@ -289,14 +289,15 @@ impl<'db> ProtocolInterface<'db> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn find_legacy_typevars(
|
pub(super) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
for data in self.inner(db).values() {
|
for data in self.inner(db).values() {
|
||||||
data.find_legacy_typevars(db, binding_context, typevars);
|
data.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,14 +361,15 @@ impl<'db> ProtocolMemberData<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_legacy_typevars(
|
fn find_legacy_typevars_impl(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
self.kind
|
self.kind
|
||||||
.find_legacy_typevars(db, binding_context, typevars);
|
.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn materialize(&self, db: &'db dyn Db, materialization_kind: MaterializationKind) -> Self {
|
fn materialize(&self, db: &'db dyn Db, materialization_kind: MaterializationKind) -> Self {
|
||||||
|
@ -456,18 +458,19 @@ impl<'db> ProtocolMemberKind<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_legacy_typevars(
|
fn find_legacy_typevars_impl(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
ProtocolMemberKind::Method(callable) => {
|
ProtocolMemberKind::Method(callable) => {
|
||||||
callable.find_legacy_typevars(db, binding_context, typevars);
|
callable.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
ProtocolMemberKind::Property(property) => {
|
ProtocolMemberKind::Property(property) => {
|
||||||
property.find_legacy_typevars(db, binding_context, typevars);
|
property.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
ProtocolMemberKind::Other(ty) => {
|
ProtocolMemberKind::Other(ty) => {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars(db, binding_context, typevars);
|
||||||
|
|
|
@ -20,9 +20,9 @@ use crate::semantic_index::definition::Definition;
|
||||||
use crate::types::constraints::{Constraints, IteratorConstraintsExtension};
|
use crate::types::constraints::{Constraints, IteratorConstraintsExtension};
|
||||||
use crate::types::generics::{GenericContext, walk_generic_context};
|
use crate::types::generics::{GenericContext, walk_generic_context};
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
BindingContext, BoundTypeVarInstance, HasRelationToVisitor, IsEquivalentVisitor, KnownClass,
|
BindingContext, BoundTypeVarInstance, FindLegacyTypeVarsVisitor, HasRelationToVisitor,
|
||||||
MaterializationKind, NormalizedVisitor, TypeMapping, TypeRelation, VarianceInferable,
|
IsEquivalentVisitor, KnownClass, MaterializationKind, NormalizedVisitor, TypeMapping,
|
||||||
todo_type,
|
TypeRelation, VarianceInferable, todo_type,
|
||||||
};
|
};
|
||||||
use crate::{Db, FxOrderSet};
|
use crate::{Db, FxOrderSet};
|
||||||
use ruff_python_ast::{self as ast, name::Name};
|
use ruff_python_ast::{self as ast, name::Name};
|
||||||
|
@ -94,14 +94,15 @@ impl<'db> CallableSignature<'db> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn find_legacy_typevars(
|
pub(crate) fn find_legacy_typevars_impl(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
for signature in &self.overloads {
|
for signature in &self.overloads {
|
||||||
signature.find_legacy_typevars(db, binding_context, typevars);
|
signature.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,22 +468,23 @@ impl<'db> Signature<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn find_legacy_typevars(
|
pub(crate) fn find_legacy_typevars_impl(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
for param in &self.parameters {
|
for param in &self.parameters {
|
||||||
if let Some(ty) = param.annotated_type() {
|
if let Some(ty) = param.annotated_type() {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
if let Some(ty) = param.default_type() {
|
if let Some(ty) = param.default_type() {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(ty) = self.return_ty {
|
if let Some(ty) = self.return_ty {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,10 @@ use crate::semantic_index::definition::Definition;
|
||||||
use crate::types::constraints::Constraints;
|
use crate::types::constraints::Constraints;
|
||||||
use crate::types::variance::VarianceInferable;
|
use crate::types::variance::VarianceInferable;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
ApplyTypeMappingVisitor, BoundTypeVarInstance, ClassType, DynamicType, HasRelationToVisitor,
|
ApplyTypeMappingVisitor, BoundTypeVarInstance, ClassType, DynamicType,
|
||||||
IsDisjointVisitor, KnownClass, MaterializationKind, MemberLookupPolicy, NormalizedVisitor,
|
FindLegacyTypeVarsVisitor, HasRelationToVisitor, IsDisjointVisitor, KnownClass,
|
||||||
SpecialFormType, Type, TypeMapping, TypeRelation,
|
MaterializationKind, MemberLookupPolicy, NormalizedVisitor, SpecialFormType, Type, TypeMapping,
|
||||||
|
TypeRelation,
|
||||||
};
|
};
|
||||||
use crate::{Db, FxOrderSet};
|
use crate::{Db, FxOrderSet};
|
||||||
|
|
||||||
|
@ -111,15 +112,16 @@ impl<'db> SubclassOfType<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn find_legacy_typevars(
|
pub(super) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
match self.subclass_of {
|
match self.subclass_of {
|
||||||
SubclassOfInner::Class(class) => {
|
SubclassOfInner::Class(class) => {
|
||||||
class.find_legacy_typevars(db, binding_context, typevars);
|
class.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
SubclassOfInner::Dynamic(_) => {}
|
SubclassOfInner::Dynamic(_) => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,9 @@ use crate::types::Truthiness;
|
||||||
use crate::types::class::{ClassType, KnownClass};
|
use crate::types::class::{ClassType, KnownClass};
|
||||||
use crate::types::constraints::{Constraints, IteratorConstraintsExtension};
|
use crate::types::constraints::{Constraints, IteratorConstraintsExtension};
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
ApplyTypeMappingVisitor, BoundTypeVarInstance, HasRelationToVisitor, IsDisjointVisitor,
|
ApplyTypeMappingVisitor, BoundTypeVarInstance, FindLegacyTypeVarsVisitor, HasRelationToVisitor,
|
||||||
IsEquivalentVisitor, MaterializationKind, NormalizedVisitor, Type, TypeMapping, TypeRelation,
|
IsDisjointVisitor, IsEquivalentVisitor, MaterializationKind, NormalizedVisitor, Type,
|
||||||
UnionBuilder, UnionType,
|
TypeMapping, TypeRelation, UnionBuilder, UnionType,
|
||||||
};
|
};
|
||||||
use crate::util::subscript::{Nth, OutOfBoundsError, PyIndex, PySlice, StepSizeZeroError};
|
use crate::util::subscript::{Nth, OutOfBoundsError, PyIndex, PySlice, StepSizeZeroError};
|
||||||
use crate::{Db, FxOrderSet, Program};
|
use crate::{Db, FxOrderSet, Program};
|
||||||
|
@ -250,14 +250,15 @@ impl<'db> TupleType<'db> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn find_legacy_typevars(
|
pub(crate) fn find_legacy_typevars_impl(
|
||||||
self,
|
self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
self.tuple(db)
|
self.tuple(db)
|
||||||
.find_legacy_typevars(db, binding_context, typevars);
|
.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn has_relation_to_impl<C: Constraints<'db>>(
|
pub(crate) fn has_relation_to_impl<C: Constraints<'db>>(
|
||||||
|
@ -414,14 +415,15 @@ impl<'db> FixedLengthTuple<Type<'db>> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_legacy_typevars(
|
fn find_legacy_typevars_impl(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
for ty in &self.0 {
|
for ty in &self.0 {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,19 +747,20 @@ impl<'db> VariableLengthTuple<Type<'db>> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_legacy_typevars(
|
fn find_legacy_typevars_impl(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
for ty in &self.prefix {
|
for ty in &self.prefix {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
self.variable
|
self.variable
|
||||||
.find_legacy_typevars(db, binding_context, typevars);
|
.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
for ty in &self.suffix {
|
for ty in &self.suffix {
|
||||||
ty.find_legacy_typevars(db, binding_context, typevars);
|
ty.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,15 +1102,20 @@ impl<'db> Tuple<Type<'db>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_legacy_typevars(
|
fn find_legacy_typevars_impl(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
binding_context: Option<Definition<'db>>,
|
binding_context: Option<Definition<'db>>,
|
||||||
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
typevars: &mut FxOrderSet<BoundTypeVarInstance<'db>>,
|
||||||
|
visitor: &FindLegacyTypeVarsVisitor<'db>,
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
Tuple::Fixed(tuple) => tuple.find_legacy_typevars(db, binding_context, typevars),
|
Tuple::Fixed(tuple) => {
|
||||||
Tuple::Variable(tuple) => tuple.find_legacy_typevars(db, binding_context, typevars),
|
tuple.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
|
}
|
||||||
|
Tuple::Variable(tuple) => {
|
||||||
|
tuple.find_legacy_typevars_impl(db, binding_context, typevars, visitor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue