[ty] remove the `visitor` parameter in the `recursive_type_normalized_impl` method (#21701)

This commit is contained in:
Shunsuke Shibayama 2025-12-01 16:48:43 +09:00 committed by GitHub
parent 846df40a6e
commit a6cbc138d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 148 additions and 233 deletions

View File

@ -52,6 +52,10 @@ def f(x: A):
JSONPrimitive = Union[str, int, float, bool, None]
JSONValue = TypeAliasType("JSONValue", 'Union[JSONPrimitive, Sequence["JSONValue"], Mapping[str, "JSONValue"]]')
def _(x: JSONValue):
# TODO: should be `JSONValue`
reveal_type(x) # revealed: Divergent
```
## Self-referential legacy type variables

View File

@ -573,20 +573,19 @@ impl<'db> PropertyInstanceType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
let getter = match self.getter(db) {
Some(ty) if nested => Some(ty.recursive_type_normalized_impl(db, div, true, visitor)?),
Some(ty) if nested => Some(ty.recursive_type_normalized_impl(db, div, true)?),
Some(ty) => Some(
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div),
),
None => None,
};
let setter = match self.setter(db) {
Some(ty) if nested => Some(ty.recursive_type_normalized_impl(db, div, true, visitor)?),
Some(ty) if nested => Some(ty.recursive_type_normalized_impl(db, div, true)?),
Some(ty) => Some(
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div),
),
None => None,
@ -1553,15 +1552,14 @@ impl<'db> Type<'db> {
#[must_use]
pub(crate) fn recursive_type_normalized(self, db: &'db dyn Db, cycle: &salsa::Cycle) -> Self {
cycle.head_ids().fold(self, |ty, id| {
let visitor = NormalizedVisitor::new(Type::divergent(id));
ty.recursive_type_normalized_impl(db, Type::divergent(id), false, &visitor)
ty.recursive_type_normalized_impl(db, Type::divergent(id), false)
.unwrap_or(Type::divergent(id))
})
}
/// Normalizes types including divergent types (recursive types), which is necessary for convergence of fixed-point iteration.
/// When nested is true, propagate `None`. That is, if the type contains a `Divergent` type, the return value of this method is `None`.
/// When nested is false, create a type containing `Divergent` types instead of propagating `None`.
/// When `nested` is true, propagate `None`. That is, if the type contains a `Divergent` type, the return value of this method is `None` (so we can use the `?` operator).
/// When `nested` is false, create a type containing `Divergent` types instead of propagating `None` (we should use `unwrap_or(Divergent)`).
/// This is to preserve the structure of the non-divergent parts of the type instead of completely collapsing the type containing a `Divergent` type into a `Divergent` type.
/// ```python
/// tuple[tuple[Divergent, Literal[1]], Literal[1]].recursive_type_normalized(nested: false)
@ -1580,102 +1578,73 @@ impl<'db> Type<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
if nested && self == div {
return None;
}
match self {
Type::Union(union) => visitor.try_visit(self, || {
union.recursive_type_normalized_impl(db, div, nested, visitor)
}),
Type::Intersection(intersection) => visitor.try_visit(self, || {
intersection
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::Intersection)
}),
Type::Callable(callable) => visitor.try_visit(self, || {
callable
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::Callable)
}),
Type::ProtocolInstance(protocol) => visitor.try_visit(self, || {
protocol
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::ProtocolInstance)
}),
Type::NominalInstance(instance) => visitor.try_visit(self, || {
instance
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::NominalInstance)
}),
Type::FunctionLiteral(function) => visitor.try_visit(self, || {
function
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::FunctionLiteral)
}),
Type::PropertyInstance(property) => visitor.try_visit(self, || {
property
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::PropertyInstance)
}),
Type::KnownBoundMethod(method_kind) => visitor.try_visit(self, || {
method_kind
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::KnownBoundMethod)
}),
Type::BoundMethod(method) => visitor.try_visit(self, || {
method
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::BoundMethod)
}),
Type::BoundSuper(bound_super) => visitor.try_visit(self, || {
bound_super
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::BoundSuper)
}),
Type::GenericAlias(generic) => visitor.try_visit(self, || {
generic
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::GenericAlias)
}),
Type::SubclassOf(subclass_of) => visitor.try_visit(self, || {
subclass_of
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::SubclassOf)
}),
Type::Union(union) => union.recursive_type_normalized_impl(db, div, nested),
Type::Intersection(intersection) => intersection
.recursive_type_normalized_impl(db, div, nested)
.map(Type::Intersection),
Type::Callable(callable) => callable
.recursive_type_normalized_impl(db, div, nested)
.map(Type::Callable),
Type::ProtocolInstance(protocol) => protocol
.recursive_type_normalized_impl(db, div, nested)
.map(Type::ProtocolInstance),
Type::NominalInstance(instance) => instance
.recursive_type_normalized_impl(db, div, nested)
.map(Type::NominalInstance),
Type::FunctionLiteral(function) => function
.recursive_type_normalized_impl(db, div, nested)
.map(Type::FunctionLiteral),
Type::PropertyInstance(property) => property
.recursive_type_normalized_impl(db, div, nested)
.map(Type::PropertyInstance),
Type::KnownBoundMethod(method_kind) => method_kind
.recursive_type_normalized_impl(db, div, nested)
.map(Type::KnownBoundMethod),
Type::BoundMethod(method) => method
.recursive_type_normalized_impl(db, div, nested)
.map(Type::BoundMethod),
Type::BoundSuper(bound_super) => bound_super
.recursive_type_normalized_impl(db, div, nested)
.map(Type::BoundSuper),
Type::GenericAlias(generic) => generic
.recursive_type_normalized_impl(db, div, nested)
.map(Type::GenericAlias),
Type::SubclassOf(subclass_of) => subclass_of
.recursive_type_normalized_impl(db, div, nested)
.map(Type::SubclassOf),
Type::TypeVar(_) => Some(self),
Type::KnownInstance(known_instance) => visitor.try_visit(self, || {
known_instance
.recursive_type_normalized_impl(db, div, nested, visitor)
.map(Type::KnownInstance)
}),
Type::TypeIs(type_is) => visitor.try_visit(self, || {
Type::KnownInstance(known_instance) => known_instance
.recursive_type_normalized_impl(db, div, nested)
.map(Type::KnownInstance),
Type::TypeIs(type_is) => {
let ty = if nested {
type_is
.return_type(db)
.recursive_type_normalized_impl(db, div, true, visitor)?
.recursive_type_normalized_impl(db, div, true)?
} else {
type_is
.return_type(db)
.recursive_type_normalized_impl(db, div, true, visitor)
.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div)
};
Some(type_is.with_type(db, ty))
}),
}
Type::Dynamic(dynamic) => Some(Type::Dynamic(dynamic.recursive_type_normalized())),
Type::TypedDict(_) => {
// TODO: Normalize TypedDicts
Some(self)
}
Type::TypeAlias(_) => Some(self),
Type::NewTypeInstance(newtype) => visitor.try_visit(self, || {
newtype
Type::NewTypeInstance(newtype) => newtype
.try_map_base_class_type(db, |class_type| {
class_type.recursive_type_normalized_impl(db, div, nested, visitor)
class_type.recursive_type_normalized_impl(db, div, nested)
})
.map(Type::NewTypeInstance)
}),
.map(Type::NewTypeInstance),
Type::LiteralString
| Type::AlwaysFalsy
| Type::AlwaysTruthy
@ -8702,7 +8671,6 @@ impl<'db> KnownInstanceType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
match self {
// Nothing to normalize
@ -8712,37 +8680,37 @@ impl<'db> KnownInstanceType<'db> {
Self::ConstraintSet(set) => Some(Self::ConstraintSet(set)),
Self::TypeVar(typevar) => Some(Self::TypeVar(typevar)),
Self::TypeAliasType(type_alias) => type_alias
.recursive_type_normalized_impl(db, div, visitor)
.recursive_type_normalized_impl(db, div)
.map(Self::TypeAliasType),
Self::Field(field) => field
.recursive_type_normalized_impl(db, div, nested, visitor)
.recursive_type_normalized_impl(db, div, nested)
.map(Self::Field),
Self::UnionType(union_type) => union_type
.recursive_type_normalized_impl(db, div, nested, visitor)
.recursive_type_normalized_impl(db, div, nested)
.map(Self::UnionType),
Self::Literal(ty) => ty
.recursive_type_normalized_impl(db, div, true, visitor)
.recursive_type_normalized_impl(db, div, true)
.map(Self::Literal),
Self::Annotated(ty) => ty
.recursive_type_normalized_impl(db, div, true, visitor)
.recursive_type_normalized_impl(db, div, true)
.map(Self::Annotated),
Self::TypeGenericAlias(ty) => ty
.recursive_type_normalized_impl(db, div, true, visitor)
.recursive_type_normalized_impl(db, div, true)
.map(Self::TypeGenericAlias),
Self::LiteralStringAlias(ty) => ty
.recursive_type_normalized_impl(db, div, true, visitor)
.recursive_type_normalized_impl(db, div, true)
.map(Self::LiteralStringAlias),
Self::Callable(callable) => callable
.recursive_type_normalized_impl(db, div, nested, visitor)
.recursive_type_normalized_impl(db, div, nested)
.map(Self::Callable),
Self::NewType(newtype) => newtype
.try_map_base_class_type(db, |class_type| {
class_type.recursive_type_normalized_impl(db, div, true, visitor)
class_type.recursive_type_normalized_impl(db, div, true)
})
.map(Self::NewType),
Self::GenericContext(generic) => Some(Self::GenericContext(generic)),
Self::Specialization(specialization) => specialization
.recursive_type_normalized_impl(db, div, true, visitor)
.recursive_type_normalized_impl(db, div, true)
.map(Self::Specialization),
}
}
@ -9231,15 +9199,12 @@ impl<'db> FieldInstance<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
let default_type = match self.default_type(db) {
Some(default) if nested => {
Some(default.recursive_type_normalized_impl(db, div, true, visitor)?)
}
Some(default) if nested => Some(default.recursive_type_normalized_impl(db, div, true)?),
Some(default) => Some(
default
.recursive_type_normalized_impl(db, div, true, visitor)
.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div),
),
None => None,
@ -10184,7 +10149,6 @@ impl<'db> UnionTypeInstance<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
// The `Divergent` elimination rules are different within union types.
// See `UnionType::recursive_type_normalized_impl` for details.
@ -10192,14 +10156,14 @@ impl<'db> UnionTypeInstance<'db> {
Some(types) if nested => Some(
types
.iter()
.map(|ty| ty.recursive_type_normalized_impl(db, div, nested, visitor))
.map(|ty| ty.recursive_type_normalized_impl(db, div, nested))
.collect::<Option<Box<_>>>()?,
),
Some(types) => Some(
types
.iter()
.map(|ty| {
ty.recursive_type_normalized_impl(db, div, nested, visitor)
ty.recursive_type_normalized_impl(db, div, nested)
.unwrap_or(div)
})
.collect::<Box<_>>(),
@ -10207,9 +10171,9 @@ impl<'db> UnionTypeInstance<'db> {
None => None,
};
let union_type = match self.union_type(db).clone() {
Ok(ty) if nested => Ok(ty.recursive_type_normalized_impl(db, div, nested, visitor)?),
Ok(ty) if nested => Ok(ty.recursive_type_normalized_impl(db, div, nested)?),
Ok(ty) => Ok(ty
.recursive_type_normalized_impl(db, div, nested, visitor)
.recursive_type_normalized_impl(db, div, nested)
.unwrap_or(div)),
Err(err) => Err(err),
};
@ -10241,14 +10205,13 @@ impl<'db> InternedType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
let inner = if nested {
self.inner(db)
.recursive_type_normalized_impl(db, div, nested, visitor)?
.recursive_type_normalized_impl(db, div, nested)?
} else {
self.inner(db)
.recursive_type_normalized_impl(db, div, nested, visitor)
.recursive_type_normalized_impl(db, div, nested)
.unwrap_or(div)
};
Some(InternedType::new(db, inner))
@ -11560,14 +11523,13 @@ impl<'db> BoundMethodType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self::new(
db,
self.function(db)
.recursive_type_normalized_impl(db, div, nested, visitor)?,
.recursive_type_normalized_impl(db, div, nested)?,
self.self_instance(db)
.recursive_type_normalized_impl(db, div, true, visitor)?,
.recursive_type_normalized_impl(db, div, true)?,
))
}
@ -11732,12 +11694,11 @@ impl<'db> CallableType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(CallableType::new(
db,
self.signatures(db)
.recursive_type_normalized_impl(db, div, nested, visitor)?,
.recursive_type_normalized_impl(db, div, nested)?,
self.is_function_like(db),
))
}
@ -12175,27 +12136,26 @@ impl<'db> KnownBoundMethodType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
match self {
KnownBoundMethodType::FunctionTypeDunderGet(function) => {
Some(KnownBoundMethodType::FunctionTypeDunderGet(
function.recursive_type_normalized_impl(db, div, nested, visitor)?,
function.recursive_type_normalized_impl(db, div, nested)?,
))
}
KnownBoundMethodType::FunctionTypeDunderCall(function) => {
Some(KnownBoundMethodType::FunctionTypeDunderCall(
function.recursive_type_normalized_impl(db, div, nested, visitor)?,
function.recursive_type_normalized_impl(db, div, nested)?,
))
}
KnownBoundMethodType::PropertyDunderGet(property) => {
Some(KnownBoundMethodType::PropertyDunderGet(
property.recursive_type_normalized_impl(db, div, nested, visitor)?,
property.recursive_type_normalized_impl(db, div, nested)?,
))
}
KnownBoundMethodType::PropertyDunderSet(property) => {
Some(KnownBoundMethodType::PropertyDunderSet(
property.recursive_type_normalized_impl(db, div, nested, visitor)?,
property.recursive_type_normalized_impl(db, div, nested)?,
))
}
KnownBoundMethodType::StrStartswith(_)
@ -12858,18 +12818,14 @@ impl<'db> ManualPEP695TypeAliasType<'db> {
)
}
fn recursive_type_normalized_impl(
self,
db: &'db dyn Db,
div: Type<'db>,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
// TODO: with full support for manual PEP-695 style type aliases, this method should become unnecessary.
fn recursive_type_normalized_impl(self, db: &'db dyn Db, div: Type<'db>) -> Option<Self> {
Some(Self::new(
db,
self.name(db),
self.definition(db),
self.value(db)
.recursive_type_normalized_impl(db, div, true, visitor)?,
.recursive_type_normalized_impl(db, div, true)?,
))
}
}
@ -12914,16 +12870,11 @@ impl<'db> TypeAliasType<'db> {
}
}
fn recursive_type_normalized_impl(
self,
db: &'db dyn Db,
div: Type<'db>,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
fn recursive_type_normalized_impl(self, db: &'db dyn Db, div: Type<'db>) -> Option<Self> {
match self {
TypeAliasType::PEP695(type_alias) => Some(TypeAliasType::PEP695(type_alias)),
TypeAliasType::ManualPEP695(type_alias) => Some(TypeAliasType::ManualPEP695(
type_alias.recursive_type_normalized_impl(db, div, visitor)?,
type_alias.recursive_type_normalized_impl(db, div)?,
)),
}
}
@ -13248,7 +13199,6 @@ impl<'db> UnionType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Type<'db>> {
let mut builder = UnionBuilder::new(db)
.order_elements(false)
@ -13258,7 +13208,7 @@ impl<'db> UnionType<'db> {
for ty in self.elements(db) {
if nested {
// list[T | Divergent] => list[Divergent]
let ty = ty.recursive_type_normalized_impl(db, div, nested, visitor)?;
let ty = ty.recursive_type_normalized_impl(db, div, nested)?;
if ty == div {
return Some(ty);
}
@ -13271,7 +13221,7 @@ impl<'db> UnionType<'db> {
continue;
}
builder = builder.add(
ty.recursive_type_normalized_impl(db, div, nested, visitor)
ty.recursive_type_normalized_impl(db, div, nested)
.unwrap_or(div),
);
empty = false;
@ -13389,18 +13339,16 @@ impl<'db> IntersectionType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
fn opt_normalized_set<'db>(
db: &'db dyn Db,
elements: &FxOrderSet<Type<'db>>,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<FxOrderSet<Type<'db>>> {
elements
.iter()
.map(|ty| ty.recursive_type_normalized_impl(db, div, nested, visitor))
.map(|ty| ty.recursive_type_normalized_impl(db, div, nested))
.collect()
}
@ -13409,26 +13357,25 @@ impl<'db> IntersectionType<'db> {
elements: &FxOrderSet<Type<'db>>,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> FxOrderSet<Type<'db>> {
elements
.iter()
.map(|ty| {
ty.recursive_type_normalized_impl(db, div, nested, visitor)
ty.recursive_type_normalized_impl(db, div, nested)
.unwrap_or(div)
})
.collect()
}
let positive = if nested {
opt_normalized_set(db, self.positive(db), div, nested, visitor)?
opt_normalized_set(db, self.positive(db), div, nested)?
} else {
normalized_set(db, self.positive(db), div, nested, visitor)
normalized_set(db, self.positive(db), div, nested)
};
let negative = if nested {
opt_normalized_set(db, self.negative(db), div, nested, visitor)?
opt_normalized_set(db, self.negative(db), div, nested)?
} else {
normalized_set(db, self.negative(db), div, nested, visitor)
normalized_set(db, self.negative(db), div, nested)
};
Some(IntersectionType::new(db, positive, negative))
@ -13911,16 +13858,15 @@ pub(crate) mod tests {
nested_rec.display(&db).to_string(),
"list[list[Divergent] | None]"
);
let visitor = NormalizedVisitor::default();
let normalized = nested_rec
.recursive_type_normalized_impl(&db, div, false, &visitor)
.recursive_type_normalized_impl(&db, div, false)
.unwrap();
assert_eq!(normalized.display(&db).to_string(), "list[Divergent]");
let union = UnionType::from_elements(&db, [div, KnownClass::Int.to_instance(&db)]);
assert_eq!(union.display(&db).to_string(), "Divergent | int");
let normalized = union
.recursive_type_normalized_impl(&db, div, false, &visitor)
.recursive_type_normalized_impl(&db, div, false)
.unwrap();
assert_eq!(normalized.display(&db).to_string(), "int");

View File

@ -197,17 +197,16 @@ impl<'db> SuperOwnerKind<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
match self {
SuperOwnerKind::Dynamic(dynamic) => {
Some(SuperOwnerKind::Dynamic(dynamic.recursive_type_normalized()))
}
SuperOwnerKind::Class(class) => Some(SuperOwnerKind::Class(
class.recursive_type_normalized_impl(db, div, nested, visitor)?,
class.recursive_type_normalized_impl(db, div, nested)?,
)),
SuperOwnerKind::Instance(instance) => Some(SuperOwnerKind::Instance(
instance.recursive_type_normalized_impl(db, div, nested, visitor)?,
instance.recursive_type_normalized_impl(db, div, nested)?,
)),
}
}
@ -620,14 +619,13 @@ impl<'db> BoundSuperType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self::new(
db,
self.pivot_class(db)
.recursive_type_normalized_impl(db, div, nested, visitor)?,
.recursive_type_normalized_impl(db, div, nested)?,
self.owner(db)
.recursive_type_normalized_impl(db, div, nested, visitor)?,
.recursive_type_normalized_impl(db, div, nested)?,
))
}
}

View File

@ -284,13 +284,12 @@ impl<'db> GenericAlias<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self::new(
db,
self.origin(db),
self.specialization(db)
.recursive_type_normalized_impl(db, div, nested, visitor)?,
.recursive_type_normalized_impl(db, div, nested)?,
))
}
@ -443,12 +442,11 @@ impl<'db> ClassType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
match self {
Self::NonGeneric(_) => Some(self),
Self::Generic(generic) => Some(Self::Generic(
generic.recursive_type_normalized_impl(db, div, nested, visitor)?,
generic.recursive_type_normalized_impl(db, div, nested)?,
)),
}
}

