@@ -4438,8 +4438,8 @@ module ts {
4438
4438
maybeStack[depth][id] = RelationComparisonResult.Succeeded;
4439
4439
depth++;
4440
4440
let saveExpandingFlags = expandingFlags;
4441
- if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack)) expandingFlags |= 1;
4442
- if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack)) expandingFlags |= 2;
4441
+ if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack, depth )) expandingFlags |= 1;
4442
+ if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth )) expandingFlags |= 2;
4443
4443
let result: Ternary;
4444
4444
if (expandingFlags === 3) {
4445
4445
result = Ternary.Maybe;
@@ -4475,27 +4475,6 @@ module ts {
4475
4475
return result;
4476
4476
}
4477
4477
4478
- // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case
4479
- // when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible,
4480
- // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding.
4481
- // Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at
4482
- // some level beyond that.
4483
- function isDeeplyNestedGeneric(type: ObjectType, stack: ObjectType[]): boolean {
4484
- // We track type references (created by createTypeReference) and instantiated types (created by instantiateType)
4485
- if (type.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && depth >= 10) {
4486
- let symbol = type.symbol;
4487
- let count = 0;
4488
- for (let i = 0; i < depth; i++) {
4489
- let t = stack[i];
4490
- if (t.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && t.symbol === symbol) {
4491
- count++;
4492
- if (count >= 10) return true;
4493
- }
4494
- }
4495
- }
4496
- return false;
4497
- }
4498
-
4499
4478
function propertiesRelatedTo(source: ObjectType, target: ObjectType, reportErrors: boolean): Ternary {
4500
4479
if (relation === identityRelation) {
4501
4480
return propertiesIdenticalTo(source, target);
@@ -4814,6 +4793,27 @@ module ts {
4814
4793
}
4815
4794
}
4816
4795
4796
+ // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case
4797
+ // when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible,
4798
+ // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding.
4799
+ // Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at
4800
+ // some level beyond that.
4801
+ function isDeeplyNestedGeneric(type: Type, stack: Type[], depth: number): boolean {
4802
+ // We track type references (created by createTypeReference) and instantiated types (created by instantiateType)
4803
+ if (type.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && depth >= 10) {
4804
+ let symbol = type.symbol;
4805
+ let count = 0;
4806
+ for (let i = 0; i < depth; i++) {
4807
+ let t = stack[i];
4808
+ if (t.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && t.symbol === symbol) {
4809
+ count++;
4810
+ if (count >= 10) return true;
4811
+ }
4812
+ }
4813
+ }
4814
+ return false;
4815
+ }
4816
+
4817
4817
function isPropertyIdenticalTo(sourceProp: Symbol, targetProp: Symbol): boolean {
4818
4818
return compareProperties(sourceProp, targetProp, compareTypes) !== Ternary.False;
4819
4819
}
@@ -5128,21 +5128,6 @@ module ts {
5128
5128
return false;
5129
5129
}
5130
5130
5131
- function isWithinDepthLimit(type: Type, stack: Type[]) {
5132
- if (depth >= 5) {
5133
- let target = (<TypeReference>type).target;
5134
- let count = 0;
5135
- for (let i = 0; i < depth; i++) {
5136
- let t = stack[i];
5137
- if (t.flags & TypeFlags.Reference && (<TypeReference>t).target === target) {
5138
- count++;
5139
- }
5140
- }
5141
- return count < 5;
5142
- }
5143
- return true;
5144
- }
5145
-
5146
5131
function inferFromTypes(source: Type, target: Type) {
5147
5132
if (source === anyFunctionType) {
5148
5133
return;
@@ -5210,7 +5195,7 @@ module ts {
5210
5195
else if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) ||
5211
5196
(target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral))) {
5212
5197
// 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
5213
- if (!isInProcess(source, target) && isWithinDepthLimit( source, sourceStack) && isWithinDepthLimit (target, targetStack)) {
5198
+ if (!isInProcess(source, target) && !(isDeeplyNestedGeneric( source, sourceStack, depth ) && isDeeplyNestedGeneric (target, targetStack, depth) )) {
5214
5199
if (depth === 0) {
5215
5200
sourceStack = [];
5216
5201
targetStack = [];
0 commit comments