@@ -3505,6 +3505,7 @@ module ts {
35053505 return t => {
35063506 for (let i = 0; i < context.typeParameters.length; i++) {
35073507 if (t === context.typeParameters[i]) {
3508+ context.inferences[i].isFixed = true;
35083509 return getInferredType(context, i);
35093510 }
35103511 }
@@ -4563,12 +4564,11 @@ module ts {
45634564 function createInferenceContext(typeParameters: TypeParameter[], inferUnionTypes: boolean): InferenceContext {
45644565 let inferences: TypeInferences[] = [];
45654566 for (let unused of typeParameters) {
4566- inferences.push({ primary: undefined, secondary: undefined });
4567+ inferences.push({ primary: undefined, secondary: undefined, isFixed: false });
45674568 }
45684569 return {
45694570 typeParameters: typeParameters,
45704571 inferUnionTypes: inferUnionTypes,
4571- inferenceCount: 0,
45724572 inferences: inferences,
45734573 inferredTypes: new Array(typeParameters.length),
45744574 };
@@ -4615,11 +4615,13 @@ module ts {
46154615 for (let i = 0; i < typeParameters.length; i++) {
46164616 if (target === typeParameters[i]) {
46174617 let inferences = context.inferences[i];
4618- let candidates = inferiority ?
4619- inferences.secondary || (inferences.secondary = []) :
4620- inferences.primary || (inferences.primary = []);
4621- if (!contains(candidates, source)) candidates.push(source);
4622- break;
4618+ if (!inferences.isFixed) {
4619+ let candidates = inferiority ?
4620+ inferences.secondary || (inferences.secondary = []) :
4621+ inferences.primary || (inferences.primary = []);
4622+ if (!contains(candidates, source)) candidates.push(source);
4623+ }
4624+ return;
46234625 }
46244626 }
46254627 }
@@ -6336,11 +6338,15 @@ module ts {
63366338 return getSignatureInstantiation(signature, getInferredTypes(context));
63376339 }
63386340
6339- function inferTypeArguments(signature: Signature, args: Expression[], excludeArgument: boolean[]) : InferenceContext {
6341+ function inferTypeArguments(signature: Signature, args: Expression[], excludeArgument: boolean[], context : InferenceContext): void {
63406342 let typeParameters = signature.typeParameters;
6341- let context = createInferenceContext(typeParameters, /*inferUnionTypes*/ false);
63426343 let inferenceMapper = createInferenceMapper(context);
63436344
6345+ // Clear out all the inference results from the last time inferTypeArguments was called on this context
6346+ for (let i = 0; i < typeParameters.length; i++) {
6347+ context.inferredTypes[i] = undefined;
6348+ }
6349+
63446350 // We perform two passes over the arguments. In the first pass we infer from all arguments, but use
63456351 // wildcards for all context sensitive function expressions.
63466352 for (let i = 0; i < args.length; i++) {
@@ -6385,8 +6391,6 @@ module ts {
63856391 inferredTypes[i] = unknownType;
63866392 }
63876393 }
6388-
6389- return context;
63906394 }
63916395
63926396 function checkTypeArguments(signature: Signature, typeArguments: TypeNode[], typeArgumentResultTypes: Type[], reportErrors: boolean): boolean {
@@ -6620,15 +6624,17 @@ module ts {
66206624 return resolveErrorCall(node);
66216625
66226626 function chooseOverload(candidates: Signature[], relation: Map<RelationComparisonResult>) {
6623- for (let current of candidates) {
6624- if (!hasCorrectArity(node, args, current )) {
6627+ for (let originalCandidate of candidates) {
6628+ if (!hasCorrectArity(node, args, originalCandidate )) {
66256629 continue;
66266630 }
6627-
6628- let originalCandidate = current;
6629- let inferenceResult: InferenceContext;
6631+
66306632 let candidate: Signature;
66316633 let typeArgumentsAreValid: boolean;
6634+ let inferenceContext = originalCandidate.typeParameters
6635+ ? createInferenceContext(originalCandidate.typeParameters, /*inferUnionTypes*/ false)
6636+ : undefined;
6637+
66326638 while (true) {
66336639 candidate = originalCandidate;
66346640 if (candidate.typeParameters) {
@@ -6638,9 +6644,9 @@ module ts {
66386644 typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false)
66396645 }
66406646 else {
6641- inferenceResult = inferTypeArguments(candidate, args, excludeArgument);
6642- typeArgumentsAreValid = inferenceResult .failedTypeParameterIndex < 0;
6643- typeArgumentTypes = inferenceResult .inferredTypes;
6647+ inferTypeArguments(candidate, args, excludeArgument, inferenceContext );
6648+ typeArgumentsAreValid = inferenceContext .failedTypeParameterIndex < 0;
6649+ typeArgumentTypes = inferenceContext .inferredTypes;
66446650 }
66456651 if (!typeArgumentsAreValid) {
66466652 break;
@@ -6670,7 +6676,7 @@ module ts {
66706676 else {
66716677 candidateForTypeArgumentError = originalCandidate;
66726678 if (!typeArguments) {
6673- resultOfFailedInference = inferenceResult ;
6679+ resultOfFailedInference = inferenceContext ;
66746680 }
66756681 }
66766682 }
0 commit comments