diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7e9e8bd4b0e..77814ccc544 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17003,6 +17003,10 @@ namespace ts { return result; } + function isUnlockedReachableFlowNode(flow: FlowNode) { + return !(flow.flags & FlowFlags.PreFinally && (flow).lock.locked) && isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false); + } + function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean { while (true) { if (flow === lastFlowNode) { @@ -17017,8 +17021,8 @@ namespace ts { } noCacheCheck = false; } - if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation | FlowFlags.PreFinally | FlowFlags.AfterFinally)) { - flow = (flow).antecedent; + if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation | FlowFlags.PreFinally)) { + flow = (flow).antecedent; } else if (flags & FlowFlags.Call) { const signature = getEffectsSignature((flow).node); @@ -17029,7 +17033,7 @@ namespace ts { } else if (flags & FlowFlags.BranchLabel) { // A branching point is reachable if any branch is reachable. - return some((flow).antecedents, isReachableFlowNode); + return some((flow).antecedents, isUnlockedReachableFlowNode); } else if (flags & FlowFlags.LoopLabel) { // A loop is reachable if the control flow path that leads to the top is reachable. @@ -17043,6 +17047,14 @@ namespace ts { } flow = (flow).antecedent; } + else if (flags & FlowFlags.AfterFinally) { + // Cache is unreliable once we start locking nodes + lastFlowNode = undefined; + (flow).locked = true; + const result = isReachableFlowNodeWorker((flow).antecedent, /*skipCacheCheck*/ false); + (flow).locked = false; + return result; + } else { return !(flags & FlowFlags.Unreachable); }