View File

@ -48,12 +48,11 @@ impl<'db> ClassBase<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
match self {
Self::Dynamic(dynamic) => Some(Self::Dynamic(dynamic.recursive_type_normalized())),
Self::Class(class) => Some(Self::Class(
class.recursive_type_normalized_impl(db, div, nested, visitor)?,
class.recursive_type_normalized_impl(db, div, nested)?,
)),
Self::Protocol | Self::Generic | Self::TypedDict => Some(self),
}

View File

@ -1112,19 +1112,14 @@ impl<'db> FunctionType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
let literal = self.literal(db);
let updated_signature = match self.updated_signature(db) {
Some(signature) => {
Some(signature.recursive_type_normalized_impl(db, div, nested, visitor)?)
}
Some(signature) => Some(signature.recursive_type_normalized_impl(db, div, nested)?),
None => None,
};
let updated_last_definition_signature = match self.updated_last_definition_signature(db) {
Some(signature) => {
Some(signature.recursive_type_normalized_impl(db, div, nested, visitor)?)
}
Some(signature) => Some(signature.recursive_type_normalized_impl(db, div, nested)?),
None => None,
};
Some(Self::new(

View File

@ -1045,24 +1045,23 @@ impl<'db> Specialization<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
let types = if nested {
self.types(db)
.iter()
.map(|ty| ty.recursive_type_normalized_impl(db, div, true, visitor))
.map(|ty| ty.recursive_type_normalized_impl(db, div, true))
.collect::<Option<Box<[_]>>>()?
} else {
self.types(db)
.iter()
.map(|ty| {
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div)
})
.collect::<Box<[_]>>()
};
let tuple_inner = match self.tuple_inner(db) {
Some(tuple) => Some(tuple.recursive_type_normalized_impl(db, div, nested, visitor)?),
Some(tuple) => Some(tuple.recursive_type_normalized_impl(db, div, nested)?),
None => None,
};
let context = self.generic_context(db);

View File

@ -379,16 +379,15 @@ impl<'db> NominalInstanceType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
match self.0 {
NominalInstanceInner::ExactTuple(tuple) => {
Some(Self(NominalInstanceInner::ExactTuple(
tuple.recursive_type_normalized_impl(db, div, nested, visitor)?,
tuple.recursive_type_normalized_impl(db, div, nested)?,
)))
}
NominalInstanceInner::NonTuple(class) => Some(Self(NominalInstanceInner::NonTuple(
class.recursive_type_normalized_impl(db, div, nested, visitor)?,
class.recursive_type_normalized_impl(db, div, nested)?,
))),
NominalInstanceInner::Object => Some(Self(NominalInstanceInner::Object)),
}
@ -750,12 +749,9 @@ impl<'db> ProtocolInstanceType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self {
inner: self
.inner
.recursive_type_normalized_impl(db, div, nested, visitor)?,
inner: self.inner.recursive_type_normalized_impl(db, div, nested)?,
_phantom: PhantomData,
})
}
@ -877,14 +873,13 @@ impl<'db> Protocol<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
match self {
Self::FromClass(class) => Some(Self::FromClass(
class.recursive_type_normalized_impl(db, div, nested, visitor)?,
class.recursive_type_normalized_impl(db, div, nested)?,
)),
Self::Synthesized(synthesized) => Some(Self::Synthesized(
synthesized.recursive_type_normalized_impl(db, div, nested, visitor)?,
synthesized.recursive_type_normalized_impl(db, div, nested)?,
)),
}
}
@ -963,11 +958,9 @@ mod synthesized_protocol {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self(
self.0
.recursive_type_normalized_impl(db, div, nested, visitor)?,
self.0.recursive_type_normalized_impl(db, div, nested)?,
))
}
}

