@@ -4439,8 +4439,8 @@ namespace ts {
44394439 maybeStack[depth][id] = RelationComparisonResult.Succeeded;
44404440 depth++;
44414441 let saveExpandingFlags = expandingFlags;
4442- if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack)) expandingFlags |= 1;
4443- if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack)) expandingFlags |= 2;
4442+ if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack, depth )) expandingFlags |= 1;
4443+ if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth )) expandingFlags |= 2;
44444444 let result: Ternary;
44454445 if (expandingFlags === 3) {
44464446 result = Ternary.Maybe;
@@ -4476,27 +4476,6 @@ namespace ts {
44764476 return result;
44774477 }
44784478
4479- // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case
4480- // when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible,
4481- // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding.
4482- // Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at
4483- // some level beyond that.
4484- function isDeeplyNestedGeneric(type: ObjectType, stack: ObjectType[]): boolean {
4485- // We track type references (created by createTypeReference) and instantiated types (created by instantiateType)
4486- if (type.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && depth >= 10) {
4487- let symbol = type.symbol;
4488- let count = 0;
4489- for (let i = 0; i < depth; i++) {
4490- let t = stack[i];
4491- if (t.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && t.symbol === symbol) {
4492- count++;
4493- if (count >= 10) return true;
4494- }
4495- }
4496- }
4497- return false;
4498- }
4499-
45004479 function propertiesRelatedTo(source: ObjectType, target: ObjectType, reportErrors: boolean): Ternary {
45014480 if (relation === identityRelation) {
45024481 return propertiesIdenticalTo(source, target);
@@ -4815,6 +4794,27 @@ namespace ts {
48154794 }
48164795 }
48174796
4797+ // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case
4798+ // when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible,
4799+ // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding.
4800+ // Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at
4801+ // some level beyond that.
4802+ function isDeeplyNestedGeneric(type: Type, stack: Type[], depth: number): boolean {
4803+ // We track type references (created by createTypeReference) and instantiated types (created by instantiateType)
4804+ if (type.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && depth >= 5) {
4805+ let symbol = type.symbol;
4806+ let count = 0;
4807+ for (let i = 0; i < depth; i++) {
4808+ let t = stack[i];
4809+ if (t.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && t.symbol === symbol) {
4810+ count++;
4811+ if (count >= 5) return true;
4812+ }
4813+ }
4814+ }
4815+ return false;
4816+ }
4817+
48184818 function isPropertyIdenticalTo(sourceProp: Symbol, targetProp: Symbol): boolean {
48194819 return compareProperties(sourceProp, targetProp, compareTypes) !== Ternary.False;
48204820 }
@@ -5129,21 +5129,6 @@ namespace ts {
51295129 return false;
51305130 }
51315131
5132- function isWithinDepthLimit(type: Type, stack: Type[]) {
5133- if (depth >= 5) {
5134- let target = (<TypeReference>type).target;
5135- let count = 0;
5136- for (let i = 0; i < depth; i++) {
5137- let t = stack[i];
5138- if (t.flags & TypeFlags.Reference && (<TypeReference>t).target === target) {
5139- count++;
5140- }
5141- }
5142- return count < 5;
5143- }
5144- return true;
5145- }
5146-
51475132 function inferFromTypes(source: Type, target: Type) {
51485133 if (source === anyFunctionType) {
51495134 return;
@@ -5211,22 +5196,27 @@ namespace ts {
52115196 else if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) ||
52125197 (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral))) {
52135198 // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members
5214- if (!isInProcess(source, target) && isWithinDepthLimit(source, sourceStack) && isWithinDepthLimit(target, targetStack)) {
5215- if (depth === 0) {
5216- sourceStack = [];
5217- targetStack = [];
5218- }
5219- sourceStack[depth] = source;
5220- targetStack[depth] = target;
5221- depth++;
5222- inferFromProperties(source, target);
5223- inferFromSignatures(source, target, SignatureKind.Call);
5224- inferFromSignatures(source, target, SignatureKind.Construct);
5225- inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String);
5226- inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number);
5227- inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number);
5228- depth--;
5199+ if (isInProcess(source, target)) {
5200+ return;
52295201 }
5202+ if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) {
5203+ return;
5204+ }
5205+
5206+ if (depth === 0) {
5207+ sourceStack = [];
5208+ targetStack = [];
5209+ }
5210+ sourceStack[depth] = source;
5211+ targetStack[depth] = target;
5212+ depth++;
5213+ inferFromProperties(source, target);
5214+ inferFromSignatures(source, target, SignatureKind.Call);
5215+ inferFromSignatures(source, target, SignatureKind.Construct);
5216+ inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String);
5217+ inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number);
5218+ inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number);
5219+ depth--;
52305220 }
52315221 }
52325222
0 commit comments