@@ -4439,8 +4439,8 @@ namespace ts {
4439
4439
maybeStack[depth][id] = RelationComparisonResult.Succeeded;
4440
4440
depth++;
4441
4441
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;
4444
4444
let result: Ternary;
4445
4445
if (expandingFlags === 3) {
4446
4446
result = Ternary.Maybe;
@@ -4476,27 +4476,6 @@ namespace ts {
4476
4476
return result;
4477
4477
}
4478
4478
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
-
4500
4479
function propertiesRelatedTo(source: ObjectType, target: ObjectType, reportErrors: boolean): Ternary {
4501
4480
if (relation === identityRelation) {
4502
4481
return propertiesIdenticalTo(source, target);
@@ -4815,6 +4794,27 @@ namespace ts {
4815
4794
}
4816
4795
}
4817
4796
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
+
4818
4818
function isPropertyIdenticalTo(sourceProp: Symbol, targetProp: Symbol): boolean {
4819
4819
return compareProperties(sourceProp, targetProp, compareTypes) !== Ternary.False;
4820
4820
}
@@ -5129,21 +5129,6 @@ namespace ts {
5129
5129
return false;
5130
5130
}
5131
5131
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
-
5147
5132
function inferFromTypes(source: Type, target: Type) {
5148
5133
if (source === anyFunctionType) {
5149
5134
return;
@@ -5211,22 +5196,27 @@ namespace ts {
5211
5196
else if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) ||
5212
5197
(target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral))) {
5213
5198
// 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;
5229
5201
}
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--;
5230
5220
}
5231
5221
}
5232
5222
0 commit comments