@@ -15564,7 +15564,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1556415564 return undefined;
1556515565 }
1556615566
15567- function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly TypeParameter[]): Signature {
15567+ function getSignatureInstantiation(signature: Signature, typeArguments: readonly Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly TypeParameter[]): Signature {
1556815568 const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
1556915569 if (inferredTypeParameters) {
1557015570 const returnSignature = getSingleCallOrConstructSignature(getReturnTypeOfSignature(instantiatedSignature));
@@ -15628,6 +15628,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1562815628 );
1562915629 }
1563015630
15631+ function getImplementationSignature(signature: Signature) {
15632+ return signature.typeParameters ?
15633+ signature.implementationSignatureCache ||= createImplementationSignature(signature) :
15634+ signature;
15635+ }
15636+
15637+ function createImplementationSignature(signature: Signature) {
15638+ return signature.typeParameters ? instantiateSignature(signature, createTypeMapper([], [])) : signature;
15639+ }
15640+
1563115641 function getBaseSignature(signature: Signature) {
1563215642 const typeParameters = signature.typeParameters;
1563315643 if (typeParameters) {
@@ -15663,7 +15673,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1566315673 // The type must have a symbol with a `Function` flag and a declaration in order to be correctly flagged as possibly containing
1566415674 // type variables by `couldContainTypeVariables`
1566515675 const type = createObjectType(ObjectFlags.Anonymous | ObjectFlags.SingleSignatureType, createSymbol(SymbolFlags.Function, InternalSymbolName.Function)) as SingleSignatureType;
15666- if (signature.declaration) {
15676+ if (signature.declaration && !nodeIsSynthesized(signature.declaration)) { // skip synthetic declarations - keeping those around could be bad, since they lack a parent pointer
1566715677 type.symbol.declarations = [signature.declaration];
1566815678 type.symbol.valueDeclaration = signature.declaration;
1566915679 }
@@ -25139,6 +25149,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2513925149 const result = !!(type.flags & TypeFlags.Instantiable ||
2514025150 type.flags & TypeFlags.Object && !isNonGenericTopLevelType(type) && (
2514125151 objectFlags & ObjectFlags.Reference && ((type as TypeReference).node || some(getTypeArguments(type as TypeReference), couldContainTypeVariables)) ||
25152+ objectFlags & ObjectFlags.SingleSignatureType && !!length((type as SingleSignatureType).outerTypeParameters) ||
2514225153 objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ||
2514325154 objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType | ObjectFlags.InstantiationExpressionType)
2514425155 ) ||
@@ -26372,25 +26383,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2637226383 // inference error only occurs when there are *conflicting* candidates, i.e.
2637326384 // candidates with no common supertype.
2637426385 const defaultType = getDefaultFromTypeParameter(inference.typeParameter);
26375- inferredType = defaultType;
26386+ // Instantiate the default type. Any forward reference to a type
26387+ // parameter should be instantiated to the empty object type.
26388+ inferredType = instantiateType(defaultType, mergeTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
2637626389 }
2637726390 }
2637826391 else {
2637926392 inferredType = getTypeFromInference(inference);
2638026393 }
2638126394
26382- const isDefault = !inferredType;
26383- inferredType ||= getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault));
26384- inference.inferredType = inferredType;
26385- // Instantiate the inferred type. Any forward reference to a type
26386- // parameter should be instantiated to the empty object type.
26387- inferredType = instantiateType(inferredType, mergeTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
26388- inference.inferredType = inferredType;
26395+ inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault));
2638926396
2639026397 const constraint = getConstraintOfTypeParameter(inference.typeParameter);
2639126398 if (constraint) {
2639226399 const instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper);
26393- if (isDefault || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
26400+ if (!inferredType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
2639426401 // If the fallback type satisfies the constraint, we pick it. Otherwise, we pick the constraint.
2639526402 inference.inferredType = fallbackType && context.compareTypes(fallbackType, getTypeWithThisArgument(instantiatedConstraint, fallbackType)) ? fallbackType : instantiatedConstraint;
2639626403 }
@@ -34875,7 +34882,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3487534882 }
3487634883
3487734884 for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
34878- const candidate = candidates[candidateIndex];
34885+ let candidate = candidates[candidateIndex];
3487934886 if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
3488034887 continue;
3488134888 }
@@ -34884,7 +34891,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3488434891 let inferenceContext: InferenceContext | undefined;
3488534892
3488634893 if (candidate.typeParameters) {
34887- let typeArgumentTypes: Type[] | undefined;
34894+ // If we are *inside the body of candidate*, we need to create a clone of `candidate` with differing type parameter identities,
34895+ // so our inference results for this call doesn't pollute expression types referencing the outer type parameter!
34896+ if (candidate.declaration && findAncestor(node, a => a === candidate.declaration)) {
34897+ candidate = getImplementationSignature(candidate);
34898+ }
34899+ let typeArgumentTypes: readonly Type[] | undefined;
3488834900 if (some(typeArguments)) {
3488934901 typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
3489034902 if (!typeArgumentTypes) {
@@ -34893,8 +34905,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3489334905 }
3489434906 }
3489534907 else {
34896- inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
34897- typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext);
34908+ inferenceContext = createInferenceContext(candidate.typeParameters!, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
34909+ // The resulting type arguments are instantiated with the inference context mapper, as the inferred types may still contain references to the inference context's
34910+ // type variables via contextual projection. These are kept generic until all inferences are locked in, so the dependencies expressed can pass constraint checks.
34911+ typeArgumentTypes = instantiateTypes(inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext), inferenceContext.nonFixingMapper);
3489834912 argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal;
3489934913 }
3490034914 checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
@@ -34919,7 +34933,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3491934933 // round of type inference and applicability checking for this particular candidate.
3492034934 argCheckMode = CheckMode.Normal;
3492134935 if (inferenceContext) {
34922- const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
34936+ const typeArgumentTypes = instantiateTypes( inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext), inferenceContext.mapper );
3492334937 checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters);
3492434938 // If the original signature has a generic rest type, instantiation may produce a
3492534939 // signature with different arity and we need to perform another arity check.
0 commit comments