Fix recursive type inference (#53396)

This commit is contained in:
Anders Hejlsberg
2023-03-21 12:53:16 -07:00
committed by GitHub
parent bace6897e2
commit 3d2c3442db
10 changed files with 143 additions and 19 deletions

View File

@@ -22911,7 +22911,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return type.symbol;
}
if (isTupleType(type)) {
return type;
return type.target;
}
}
if (type.flags & TypeFlags.TypeParameter) {
@@ -24273,8 +24273,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
let inferencePriority: number = InferencePriority.MaxValue;
let allowComplexConstraintInference = true;
let visited: Map<string, number>;
let sourceStack: object[];
let targetStack: object[];
let sourceStack: Type[];
let targetStack: Type[];
let expandingFlags = ExpandingFlags.None;
inferFromTypes(originalSource, originalTarget);
@@ -24530,20 +24530,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// We stop inferring and report a circularity if we encounter duplicate recursion identities on both
// the source side and the target side.
const saveExpandingFlags = expandingFlags;
const sourceIdentity = getRecursionIdentity(source);
const targetIdentity = getRecursionIdentity(target);
if (contains(sourceStack, sourceIdentity)) expandingFlags |= ExpandingFlags.Source;
if (contains(targetStack, targetIdentity)) expandingFlags |= ExpandingFlags.Target;
(sourceStack ??= []).push(source);
(targetStack ??= []).push(target);
if (isDeeplyNestedType(source, sourceStack, sourceStack.length, 2)) expandingFlags |= ExpandingFlags.Source;
if (isDeeplyNestedType(target, targetStack, targetStack.length, 2)) expandingFlags |= ExpandingFlags.Target;
if (expandingFlags !== ExpandingFlags.Both) {
(sourceStack || (sourceStack = [])).push(sourceIdentity);
(targetStack || (targetStack = [])).push(targetIdentity);
action(source, target);
targetStack.pop();
sourceStack.pop();
}
else {
inferencePriority = InferencePriority.Circularity;
}
targetStack.pop();
sourceStack.pop();
expandingFlags = saveExpandingFlags;
visited.set(key, inferencePriority);
inferencePriority = Math.min(inferencePriority, saveInferencePriority);