@@ -1487,6 +1487,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
14871487 var lastGetCombinedModifierFlagsNode: Declaration | undefined;
14881488 var lastGetCombinedModifierFlagsResult = ModifierFlags.None;
14891489
1490+ var chooseOverloadRecursionLevel = -1; // #56013
1491+ var chooseOverloadFlushNodesSignaturesReq: (Set<Node> | undefined)[] = []; // #56013
1492+
14901493 // for public members that accept a Node or one of its subtypes, we must guard against
14911494 // synthetic nodes created during transformations by calling `getParseTreeNode`.
14921495 // for most of these, we perform the guard only on `checker` to avoid any possible
@@ -34310,87 +34313,95 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3431034313 }
3431134314
3431234315 function chooseOverload(candidates: Signature[], relation: Map<string, RelationComparisonResult>, isSingleNonGenericCandidate: boolean, signatureHelpTrailingComma = false) {
34313- candidatesForArgumentError = undefined;
34314- candidateForArgumentArityError = undefined;
34315- candidateForTypeArgumentError = undefined;
34316-
34317- if (isSingleNonGenericCandidate) {
34318- const candidate = candidates[0];
34319- if (some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
34320- return undefined;
34321- }
34322- if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
34323- candidatesForArgumentError = [candidate];
34324- return undefined;
34316+ chooseOverloadRecursionLevel++; // #56013
34317+ chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = undefined;
34318+ const result = (() => {
34319+ candidatesForArgumentError = undefined;
34320+ candidateForArgumentArityError = undefined;
34321+ candidateForTypeArgumentError = undefined;
34322+
34323+ if (isSingleNonGenericCandidate) {
34324+ const candidate = candidates[0];
34325+ if (some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
34326+ return undefined;
34327+ }
34328+ if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
34329+ candidatesForArgumentError = [candidate];
34330+ return undefined;
34331+ }
34332+ return candidate;
3432534333 }
34326- return candidate;
34327- }
3432834334
34329- for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
34330- const candidate = candidates[candidateIndex];
34331- if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
34332- continue;
34333- }
34335+ for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
34336+ if (candidateIndex > 0) chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = new Set(); // #56013
34337+ const candidate = candidates[candidateIndex];
34338+ if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
34339+ continue;
34340+ }
3433434341
34335- let checkCandidate: Signature;
34336- let inferenceContext: InferenceContext | undefined;
34342+ let checkCandidate: Signature;
34343+ let inferenceContext: InferenceContext | undefined;
3433734344
34338- if (candidate.typeParameters) {
34339- let typeArgumentTypes: Type[] | undefined;
34340- if (some(typeArguments)) {
34341- typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
34342- if (!typeArgumentTypes) {
34343- candidateForTypeArgumentError = candidate;
34344- continue;
34345+ if (candidate.typeParameters) {
34346+ let typeArgumentTypes: Type[] | undefined;
34347+ if (some(typeArguments)) {
34348+ typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
34349+ if (!typeArgumentTypes) {
34350+ candidateForTypeArgumentError = candidate;
34351+ continue;
34352+ }
3434534353 }
34346- }
34347- else {
34348- inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
34349- typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext);
34350- argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal;
34351- }
34352- checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
34353- // If the original signature has a generic rest type, instantiation may produce a
34354- // signature with different arity and we need to perform another arity check.
34355- if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
34356- candidateForArgumentArityError = checkCandidate;
34357- continue;
34358- }
34359- }
34360- else {
34361- checkCandidate = candidate;
34362- }
34363- if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
34364- // Give preference to error candidates that have no rest parameters (as they are more specific)
34365- (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
34366- continue;
34367- }
34368- if (argCheckMode) {
34369- // If one or more context sensitive arguments were excluded, we start including
34370- // them now (and keeping do so for any subsequent candidates) and perform a second
34371- // round of type inference and applicability checking for this particular candidate.
34372- argCheckMode = CheckMode.Normal;
34373- if (inferenceContext) {
34374- const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
34375- checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters);
34354+ else {
34355+ inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
34356+ typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext);
34357+ argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal;
34358+ }
34359+ checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
3437634360 // If the original signature has a generic rest type, instantiation may produce a
3437734361 // signature with different arity and we need to perform another arity check.
3437834362 if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
3437934363 candidateForArgumentArityError = checkCandidate;
3438034364 continue;
3438134365 }
3438234366 }
34367+ else {
34368+ checkCandidate = candidate;
34369+ }
3438334370 if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
3438434371 // Give preference to error candidates that have no rest parameters (as they are more specific)
3438534372 (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
3438634373 continue;
3438734374 }
34375+ if (argCheckMode) {
34376+ // If one or more context sensitive arguments were excluded, we start including
34377+ // them now (and keeping do so for any subsequent candidates) and perform a second
34378+ // round of type inference and applicability checking for this particular candidate.
34379+ argCheckMode = CheckMode.Normal;
34380+ if (inferenceContext) {
34381+ const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
34382+ checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters);
34383+ // If the original signature has a generic rest type, instantiation may produce a
34384+ // signature with different arity and we need to perform another arity check.
34385+ if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
34386+ candidateForArgumentArityError = checkCandidate;
34387+ continue;
34388+ }
34389+ }
34390+ if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
34391+ // Give preference to error candidates that have no rest parameters (as they are more specific)
34392+ (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
34393+ continue;
34394+ }
34395+ }
34396+ candidates[candidateIndex] = checkCandidate;
34397+ return checkCandidate;
3438834398 }
34389- candidates[candidateIndex] = checkCandidate;
34390- return checkCandidate;
34391- }
3439234399
34393- return undefined;
34400+ return undefined;
34401+ })();
34402+ chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = undefined;
34403+ chooseOverloadRecursionLevel--;
34404+ return result;
3439434405 }
3439534406 }
3439634407
@@ -38932,6 +38943,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3893238943 const saveCurrentNode = currentNode;
3893338944 currentNode = node;
3893438945 instantiationCount = 0;
38946+ // #56013
38947+ if (node.kind === SyntaxKind.CallExpression && chooseOverloadRecursionLevel >= 0) {
38948+ let setOfNode: Set<Node> | undefined;
38949+ if (chooseOverloadRecursionLevel >= 0 && (setOfNode = chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel])) {
38950+ if (!setOfNode.has(node)) {
38951+ getNodeLinks(node).resolvedSignature = undefined;
38952+ setOfNode.add(node);
38953+ }
38954+ }
38955+ }
3893538956 const uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple);
3893638957 const type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
3893738958 if (isConstEnumObjectType(type)) {
0 commit comments