@@ -1487,6 +1487,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1487
1487
var lastGetCombinedModifierFlagsNode: Declaration | undefined;
1488
1488
var lastGetCombinedModifierFlagsResult = ModifierFlags.None;
1489
1489
1490
+ var chooseOverloadRecursionLevel = -1; // #56013
1491
+ var chooseOverloadFlushNodesSignaturesReq: (Set<Node> | undefined)[] = []; // #56013
1492
+
1490
1493
// for public members that accept a Node or one of its subtypes, we must guard against
1491
1494
// synthetic nodes created during transformations by calling `getParseTreeNode`.
1492
1495
// 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 {
34310
34313
}
34311
34314
34312
34315
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;
34325
34333
}
34326
- return candidate;
34327
- }
34328
34334
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
+ }
34334
34341
34335
- let checkCandidate: Signature;
34336
- let inferenceContext: InferenceContext | undefined;
34342
+ let checkCandidate: Signature;
34343
+ let inferenceContext: InferenceContext | undefined;
34337
34344
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
+ }
34345
34353
}
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);
34376
34360
// If the original signature has a generic rest type, instantiation may produce a
34377
34361
// signature with different arity and we need to perform another arity check.
34378
34362
if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
34379
34363
candidateForArgumentArityError = checkCandidate;
34380
34364
continue;
34381
34365
}
34382
34366
}
34367
+ else {
34368
+ checkCandidate = candidate;
34369
+ }
34383
34370
if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
34384
34371
// Give preference to error candidates that have no rest parameters (as they are more specific)
34385
34372
(candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
34386
34373
continue;
34387
34374
}
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;
34388
34398
}
34389
- candidates[candidateIndex] = checkCandidate;
34390
- return checkCandidate;
34391
- }
34392
34399
34393
- return undefined;
34400
+ return undefined;
34401
+ })();
34402
+ chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = undefined;
34403
+ chooseOverloadRecursionLevel--;
34404
+ return result;
34394
34405
}
34395
34406
}
34396
34407
@@ -38932,6 +38943,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
38932
38943
const saveCurrentNode = currentNode;
38933
38944
currentNode = node;
38934
38945
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
+ }
38935
38956
const uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple);
38936
38957
const type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
38937
38958
if (isConstEnumObjectType(type)) {
0 commit comments