Skip to content

Commit d798557

Browse files
committed
Try and handle join points properly
1 parent fde48dd commit d798557

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

src/compiler/checker.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,7 @@ namespace ts {
844844
const symbolLinks: SymbolLinks[] = [];
845845
const nodeLinks: NodeLinks[] = [];
846846
const flowLoopCaches: Map<Type>[] = [];
847+
const flowLoopContainingUnionCache: (UnionType | undefined)[] = [];
847848
const flowAssignmentTypes: Type[] = [];
848849
const flowLoopNodes: FlowNode[] = [];
849850
const flowLoopKeys: string[] = [];
@@ -19004,8 +19005,8 @@ namespace ts {
1900419005
return key = getFlowCacheKey(reference, declaredType, initialType, flowContainer);
1900519006
}
1900619007

19007-
function captureContainingUnion(type: FlowType) {
19008-
if (!isIncomplete(type) && type.flags & TypeFlags.Union) {
19008+
function captureContainingUnion(type: FlowType, flags?: FlowFlags) {
19009+
if ((flags === undefined || (flags & FlowFlags.BranchLabel) === 0) && !isIncomplete(type) && type.flags & TypeFlags.Union) {
1900919010
containingUnion = type as UnionType;
1901019011
}
1901119012
}
@@ -19107,7 +19108,7 @@ namespace ts {
1910719108
sharedFlowTypes[sharedFlowCount] = type;
1910819109
sharedFlowCount++;
1910919110
}
19110-
captureContainingUnion(type);
19111+
captureContainingUnion(type, flags);
1911119112
flowDepth--;
1911219113
return type;
1911319114
}
@@ -19328,6 +19329,7 @@ namespace ts {
1932819329
// are the same), there is no reason to process more antecedents since the only
1932919330
// possible outcome is subtypes that will be removed in the final union type anyway.
1933019331
if (type === declaredType && declaredType === initialType) {
19332+
containingUnion = undefined;
1933119333
return type;
1933219334
}
1933319335
pushIfUnique(antecedentTypes, type);
@@ -19342,8 +19344,13 @@ namespace ts {
1934219344
seenIncomplete = true;
1934319345
}
1934419346
}
19345-
const containingUnionType = createFlowType(getUnionOrEvolvingArrayType(containedUnions, subtypeReduction ? UnionReduction.Subtype : UnionReduction.Literal), seenIncomplete);
19346-
captureContainingUnion(containingUnionType);
19347+
containingUnion = undefined;
19348+
captureContainingUnion(
19349+
createFlowType(
19350+
getUnionOrEvolvingArrayType(containedUnions, subtypeReduction ? UnionReduction.Subtype : UnionReduction.Literal),
19351+
seenIncomplete
19352+
)
19353+
);
1934719354
return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? UnionReduction.Subtype : UnionReduction.Literal), seenIncomplete);
1934819355
}
1934919356

@@ -19359,6 +19366,7 @@ namespace ts {
1935919366
}
1936019367
const cached = cache.get(key);
1936119368
if (cached) {
19369+
containingUnion = flowLoopContainingUnionCache[id];
1936219370
return cached;
1936319371
}
1936419372
// If this flow loop junction and reference are already being processed, return
@@ -19379,12 +19387,14 @@ namespace ts {
1937919387
const antecedentTypes: Type[] = [];
1938019388
let subtypeReduction = false;
1938119389
let firstAntecedentType: FlowType | undefined;
19390+
let unionContainedAtTop: UnionType | undefined;
1938219391
for (const antecedent of flow.antecedents!) {
1938319392
let flowType;
1938419393
if (!firstAntecedentType) {
1938519394
// The first antecedent of a loop junction is always the non-looping control
1938619395
// flow path that leads to the top.
1938719396
flowType = firstAntecedentType = getTypeAtFlowNode(antecedent);
19397+
unionContainedAtTop = containingUnion;
1938819398
}
1938919399
else {
1939019400
// All but the first antecedent are the looping control flow paths that lead
@@ -19400,6 +19410,7 @@ namespace ts {
1940019410
// the resulting type and bail out.
1940119411
const cached = cache.get(key);
1940219412
if (cached) {
19413+
containingUnion = flowLoopContainingUnionCache[id];
1940319414
return cached;
1940419415
}
1940519416
}
@@ -19422,8 +19433,10 @@ namespace ts {
1942219433
// is incomplete.
1942319434
const result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? UnionReduction.Subtype : UnionReduction.Literal);
1942419435
if (isIncomplete(firstAntecedentType!)) {
19436+
containingUnion = undefined;
1942519437
return createFlowType(result, /*incomplete*/ true);
1942619438
}
19439+
containingUnion = flowLoopContainingUnionCache[id] = unionContainedAtTop;
1942719440
cache.set(key, result);
1942819441
return result;
1942919442
}

0 commit comments

Comments
 (0)