@@ -3221,9 +3221,9 @@ module ts {
3221
3221
3222
3222
// TYPE CHECKING
3223
3223
3224
- var subtypeRelation : Map < Ternary > = { } ;
3225
- var assignableRelation : Map < Ternary > = { } ;
3226
- var identityRelation : Map < Ternary > = { } ;
3224
+ var subtypeRelation : Map < boolean > = { } ;
3225
+ var assignableRelation : Map < boolean > = { } ;
3226
+ var identityRelation : Map < boolean > = { } ;
3227
3227
3228
3228
function isTypeIdenticalTo ( source : Type , target : Type ) : boolean {
3229
3229
return checkTypeRelatedTo ( source , target , identityRelation , /*errorNode*/ undefined ) ;
@@ -3258,14 +3258,15 @@ module ts {
3258
3258
function checkTypeRelatedTo (
3259
3259
source : Type ,
3260
3260
target : Type ,
3261
- relation : Map < Ternary > ,
3261
+ relation : Map < boolean > ,
3262
3262
errorNode : Node ,
3263
3263
headMessage ?: DiagnosticMessage ,
3264
3264
containingMessageChain ?: DiagnosticMessageChain ) : boolean {
3265
3265
3266
3266
var errorInfo : DiagnosticMessageChain ;
3267
3267
var sourceStack : ObjectType [ ] ;
3268
3268
var targetStack : ObjectType [ ] ;
3269
+ var maybeStack : Map < boolean > [ ] ;
3269
3270
var expandingFlags : number ;
3270
3271
var depth = 0 ;
3271
3272
var overflow = false ;
@@ -3424,12 +3425,12 @@ module ts {
3424
3425
var id = source . id + "," + target . id ;
3425
3426
var related = relation [ id ] ;
3426
3427
if ( related !== undefined ) {
3427
- return related ;
3428
+ return related ? Ternary . True : Ternary . False ;
3428
3429
}
3429
3430
if ( depth > 0 ) {
3430
3431
for ( var i = 0 ; i < depth ; i ++ ) {
3431
3432
// If source and target are already being compared, consider them related with assumptions
3432
- if ( source === sourceStack [ i ] && target === targetStack [ i ] ) {
3433
+ if ( maybeStack [ i ] [ id ] ) {
3433
3434
return Ternary . Maybe ;
3434
3435
}
3435
3436
}
@@ -3441,10 +3442,13 @@ module ts {
3441
3442
else {
3442
3443
sourceStack = [ ] ;
3443
3444
targetStack = [ ] ;
3445
+ maybeStack = [ ] ;
3444
3446
expandingFlags = 0 ;
3445
3447
}
3446
3448
sourceStack [ depth ] = source ;
3447
3449
targetStack [ depth ] = target ;
3450
+ maybeStack [ depth ] = { } ;
3451
+ maybeStack [ depth ] [ id ] = true ;
3448
3452
depth ++ ;
3449
3453
var saveExpandingFlags = expandingFlags ;
3450
3454
if ( ! ( expandingFlags & 1 ) && isDeeplyNestedGeneric ( source , sourceStack ) ) expandingFlags |= 1 ;
@@ -3469,9 +3473,18 @@ module ts {
3469
3473
}
3470
3474
expandingFlags = saveExpandingFlags ;
3471
3475
depth -- ;
3472
- // Only cache results that are free of assumptions
3473
- if ( result !== Ternary . Maybe ) {
3474
- relation [ id ] = result ;
3476
+ if ( result ) {
3477
+ var sourceCache = maybeStack [ depth ] ;
3478
+ // If result is definitely true, copy assumptions to global cache, else copy to next level up
3479
+ var targetCache = result === Ternary . True || depth === 0 ? relation : maybeStack [ depth - 1 ] ;
3480
+ for ( var p in sourceCache ) {
3481
+ targetCache [ p ] = sourceCache [ p ] ;
3482
+ }
3483
+ }
3484
+ else {
3485
+ // A false result goes straight into global cache (when something is false under assumptions it
3486
+ // will also be false without assumptions)
3487
+ relation [ id ] = false ;
3475
3488
}
3476
3489
return result ;
3477
3490
}
@@ -5399,7 +5412,7 @@ module ts {
5399
5412
return typeArgumentsAreAssignable ;
5400
5413
}
5401
5414
5402
- function checkApplicableSignature ( node : CallLikeExpression , args : Node [ ] , signature : Signature , relation : Map < Ternary > , excludeArgument : boolean [ ] , reportErrors : boolean ) {
5415
+ function checkApplicableSignature ( node : CallLikeExpression , args : Node [ ] , signature : Signature , relation : Map < boolean > , excludeArgument : boolean [ ] , reportErrors : boolean ) {
5403
5416
for ( var i = 0 ; i < args . length ; i ++ ) {
5404
5417
var arg = args [ i ] ;
5405
5418
var argType : Type ;
@@ -5593,7 +5606,7 @@ module ts {
5593
5606
5594
5607
return resolveErrorCall ( node ) ;
5595
5608
5596
- function chooseOverload ( candidates : Signature [ ] , relation : Map < Ternary > ) {
5609
+ function chooseOverload ( candidates : Signature [ ] , relation : Map < boolean > ) {
5597
5610
for ( var i = 0 ; i < candidates . length ; i ++ ) {
5598
5611
if ( ! hasCorrectArity ( node , args , candidates [ i ] ) ) {
5599
5612
continue ;
0 commit comments