@@ -336,7 +336,6 @@ namespace ts {
336
336
let totalInstantiationCount = 0;
337
337
let instantiationCount = 0;
338
338
let instantiationDepth = 0;
339
- let constraintDepth = 0;
340
339
let currentNode: Node | undefined;
341
340
342
341
const typeCatalog: Type[] = []; // NB: id is index + 1
@@ -11033,7 +11032,6 @@ namespace ts {
11033
11032
if (type.resolvedBaseConstraint) {
11034
11033
return type.resolvedBaseConstraint;
11035
11034
}
11036
- let nonTerminating = false;
11037
11035
const stack: Type[] = [];
11038
11036
return type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type);
11039
11037
@@ -11042,22 +11040,16 @@ namespace ts {
11042
11040
if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) {
11043
11041
return circularConstraintType;
11044
11042
}
11045
- if (constraintDepth >= 50) {
11046
- // We have reached 50 recursive invocations of getImmediateBaseConstraint and there is a
11047
- // very high likelihood we're dealing with an infinite generic type that perpetually generates
11048
- // new type identities as we descend into it. We stop the recursion here and mark this type
11049
- // and the outer types as having circular constraints.
11050
- tracing.instant(tracing.Phase.CheckTypes, "getImmediateBaseConstraint_DepthLimit", { typeId: t.id, originalTypeId: type.id, depth: constraintDepth });
11051
- error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
11052
- nonTerminating = true;
11053
- return t.immediateBaseConstraint = noConstraintType;
11054
- }
11055
11043
let result;
11056
- if (stack.length < 10 || !isDeeplyNestedType(t, stack, stack.length)) {
11044
+ // We always explore at least 10 levels of nested constraints. Thereafter, we continue to explore
11045
+ // up to 50 levels of nested constraints provided there are no "deeply nested" types on the stack
11046
+ // (i.e. no types for which five instantiations have been recorded on the stack). If we reach 50
11047
+ // levels of nesting, we are presumably exploring a repeating pattern with a long cycle that hasn't
11048
+ // yet triggered the deeply nested limiter. We have no test cases that actually get to 50 levels of
11049
+ // nesting, so it is effectively just a safety stop.
11050
+ if (stack.length < 10 || stack.length < 50 && !isDeeplyNestedType(t, stack, stack.length)) {
11057
11051
stack.push(t);
11058
- constraintDepth++;
11059
11052
result = computeBaseConstraint(getSimplifiedType(t, /*writing*/ false));
11060
- constraintDepth--;
11061
11053
stack.pop();
11062
11054
}
11063
11055
if (!popTypeResolution()) {
@@ -11072,9 +11064,6 @@ namespace ts {
11072
11064
}
11073
11065
result = circularConstraintType;
11074
11066
}
11075
- if (nonTerminating) {
11076
- result = circularConstraintType;
11077
- }
11078
11067
t.immediateBaseConstraint = result || noConstraintType;
11079
11068
}
11080
11069
return t.immediateBaseConstraint;
@@ -11125,10 +11114,7 @@ namespace ts {
11125
11114
}
11126
11115
if (t.flags & TypeFlags.Conditional) {
11127
11116
const constraint = getConstraintFromConditionalType(<ConditionalType>t);
11128
- constraintDepth++; // Penalize repeating conditional types (this captures the recursion within getConstraintFromConditionalType and carries it forward)
11129
- const result = constraint && getBaseConstraint(constraint);
11130
- constraintDepth--;
11131
- return result;
11117
+ return constraint && getBaseConstraint(constraint);
11132
11118
}
11133
11119
if (t.flags & TypeFlags.Substitution) {
11134
11120
return getBaseConstraint((<SubstitutionType>t).substitute);
0 commit comments