View File

@ -150,11 +150,9 @@ impl<'db> ProtocolClass<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self(
self.0
.recursive_type_normalized_impl(db, div, nested, visitor)?,
self.0.recursive_type_normalized_impl(db, div, nested)?,
))
}
}
@ -386,7 +384,6 @@ impl<'db> ProtocolInterface<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self::new(
db,
@ -395,7 +392,7 @@ impl<'db> ProtocolInterface<'db> {
.map(|(name, data)| {
Some((
name.clone(),
data.recursive_type_normalized_impl(db, div, nested, visitor)?,
data.recursive_type_normalized_impl(db, div, nested)?,
))
})
.collect::<Option<BTreeMap<_, _>>>()?,
@ -498,21 +495,20 @@ impl<'db> ProtocolMemberData<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self {
kind: match &self.kind {
ProtocolMemberKind::Method(callable) => ProtocolMemberKind::Method(
callable.recursive_type_normalized_impl(db, div, nested, visitor)?,
callable.recursive_type_normalized_impl(db, div, nested)?,
),
ProtocolMemberKind::Property(property) => ProtocolMemberKind::Property(
property.recursive_type_normalized_impl(db, div, nested, visitor)?,
),
ProtocolMemberKind::Other(ty) if nested => ProtocolMemberKind::Other(
ty.recursive_type_normalized_impl(db, div, true, visitor)?,
property.recursive_type_normalized_impl(db, div, nested)?,
),
ProtocolMemberKind::Other(ty) if nested => {
ProtocolMemberKind::Other(ty.recursive_type_normalized_impl(db, div, true)?)
}
ProtocolMemberKind::Other(ty) => ProtocolMemberKind::Other(
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div),
),
},

