Skip to content

Commit 7b77b49

Browse files
committed
Enable caching for control flow paths that precede loops
1 parent 5e06bea commit 7b77b49

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

src/compiler/checker.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17309,24 +17309,31 @@ namespace ts {
1730917309
const antecedentTypes: Type[] = [];
1731017310
let subtypeReduction = false;
1731117311
let firstAntecedentType: FlowType | undefined;
17312-
flowLoopNodes[flowLoopCount] = flow;
17313-
flowLoopKeys[flowLoopCount] = key;
17314-
flowLoopTypes[flowLoopCount] = antecedentTypes;
1731517312
for (const antecedent of flow.antecedents!) {
17316-
flowLoopCount++;
17317-
const flowType = getTypeAtFlowNode(antecedent);
17318-
flowLoopCount--;
17313+
let flowType;
1731917314
if (!firstAntecedentType) {
17320-
firstAntecedentType = flowType;
17315+
// The first antecedent of a loop junction is always the non-looping control
17316+
// flow path that leads to the top.
17317+
flowType = firstAntecedentType = getTypeAtFlowNode(antecedent);
1732117318
}
17322-
const type = getTypeFromFlowType(flowType);
17323-
// If we see a value appear in the cache it is a sign that control flow analysis
17324-
// was restarted and completed by checkExpressionCached. We can simply pick up
17325-
// the resulting type and bail out.
17326-
const cached = cache.get(key);
17327-
if (cached) {
17328-
return cached;
17319+
else {
17320+
// All but the first antecedent are the looping control flow paths that lead
17321+
// back to the loop junction. We track these on the flow loop stack.
17322+
flowLoopNodes[flowLoopCount] = flow;
17323+
flowLoopKeys[flowLoopCount] = key;
17324+
flowLoopTypes[flowLoopCount] = antecedentTypes;
17325+
flowLoopCount++;
17326+
flowType = getTypeAtFlowNode(antecedent);
17327+
flowLoopCount--;
17328+
// If we see a value appear in the cache it is a sign that control flow analysis
17329+
// was restarted and completed by checkExpressionCached. We can simply pick up
17330+
// the resulting type and bail out.
17331+
const cached = cache.get(key);
17332+
if (cached) {
17333+
return cached;
17334+
}
1732917335
}
17336+
const type = getTypeFromFlowType(flowType);
1733017337
pushIfUnique(antecedentTypes, type);
1733117338
// If an antecedent type is not a subset of the declared type, we need to perform
1733217339
// subtype reduction. This happens when a "foreign" type is injected into the control

0 commit comments

Comments
 (0)