Track if incomplete variances have been observed

This commit is contained in:
Anders Hejlsberg 2022-03-01 17:02:58 -08:00
parent de4a166905
commit d059791728

View File

@ -348,6 +348,7 @@ namespace ts {
let inlineLevel = 0;
let varianceLevel = 0;
let nestedVarianceSymbols: Symbol[] | undefined;
let incompleteVariancesObserved = false;
let currentNode: Node | undefined;
const emptySymbols = createSymbolTable();
@ -20445,15 +20446,22 @@ namespace ts {
varianceLevel--;
// Recursive invocations of getVariancesWorker occur when two or more types circularly reference each
// other. In such cases, the nested invocations might observe in-process variance computations, i.e.
// cases where getVariancesWorker returns emptyArray, and thus might compute incomplete variances. For
// this reason we clear (and thus re-compute) the results of nested variance computations and only
// permanently record the outermost result. See #44572.
if (varianceLevel === 0 && nestedVarianceSymbols) {
for (const sym of nestedVarianceSymbols) getSymbolLinks(sym).variances = undefined;
// cases where getVariancesWorker returns emptyArray. If that happens we clear (and thus re-compute) the
// results of nested variance computations and only permanently record the outermost result. See #44572.
if (varianceLevel === 0) {
if (nestedVarianceSymbols && incompleteVariancesObserved) {
for (const sym of nestedVarianceSymbols) {
getSymbolLinks(sym).variances = undefined;
}
}
nestedVarianceSymbols = undefined;
incompleteVariancesObserved = false;
}
tracing?.pop();
}
else {
incompleteVariancesObserved ||= links.variances === emptyArray;
}
return links.variances;
}