Skip to content

Commit 05300a7

Browse files
committed
Have inferArgumentTypes return the InferenceContext
1 parent 2517185 commit 05300a7

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

src/compiler/checker.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5070,7 +5070,7 @@ module ts {
50705070
return getSignatureInstantiation(signature, getInferredTypes(context));
50715071
}
50725072

5073-
function inferTypeArguments(signature: Signature, args: Expression[], typeArgumentResultTypes: Type[], excludeArgument?: boolean[]): boolean {
5073+
function inferTypeArguments(signature: Signature, args: Expression[], typeArgumentResultTypes: Type[], excludeArgument?: boolean[]): InferenceContext {
50745074
var typeParameters = signature.typeParameters;
50755075
var context = createInferenceContext(typeParameters, /*inferUnionTypes*/ false, typeArgumentResultTypes);
50765076
var mapper = createInferenceMapper(context);
@@ -5097,8 +5097,17 @@ module ts {
50975097
}
50985098
}
50995099
var inferredTypes = getInferredTypes(context);
5100-
// Inference has failed if the undefined type is in list of inferences
5101-
return !contains(inferredTypes, typeArgumentInferenceFailureType);
5100+
// Inference has failed if the typeArgumentInferenceFailureType type is in list of inferences
5101+
context.failureIndex = indexOf(inferredTypes, typeArgumentInferenceFailureType);
5102+
5103+
// Wipe out the typeArgumentInferenceFailureType from the array so that error recovery can work properly
5104+
for (var i = 0; i < inferredTypes.length; i++) {
5105+
if (inferredTypes[i] === typeArgumentInferenceFailureType) {
5106+
inferredTypes[i] = unknownType;
5107+
}
5108+
}
5109+
5110+
return context;
51025111
}
51035112

51045113
function checkTypeArguments(signature: Signature, typeArguments: TypeNode[], typeArgumentResultTypes: Type[], reportErrors: boolean): boolean {
@@ -5165,7 +5174,7 @@ module ts {
51655174

51665175
var candidateForArgumentError: Signature;
51675176
var candidateForTypeArgumentError: Signature;
5168-
var indexOfUninferredTypeParameter: number;
5177+
var resultOfFailedInference: InferenceContext;
51695178
var result: Signature;
51705179
if (candidates.length > 1) {
51715180
result = chooseOverload(candidates, subtypeRelation, excludeArgument);
@@ -5174,7 +5183,7 @@ module ts {
51745183
// Reinitialize these pointers for round two
51755184
candidateForArgumentError = undefined;
51765185
candidateForTypeArgumentError = undefined;
5177-
indexOfUninferredTypeParameter = undefined;
5186+
resultOfFailedInference = undefined;
51785187
result = chooseOverload(candidates, assignableRelation, excludeArgument);
51795188
}
51805189
if (result) {
@@ -5193,8 +5202,9 @@ module ts {
51935202
checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, [], /*reportErrors*/ true)
51945203
}
51955204
else {
5205+
Debug.assert(resultOfFailedInference.failureIndex >= 0);
51965206
error(node.func, Diagnostics.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Try_specifying_the_type_arguments_explicitly,
5197-
typeToString(candidateForTypeArgumentError.typeParameters[indexOfUninferredTypeParameter]));
5207+
typeToString(candidateForTypeArgumentError.typeParameters[resultOfFailedInference.failureIndex]));
51985208
}
51995209
}
52005210
else {
@@ -5223,14 +5233,20 @@ module ts {
52235233
}
52245234

52255235
var originalCandidate = candidates[i];
5236+
var inferenceResult: InferenceContext;
52265237

52275238
while (true) {
52285239
var candidate = originalCandidate;
52295240
if (candidate.typeParameters) {
52305241
var typeArgumentTypes = new Array<Type>(candidate.typeParameters.length);
5231-
var typeArgumentsAreValid = node.typeArguments ?
5232-
checkTypeArguments(candidate, node.typeArguments, typeArgumentTypes, /*reportErrors*/ false) :
5233-
inferTypeArguments(candidate, args, typeArgumentTypes, excludeArgument);
5242+
var typeArgumentsAreValid: boolean;
5243+
if (node.typeArguments) {
5244+
typeArgumentsAreValid = checkTypeArguments(candidate, node.typeArguments, typeArgumentTypes, /*reportErrors*/ false)
5245+
}
5246+
else {
5247+
inferenceResult = inferTypeArguments(candidate, args, typeArgumentTypes, excludeArgument);
5248+
typeArgumentsAreValid = inferenceResult.failureIndex < 0;
5249+
}
52345250
if (!typeArgumentsAreValid) {
52355251
break;
52365252
}
@@ -5259,7 +5275,7 @@ module ts {
52595275
else {
52605276
candidateForTypeArgumentError = originalCandidate;
52615277
if (!node.typeArguments) {
5262-
indexOfUninferredTypeParameter = typeArgumentTypes.indexOf(typeArgumentInferenceFailureType);
5278+
resultOfFailedInference = inferenceResult;
52635279
}
52645280
}
52655281
}

src/compiler/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,8 @@ module ts {
10171017
inferenceCount: number; // Incremented for every inference made (whether new or not)
10181018
inferences: Type[][]; // Inferences made for each type parameter
10191019
inferredTypes: Type[]; // Inferred type for each type parameter
1020+
failureIndex?: number; // Index of type parameter for which inference failed
1021+
// It is optional because in contextual signature instantiation, nothing fails
10201022
}
10211023

10221024
export interface DiagnosticMessage {

0 commit comments

Comments
 (0)