@@ -8733,11 +8733,12 @@ namespace ts {
87338733 containingMessageChain?: DiagnosticMessageChain): boolean {
87348734
87358735 let errorInfo: DiagnosticMessageChain;
8736+ let maybeKeys: string[];
87368737 let sourceStack: Type[];
87378738 let targetStack: Type[];
8738- let maybeStack: Map<RelationComparisonResult>[];
8739- let expandingFlags: number;
8739+ let maybeCount = 0;
87408740 let depth = 0;
8741+ let expandingFlags = 0;
87418742 let overflow = false;
87428743 let isIntersectionConstituent = false;
87438744
@@ -9105,10 +9106,15 @@ namespace ts {
91059106 return related === RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False;
91069107 }
91079108 }
9108- if (depth > 0) {
9109- for (let i = 0; i < depth; i++) {
9109+ if (!maybeKeys) {
9110+ maybeKeys = [];
9111+ sourceStack = [];
9112+ targetStack = [];
9113+ }
9114+ else {
9115+ for (let i = 0; i < maybeCount; i++) {
91109116 // If source and target are already being compared, consider them related with assumptions
9111- if (maybeStack [i].get(id) ) {
9117+ if (id === maybeKeys [i]) {
91129118 return Ternary.Maybe;
91139119 }
91149120 }
@@ -9117,16 +9123,11 @@ namespace ts {
91179123 return Ternary.False;
91189124 }
91199125 }
9120- else {
9121- sourceStack = [];
9122- targetStack = [];
9123- maybeStack = [];
9124- expandingFlags = 0;
9125- }
9126+ const maybeStart = maybeCount;
9127+ maybeKeys[maybeCount] = id;
9128+ maybeCount++;
91269129 sourceStack[depth] = source;
91279130 targetStack[depth] = target;
9128- maybeStack[depth] = createMap<RelationComparisonResult>();
9129- maybeStack[depth].set(id, RelationComparisonResult.Succeeded);
91309131 depth++;
91319132 const saveExpandingFlags = expandingFlags;
91329133 if (!(expandingFlags & 1) && isDeeplyNestedType(source, sourceStack, depth)) expandingFlags |= 1;
@@ -9135,15 +9136,19 @@ namespace ts {
91359136 expandingFlags = saveExpandingFlags;
91369137 depth--;
91379138 if (result) {
9138- const maybeCache = maybeStack[depth];
9139- // If result is definitely true, copy assumptions to global cache, else copy to next level up
9140- const destinationCache = (result === Ternary.True || depth === 0) ? relation : maybeStack[depth - 1];
9141- copyEntries(maybeCache, destinationCache);
9139+ if (result === Ternary.True || depth === 0) {
9140+ // If result is definitely true, record all maybe keys as having succeeded
9141+ for (let i = maybeStart; i < maybeCount; i++) {
9142+ relation.set(maybeKeys[i], RelationComparisonResult.Succeeded);
9143+ }
9144+ maybeCount = maybeStart;
9145+ }
91429146 }
91439147 else {
9144- // A false result goes straight into global cache (when something is false under assumptions it
9145- // will also be false without assumptions)
9148+ // A false result goes straight into global cache (when something is false under
9149+ // assumptions it will also be false without assumptions)
91469150 relation.set(id, reportErrors ? RelationComparisonResult.FailedAndReported : RelationComparisonResult.Failed);
9151+ maybeCount = maybeStart;
91479152 }
91489153 return result;
91499154 }
0 commit comments