Revert "break recursion cycle"

This reverts commit ee68251407.
This commit is contained in:
Douglas Creager 2025-12-07 16:27:22 -05:00
parent 2428c29226
commit 048cf419a4
3 changed files with 26 additions and 27 deletions

View File

@ -7595,15 +7595,11 @@ impl<'db> Type<'db> {
tcx: TypeContext<'db>,
visitor: &ApplyTypeMappingVisitor<'db>,
) -> Type<'db> {
// If we are binding `typing.Self`, and this type is what we are binding `Self` to, return
// early. This is not just an optimization, it also prevents us from infinitely expanding
// the type, if it's something that can contain a `Self` reference.
match type_mapping {
// If we are binding `typing.Self`, and this type is what we are binding `Self` to, return
// early. This is not just an optimization, it also prevents us from infinitely expanding
// the type, if it's something that can contain a `Self` reference.
TypeMapping::BindSelf { self_type, .. } if self == *self_type => return self,
// If we are breaking a recursive type, look for that before expanding this type.
TypeMapping::BreakRecursionCycle(target) if self == *target => return Type::unknown(),
_ => {}
}
@ -7622,7 +7618,7 @@ impl<'db> Type<'db> {
TypeMapping::BindSelf { .. } |
TypeMapping::ReplaceSelf { .. } |
TypeMapping::Materialize(_) |
TypeMapping::BreakRecursionCycle(_) |
TypeMapping::ReplaceParameterDefaults |
TypeMapping::EagerExpansion => self,
}
}
@ -7798,7 +7794,7 @@ impl<'db> Type<'db> {
TypeMapping::BindSelf { .. } |
TypeMapping::ReplaceSelf { .. } |
TypeMapping::Materialize(_) |
TypeMapping::BreakRecursionCycle(_) |
TypeMapping::ReplaceParameterDefaults |
TypeMapping::EagerExpansion |
TypeMapping::PromoteLiterals(PromoteLiteralsMode::Off) => self,
TypeMapping::PromoteLiterals(PromoteLiteralsMode::On) => self.promote_literals_impl(db, tcx)
@ -7811,7 +7807,7 @@ impl<'db> Type<'db> {
TypeMapping::BindSelf { .. } |
TypeMapping::ReplaceSelf { .. } |
TypeMapping::PromoteLiterals(_) |
TypeMapping::BreakRecursionCycle(_) |
TypeMapping::ReplaceParameterDefaults |
TypeMapping::EagerExpansion => self,
TypeMapping::Materialize(materialization_kind) => match materialization_kind {
MaterializationKind::Top => Type::object(),
@ -8088,12 +8084,11 @@ impl<'db> Type<'db> {
.find_legacy_typevars(db, None, variables);
}
/// Looks for any recursive references to this type inside of itself, replacing them with
/// `Unknown`.
pub(crate) fn break_recursion_cycle(self, db: &'db dyn Db) -> Type<'db> {
/// Replace default types in parameters of callables with `Unknown`.
pub(crate) fn replace_parameter_defaults(self, db: &'db dyn Db) -> Type<'db> {
self.apply_type_mapping(
db,
&TypeMapping::BreakRecursionCycle(self),
&TypeMapping::ReplaceParameterDefaults,
TypeContext::default(),
)
}
@ -8533,9 +8528,9 @@ pub enum TypeMapping<'a, 'db> {
ReplaceSelf { new_upper_bound: Type<'db> },
/// Create the top or bottom materialization of a type.
Materialize(MaterializationKind),
/// Looks for any recursive references to a type inside of itself, replacing them with
/// `Unknown`.
BreakRecursionCycle(Type<'db>),
/// Replace default types in parameters of callables with `Unknown`. This is used to avoid infinite
/// recursion when the type of the default value of a parameter depends on the callable itself.
ReplaceParameterDefaults,
/// Apply eager expansion to the type.
/// In the case of recursive type aliases, this will diverge, so that part will be replaced with `Divergent`.
EagerExpansion,
@ -8554,7 +8549,7 @@ impl<'db> TypeMapping<'_, 'db> {
| TypeMapping::PromoteLiterals(_)
| TypeMapping::BindLegacyTypevars(_)
| TypeMapping::Materialize(_)
| TypeMapping::BreakRecursionCycle(_)
| TypeMapping::ReplaceParameterDefaults
| TypeMapping::EagerExpansion => context,
TypeMapping::BindSelf {
binding_context, ..
@ -8588,7 +8583,7 @@ impl<'db> TypeMapping<'_, 'db> {
| TypeMapping::BindLegacyTypevars(_)
| TypeMapping::BindSelf { .. }
| TypeMapping::ReplaceSelf { .. }
| TypeMapping::BreakRecursionCycle(_)
| TypeMapping::ReplaceParameterDefaults
| TypeMapping::EagerExpansion => self.clone(),
}
}
@ -10185,7 +10180,7 @@ impl<'db> BoundTypeVarInstance<'db> {
}
}
TypeMapping::PromoteLiterals(_)
| TypeMapping::BreakRecursionCycle(_)
| TypeMapping::ReplaceParameterDefaults
| TypeMapping::BindLegacyTypevars(_)
| TypeMapping::EagerExpansion => Type::TypeVar(self),
TypeMapping::Materialize(materialization_kind) => {

View File

@ -8248,7 +8248,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
if let Some(default) = param.default() {
parameter = parameter.with_default_type(
self.infer_expression(default, TypeContext::default())
.break_recursion_cycle(self.db()),
.replace_parameter_defaults(self.db()),
);
}
parameter
@ -8262,7 +8262,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
if let Some(default) = param.default() {
parameter = parameter.with_default_type(
self.infer_expression(default, TypeContext::default())
.break_recursion_cycle(self.db()),
.replace_parameter_defaults(self.db()),
);
}
parameter
@ -8280,7 +8280,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
if let Some(default) = param.default() {
parameter = parameter.with_default_type(
self.infer_expression(default, TypeContext::default())
.break_recursion_cycle(self.db()),
.replace_parameter_defaults(self.db()),
);
}
parameter

View File

@ -544,7 +544,7 @@ impl<'db> Signature<'db> {
defaults
.next()
.expect("should have optional default for each non-variadic parameter")
.map(|ty| ty.break_recursion_cycle(db))
.map(|ty| ty.replace_parameter_defaults(db))
});
}
let mut parameters = Parameters::new(db, inferred_signature.parameters);
@ -2202,9 +2202,13 @@ impl<'db> ParameterKind<'db> {
visitor: &ApplyTypeMappingVisitor<'db>,
) -> Self {
let apply_to_default_type = |default_type: &Option<Type<'db>>| {
default_type
.as_ref()
.map(|ty| ty.apply_type_mapping_impl(db, type_mapping, tcx, visitor))
if type_mapping == &TypeMapping::ReplaceParameterDefaults && default_type.is_some() {
Some(Type::unknown())
} else {
default_type
.as_ref()
.map(|ty| ty.apply_type_mapping_impl(db, type_mapping, tcx, visitor))
}
};
match self {