@@ -3234,9 +3234,9 @@ module ts {
32343234
32353235 // TYPE CHECKING
32363236
3237- var subtypeRelation : Map < Ternary > = { } ;
3238- var assignableRelation : Map < Ternary > = { } ;
3239- var identityRelation : Map < Ternary > = { } ;
3237+ var subtypeRelation : Map < boolean > = { } ;
3238+ var assignableRelation : Map < boolean > = { } ;
3239+ var identityRelation : Map < boolean > = { } ;
32403240
32413241 function isTypeIdenticalTo ( source : Type , target : Type ) : boolean {
32423242 return checkTypeRelatedTo ( source , target , identityRelation , /*errorNode*/ undefined ) ;
@@ -3271,14 +3271,15 @@ module ts {
32713271 function checkTypeRelatedTo (
32723272 source : Type ,
32733273 target : Type ,
3274- relation : Map < Ternary > ,
3274+ relation : Map < boolean > ,
32753275 errorNode : Node ,
32763276 headMessage ?: DiagnosticMessage ,
32773277 containingMessageChain ?: DiagnosticMessageChain ) : boolean {
32783278
32793279 var errorInfo : DiagnosticMessageChain ;
32803280 var sourceStack : ObjectType [ ] ;
32813281 var targetStack : ObjectType [ ] ;
3282+ var maybeStack : Map < boolean > [ ] ;
32823283 var expandingFlags : number ;
32833284 var depth = 0 ;
32843285 var overflow = false ;
@@ -3437,12 +3438,12 @@ module ts {
34373438 var id = source . id + "," + target . id ;
34383439 var related = relation [ id ] ;
34393440 if ( related !== undefined ) {
3440- return related ;
3441+ return related ? Ternary . True : Ternary . False ;
34413442 }
34423443 if ( depth > 0 ) {
34433444 for ( var i = 0 ; i < depth ; i ++ ) {
34443445 // If source and target are already being compared, consider them related with assumptions
3445- if ( source === sourceStack [ i ] && target === targetStack [ i ] ) {
3446+ if ( maybeStack [ i ] [ id ] ) {
34463447 return Ternary . Maybe ;
34473448 }
34483449 }
@@ -3454,16 +3455,19 @@ module ts {
34543455 else {
34553456 sourceStack = [ ] ;
34563457 targetStack = [ ] ;
3458+ maybeStack = [ ] ;
34573459 expandingFlags = 0 ;
34583460 }
34593461 sourceStack [ depth ] = source ;
34603462 targetStack [ depth ] = target ;
3463+ maybeStack [ depth ] = { } ;
3464+ maybeStack [ depth ] [ id ] = true ;
34613465 depth ++ ;
34623466 var saveExpandingFlags = expandingFlags ;
34633467 if ( ! ( expandingFlags & 1 ) && isDeeplyNestedGeneric ( source , sourceStack ) ) expandingFlags |= 1 ;
34643468 if ( ! ( expandingFlags & 2 ) && isDeeplyNestedGeneric ( target , targetStack ) ) expandingFlags |= 2 ;
34653469 if ( expandingFlags === 3 ) {
3466- var result = Ternary . True ;
3470+ var result = Ternary . Maybe ;
34673471 }
34683472 else {
34693473 var result = propertiesRelatedTo ( source , target , reportErrors ) ;
@@ -3482,9 +3486,18 @@ module ts {
34823486 }
34833487 expandingFlags = saveExpandingFlags ;
34843488 depth -- ;
3485- // Only cache results that are free of assumptions
3486- if ( result !== Ternary . Maybe ) {
3487- relation [ id ] = result ;
3489+ if ( result ) {
3490+ var maybeCache = maybeStack [ depth ] ;
3491+ // If result is definitely true, copy assumptions to global cache, else copy to next level up
3492+ var destinationCache = result === Ternary . True || depth === 0 ? relation : maybeStack [ depth - 1 ] ;
3493+ for ( var p in maybeCache ) {
3494+ destinationCache [ p ] = maybeCache [ p ] ;
3495+ }
3496+ }
3497+ else {
3498+ // A false result goes straight into global cache (when something is false under assumptions it
3499+ // will also be false without assumptions)
3500+ relation [ id ] = false ;
34883501 }
34893502 return result ;
34903503 }
@@ -5420,7 +5433,7 @@ module ts {
54205433 return typeArgumentsAreAssignable ;
54215434 }
54225435
5423- function checkApplicableSignature ( node : CallLikeExpression , args : Node [ ] , signature : Signature , relation : Map < Ternary > , excludeArgument : boolean [ ] , reportErrors : boolean ) {
5436+ function checkApplicableSignature ( node : CallLikeExpression , args : Node [ ] , signature : Signature , relation : Map < boolean > , excludeArgument : boolean [ ] , reportErrors : boolean ) {
54245437 for ( var i = 0 ; i < args . length ; i ++ ) {
54255438 var arg = args [ i ] ;
54265439 var argType : Type ;
@@ -5614,7 +5627,7 @@ module ts {
56145627
56155628 return resolveErrorCall ( node ) ;
56165629
5617- function chooseOverload ( candidates : Signature [ ] , relation : Map < Ternary > ) {
5630+ function chooseOverload ( candidates : Signature [ ] , relation : Map < boolean > ) {
56185631 for ( var i = 0 ; i < candidates . length ; i ++ ) {
56195632 if ( ! hasCorrectArity ( node , args , candidates [ i ] ) ) {
56205633 continue ;
0 commit comments