@@ -364,13 +364,45 @@ private predicate typeFlow(TypeFlowNode n, RefType t) {
364
364
typeFlowJoin ( lastRank ( n ) , n , t )
365
365
}
366
366
367
+ pragma [ nomagic]
368
+ predicate erasedTypeBound ( RefType t ) {
369
+ exists ( RefType t0 | typeFlow ( _, t0 ) and t = t0 .getErasure ( ) )
370
+ }
371
+
372
+ pragma [ nomagic]
373
+ predicate typeBound ( RefType t ) { typeFlow ( _, t ) }
374
+
375
+ /**
376
+ * Holds if we have a bound for `n` that is better than `t`, taking only erased
377
+ * types into account.
378
+ */
379
+ pragma [ nomagic]
380
+ private predicate irrelevantErasedBound ( TypeFlowNode n , RefType t ) {
381
+ exists ( RefType bound |
382
+ typeFlow ( n , bound )
383
+ or
384
+ n .getType ( ) = bound and typeFlow ( n , _)
385
+ |
386
+ t = bound .getErasure ( ) .( RefType ) .getASourceSupertype + ( ) and
387
+ erasedTypeBound ( t )
388
+ )
389
+ }
390
+
367
391
/**
368
392
* Holds if we have a bound for `n` that is better than `t`.
369
393
*/
370
- pragma [ noinline ]
394
+ pragma [ nomagic ]
371
395
private predicate irrelevantBound ( TypeFlowNode n , RefType t ) {
372
- exists ( RefType bound | typeFlow ( n , bound ) or n .getType ( ) = bound |
373
- t = bound .getErasure ( ) .( RefType ) .getASourceSupertype + ( )
396
+ exists ( RefType bound |
397
+ typeFlow ( n , bound ) and
398
+ t = bound .getASupertype + ( ) and
399
+ typeBound ( t ) and
400
+ typeFlow ( n , t ) and
401
+ not t .getASupertype * ( ) = bound
402
+ or
403
+ n .getType ( ) = bound and
404
+ typeFlow ( n , t ) and
405
+ t = bound .getASupertype * ( )
374
406
)
375
407
}
376
408
@@ -380,7 +412,8 @@ private predicate irrelevantBound(TypeFlowNode n, RefType t) {
380
412
*/
381
413
private predicate bestTypeFlow ( TypeFlowNode n , RefType t ) {
382
414
typeFlow ( n , t ) and
383
- not irrelevantBound ( n , t .getErasure ( ) )
415
+ not irrelevantErasedBound ( n , t .getErasure ( ) ) and
416
+ not irrelevantBound ( n , t )
384
417
}
385
418
386
419
cached
0 commit comments