503 } |
503 } |
504 if (bestSoFar == null) return null; |
504 if (bestSoFar == null) return null; |
505 |
505 |
506 //merge thrown types - form the intersection of all the thrown types in |
506 //merge thrown types - form the intersection of all the thrown types in |
507 //all the signatures in the list |
507 //all the signatures in the list |
|
508 boolean toErase = !bestSoFar.type.hasTag(FORALL); |
508 List<Type> thrown = null; |
509 List<Type> thrown = null; |
509 for (Symbol msym1 : methodSyms) { |
510 Type mt1 = memberType(origin.type, bestSoFar); |
510 Type mt1 = memberType(origin.type, msym1); |
511 for (Symbol msym2 : methodSyms) { |
|
512 Type mt2 = memberType(origin.type, msym2); |
|
513 List<Type> thrown_mt2 = mt2.getThrownTypes(); |
|
514 if (toErase) { |
|
515 thrown_mt2 = erasure(thrown_mt2); |
|
516 } else { |
|
517 /* If bestSoFar is generic then all the methods are generic. |
|
518 * The opposite is not true: a non generic method can override |
|
519 * a generic method (raw override) so it's safe to cast mt1 and |
|
520 * mt2 to ForAll. |
|
521 */ |
|
522 ForAll fa1 = (ForAll)mt1; |
|
523 ForAll fa2 = (ForAll)mt2; |
|
524 thrown_mt2 = subst(thrown_mt2, fa2.tvars, fa1.tvars); |
|
525 } |
511 thrown = (thrown == null) ? |
526 thrown = (thrown == null) ? |
512 mt1.getThrownTypes() : |
527 thrown_mt2 : |
513 chk.intersect(mt1.getThrownTypes(), thrown); |
528 chk.intersect(thrown_mt2, thrown); |
514 } |
529 } |
515 |
530 |
516 final List<Type> thrown1 = thrown; |
531 final List<Type> thrown1 = thrown; |
517 return new FunctionDescriptor(bestSoFar) { |
532 return new FunctionDescriptor(bestSoFar) { |
518 @Override |
533 @Override |