View File

@ -179,13 +179,12 @@ impl<'db> CallableSignature<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self {
overloads: self
.overloads
.iter()
.map(|signature| signature.recursive_type_normalized_impl(db, div, nested, visitor))
.map(|signature| signature.recursive_type_normalized_impl(db, div, nested))
.collect::<Option<SmallVec<_>>>()?,
})
}
@ -575,15 +574,14 @@ impl<'db> Signature<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
let return_ty = match self.return_ty {
Some(return_ty) if nested => {
Some(return_ty.recursive_type_normalized_impl(db, div, true, visitor)?)
Some(return_ty.recursive_type_normalized_impl(db, div, true)?)
}
Some(return_ty) => Some(
return_ty
.recursive_type_normalized_impl(db, div, true, visitor)
.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div),
),
None => None,
@ -591,7 +589,7 @@ impl<'db> Signature<'db> {
let parameters = {
let mut parameters = Vec::with_capacity(self.parameters.len());
for param in &self.parameters {
parameters.push(param.recursive_type_normalized_impl(db, div, nested, visitor)?);
parameters.push(param.recursive_type_normalized_impl(db, div, nested)?);
}
Parameters::new(db, parameters)
};
@ -1906,7 +1904,6 @@ impl<'db> Parameter<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
let Parameter {
annotated_type,
@ -1916,9 +1913,9 @@ impl<'db> Parameter<'db> {
} = self;
let annotated_type = match annotated_type {
Some(ty) if nested => Some(ty.recursive_type_normalized_impl(db, div, true, visitor)?),
Some(ty) if nested => Some(ty.recursive_type_normalized_impl(db, div, true)?),
Some(ty) => Some(
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div),
),
None => None,
@ -1928,11 +1925,9 @@ impl<'db> Parameter<'db> {
ParameterKind::PositionalOnly { name, default_type } => ParameterKind::PositionalOnly {
name: name.clone(),
default_type: match default_type {
Some(ty) if nested => {
Some(ty.recursive_type_normalized_impl(db, div, true, visitor)?)
}
Some(ty) if nested => Some(ty.recursive_type_normalized_impl(db, div, true)?),
Some(ty) => Some(
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div),
),
None => None,
@ -1943,10 +1938,10 @@ impl<'db> Parameter<'db> {
name: name.clone(),
default_type: match default_type {
Some(ty) if nested => {
Some(ty.recursive_type_normalized_impl(db, div, true, visitor)?)
Some(ty.recursive_type_normalized_impl(db, div, true)?)
}
Some(ty) => Some(
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div),
),
None => None,
@ -1956,11 +1951,9 @@ impl<'db> Parameter<'db> {
ParameterKind::KeywordOnly { name, default_type } => ParameterKind::KeywordOnly {
name: name.clone(),
default_type: match default_type {
Some(ty) if nested => {
Some(ty.recursive_type_normalized_impl(db, div, true, visitor)?)
}
Some(ty) if nested => Some(ty.recursive_type_normalized_impl(db, div, true)?),
Some(ty) => Some(
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div),
),
None => None,

View File

@ -272,12 +272,11 @@ impl<'db> SubclassOfType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self {
subclass_of: self
.subclass_of
.recursive_type_normalized_impl(db, div, nested, visitor)?,
.recursive_type_normalized_impl(db, div, nested)?,
})
}
@ -449,11 +448,10 @@ impl<'db> SubclassOfInner<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
match self {
Self::Class(class) => Some(Self::Class(
class.recursive_type_normalized_impl(db, div, nested, visitor)?,
class.recursive_type_normalized_impl(db, div, nested)?,
)),
Self::Dynamic(dynamic) => Some(Self::Dynamic(dynamic.recursive_type_normalized())),
Self::TypeVar(_) => Some(self),

View File

@ -234,12 +234,11 @@ impl<'db> TupleType<'db> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
Some(Self::new_internal(
db,
self.tuple(db)
.recursive_type_normalized_impl(db, div, nested, visitor)?,
.recursive_type_normalized_impl(db, div, nested)?,
))
}
@ -411,13 +410,12 @@ impl<'db> FixedLengthTuple<Type<'db>> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
if nested {
Some(Self::from_elements(
self.0
.iter()
.map(|ty| ty.recursive_type_normalized_impl(db, div, true, visitor))
.map(|ty| ty.recursive_type_normalized_impl(db, div, true))
.collect::<Option<Box<[_]>>>()?,
))
} else {
@ -425,7 +423,7 @@ impl<'db> FixedLengthTuple<Type<'db>> {
self.0
.iter()
.map(|ty| {
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div)
})
.collect::<Box<[_]>>(),
@ -804,18 +802,17 @@ impl<'db> VariableLengthTuple<Type<'db>> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
let prefix = if nested {
self.prefix
.iter()
.map(|ty| ty.recursive_type_normalized_impl(db, div, true, visitor))
.map(|ty| ty.recursive_type_normalized_impl(db, div, true))
.collect::<Option<Box<_>>>()?
} else {
self.prefix
.iter()
.map(|ty| {
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div)
})
.collect::<Box<_>>()
@ -823,23 +820,23 @@ impl<'db> VariableLengthTuple<Type<'db>> {
let suffix = if nested {
self.suffix
.iter()
.map(|ty| ty.recursive_type_normalized_impl(db, div, true, visitor))
.map(|ty| ty.recursive_type_normalized_impl(db, div, true))
.collect::<Option<Box<_>>>()?
} else {
self.suffix
.iter()
.map(|ty| {
ty.recursive_type_normalized_impl(db, div, true, visitor)
ty.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div)
})
.collect::<Box<_>>()
};
let variable = if nested {
self.variable
.recursive_type_normalized_impl(db, div, true, visitor)?
.recursive_type_normalized_impl(db, div, true)?
} else {
self.variable
.recursive_type_normalized_impl(db, div, true, visitor)
.recursive_type_normalized_impl(db, div, true)
.unwrap_or(div)
};
Some(Self {
@ -1250,14 +1247,13 @@ impl<'db> Tuple<Type<'db>> {
db: &'db dyn Db,
div: Type<'db>,
nested: bool,
visitor: &NormalizedVisitor<'db>,
) -> Option<Self> {
match self {
Tuple::Fixed(tuple) => Some(Tuple::Fixed(
tuple.recursive_type_normalized_impl(db, div, nested, visitor)?,
tuple.recursive_type_normalized_impl(db, div, nested)?,
)),
Tuple::Variable(tuple) => Some(Tuple::Variable(
tuple.recursive_type_normalized_impl(db, div, nested, visitor)?,
tuple.recursive_type_normalized_impl(db, div, nested)?,
)),
}
}