@@ -5070,7 +5070,7 @@ module ts {
5070
5070
return getSignatureInstantiation ( signature , getInferredTypes ( context ) ) ;
5071
5071
}
5072
5072
5073
- function inferTypeArguments ( signature : Signature , args : Expression [ ] , typeArgumentResultTypes : Type [ ] , excludeArgument ?: boolean [ ] ) : boolean {
5073
+ function inferTypeArguments ( signature : Signature , args : Expression [ ] , typeArgumentResultTypes : Type [ ] , excludeArgument ?: boolean [ ] ) : InferenceContext {
5074
5074
var typeParameters = signature . typeParameters ;
5075
5075
var context = createInferenceContext ( typeParameters , /*inferUnionTypes*/ false , typeArgumentResultTypes ) ;
5076
5076
var mapper = createInferenceMapper ( context ) ;
@@ -5097,8 +5097,17 @@ module ts {
5097
5097
}
5098
5098
}
5099
5099
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 ;
5102
5111
}
5103
5112
5104
5113
function checkTypeArguments ( signature : Signature , typeArguments : TypeNode [ ] , typeArgumentResultTypes : Type [ ] , reportErrors : boolean ) : boolean {
@@ -5165,7 +5174,7 @@ module ts {
5165
5174
5166
5175
var candidateForArgumentError : Signature ;
5167
5176
var candidateForTypeArgumentError : Signature ;
5168
- var indexOfUninferredTypeParameter : number ;
5177
+ var resultOfFailedInference : InferenceContext ;
5169
5178
var result : Signature ;
5170
5179
if ( candidates . length > 1 ) {
5171
5180
result = chooseOverload ( candidates , subtypeRelation , excludeArgument ) ;
@@ -5174,7 +5183,7 @@ module ts {
5174
5183
// Reinitialize these pointers for round two
5175
5184
candidateForArgumentError = undefined ;
5176
5185
candidateForTypeArgumentError = undefined ;
5177
- indexOfUninferredTypeParameter = undefined ;
5186
+ resultOfFailedInference = undefined ;
5178
5187
result = chooseOverload ( candidates , assignableRelation , excludeArgument ) ;
5179
5188
}
5180
5189
if ( result ) {
@@ -5193,8 +5202,9 @@ module ts {
5193
5202
checkTypeArguments ( candidateForTypeArgumentError , node . typeArguments , [ ] , /*reportErrors*/ true )
5194
5203
}
5195
5204
else {
5205
+ Debug . assert ( resultOfFailedInference . failureIndex >= 0 ) ;
5196
5206
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 ] ) ) ;
5198
5208
}
5199
5209
}
5200
5210
else {
@@ -5223,14 +5233,20 @@ module ts {
5223
5233
}
5224
5234
5225
5235
var originalCandidate = candidates [ i ] ;
5236
+ var inferenceResult : InferenceContext ;
5226
5237
5227
5238
while ( true ) {
5228
5239
var candidate = originalCandidate ;
5229
5240
if ( candidate . typeParameters ) {
5230
5241
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
+ }
5234
5250
if ( ! typeArgumentsAreValid ) {
5235
5251
break ;
5236
5252
}
@@ -5259,7 +5275,7 @@ module ts {
5259
5275
else {
5260
5276
candidateForTypeArgumentError = originalCandidate ;
5261
5277
if ( ! node . typeArguments ) {
5262
- indexOfUninferredTypeParameter = typeArgumentTypes . indexOf ( typeArgumentInferenceFailureType ) ;
5278
+ resultOfFailedInference = inferenceResult ;
5263
5279
}
5264
5280
}
5265
5281
}
0 commit comments