@@ -3930,15 +3930,15 @@ module ts {
39303930 }
39313931 }
39323932
3933- function createInferenceContext ( typeParameters : TypeParameter [ ] , inferUnionTypes : boolean , typeArgumentResultTypes ?: Type [ ] ) : InferenceContext {
3933+ function createInferenceContext ( typeParameters : TypeParameter [ ] , inferUnionTypes : boolean ) : InferenceContext {
39343934 var inferences : Type [ ] [ ] = [ ] ;
39353935 for ( var i = 0 ; i < typeParameters . length ; i ++ ) inferences . push ( [ ] ) ;
39363936 return {
39373937 typeParameters : typeParameters ,
39383938 inferUnionTypes : inferUnionTypes ,
39393939 inferenceCount : 0 ,
39403940 inferences : inferences ,
3941- inferredTypes : typeArgumentResultTypes || new Array ( typeParameters . length ) ,
3941+ inferredTypes : new Array ( typeParameters . length ) ,
39423942 } ;
39433943 }
39443944
@@ -5154,9 +5154,9 @@ module ts {
51545154 return getSignatureInstantiation ( signature , getInferredTypes ( context ) ) ;
51555155 }
51565156
5157- function inferTypeArguments ( signature : Signature , args : Expression [ ] , typeArgumentResultTypes : Type [ ] , excludeArgument ?: boolean [ ] ) : InferenceContext {
5157+ function inferTypeArguments ( signature : Signature , args : Expression [ ] , excludeArgument ?: boolean [ ] ) : InferenceContext {
51585158 var typeParameters = signature . typeParameters ;
5159- var context = createInferenceContext ( typeParameters , /*inferUnionTypes*/ false , typeArgumentResultTypes ) ;
5159+ var context = createInferenceContext ( typeParameters , /*inferUnionTypes*/ false ) ;
51605160 var mapper = createInferenceMapper ( context ) ;
51615161 // First infer from arguments that are not context sensitive
51625162 for ( var i = 0 ; i < args . length ; i ++ ) {
@@ -5205,8 +5205,7 @@ module ts {
52055205 if ( typeArgumentsAreAssignable /* so far */ ) {
52065206 var constraint = getConstraintOfTypeParameter ( typeParameters [ i ] ) ;
52075207 if ( constraint ) {
5208- typeArgumentsAreAssignable = typeArgumentsAreAssignable &&
5209- checkTypeAssignableTo ( typeArgument , constraint , reportErrors ? typeArgNode : undefined ,
5208+ typeArgumentsAreAssignable = checkTypeAssignableTo ( typeArgument , constraint , reportErrors ? typeArgNode : undefined ,
52105209 Diagnostics . Type_0_does_not_satisfy_the_constraint_1_Colon , Diagnostics . Type_0_does_not_satisfy_the_constraint_1 ) ;
52115210 }
52125211 }
@@ -5257,10 +5256,42 @@ module ts {
52575256 }
52585257 }
52595258
5259+ // The following variables are captured and modified by calls to chooseOverload.
5260+ // If overload resolution or type argument inference fails, we want to report the
5261+ // best error possible. The best error is one which says that an argument was not
5262+ // assignable to a parameter. This implies that everything else about the overload
5263+ // was fine. So if there is any overload that is only incorrect because of an
5264+ // argument, we will report an error on that one.
5265+ //
5266+ // function foo(s: string) {}
5267+ // function foo(n: number) {} // Report argument error on this overload
5268+ // function foo() {}
5269+ // foo(true);
5270+ //
5271+ // If none of the overloads even made it that far, there are two possibilities.
5272+ // There was a problem with type arguments for some overload, in which case
5273+ // report an error on that. Or none of the overloads even had correct arity,
5274+ // in which case give an arity error.
5275+ //
5276+ // function foo<T>(x: T, y: T) {} // Report type argument inference error
5277+ // function foo() {}
5278+ // foo(0, true);
5279+ //
52605280 var candidateForArgumentError : Signature ;
52615281 var candidateForTypeArgumentError : Signature ;
52625282 var resultOfFailedInference : InferenceContext ;
52635283 var result : Signature ;
5284+
5285+ // Section 4.12.1:
5286+ // if the candidate list contains one or more signatures for which the type of each argument
5287+ // expression is a subtype of each corresponding parameter type, the return type of the first
5288+ // of those signatures becomes the return type of the function call.
5289+ // Otherwise, the return type of the first signature in the candidate list becomes the return
5290+ // type of the function call.
5291+ //
5292+ // Whether the call is an error is determined by assignability of the arguments. The subtype pass
5293+ // is just important for choosing the best signature. So in the case where there is only one
5294+ // signature, the subtype pass is useless. So skipping it is an optimization.
52645295 if ( candidates . length > 1 ) {
52655296 result = chooseOverload ( candidates , subtypeRelation , excludeArgument ) ;
52665297 }
@@ -5280,6 +5311,11 @@ module ts {
52805311 // If candidate is undefined, it means that no candidates had a suitable arity. In that case,
52815312 // skip the checkApplicableSignature check.
52825313 if ( candidateForArgumentError ) {
5314+ // excludeArgument is undefined, in this case also equivalent to [undefined, undefined, ...]
5315+ // The importance of exlcludeArgument is to prevent us from typing function expression parameters
5316+ // in arguments too early. If possible, we'd like to only type them once we know the correct
5317+ // overload. However, this matters for the case where the call is correct. When the call is
5318+ // an error, we don't need to exclude any arguments, although it would cause no harm to do so.
52835319 checkApplicableSignature ( node , candidateForArgumentError , assignableRelation , /*excludeArgument*/ undefined , /*reportErrors*/ true ) ;
52845320 }
52855321 else if ( candidateForTypeArgumentError ) {
@@ -5329,14 +5365,16 @@ module ts {
53295365 while ( true ) {
53305366 var candidate = originalCandidate ;
53315367 if ( candidate . typeParameters ) {
5332- var typeArgumentTypes = new Array < Type > ( candidate . typeParameters . length ) ;
5368+ var typeArgumentTypes : Type [ ] ;
53335369 var typeArgumentsAreValid : boolean ;
53345370 if ( node . typeArguments ) {
5371+ typeArgumentTypes = new Array < Type > ( candidate . typeParameters . length ) ;
53355372 typeArgumentsAreValid = checkTypeArguments ( candidate , node . typeArguments , typeArgumentTypes , /*reportErrors*/ false )
53365373 }
53375374 else {
5338- inferenceResult = inferTypeArguments ( candidate , args , typeArgumentTypes , excludeArgument ) ;
5375+ inferenceResult = inferTypeArguments ( candidate , args , excludeArgument ) ;
53395376 typeArgumentsAreValid = inferenceResult . failureIndex < 0 ;
5377+ typeArgumentTypes = inferenceResult . inferredTypes ;
53405378 }
53415379 if ( ! typeArgumentsAreValid ) {
53425380 break ;
@@ -5371,7 +5409,8 @@ module ts {
53715409 }
53725410 }
53735411 else {
5374- candidateForArgumentError = originalCandidate ; // Could be candidate too
5412+ Debug . assert ( originalCandidate === candidate ) ;
5413+ candidateForArgumentError = originalCandidate ;
53755414 }
53765415 }
53775416
0 commit comments