765 // check that both signatures have the same erasure |
765 // check that both signatures have the same erasure |
766 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), |
766 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), |
767 m2.erasure(types).getParameterTypes())) |
767 m2.erasure(types).getParameterTypes())) |
768 return ambiguityError(m1, m2); |
768 return ambiguityError(m1, m2); |
769 // both abstract, neither overridden; merge throws clause and result type |
769 // both abstract, neither overridden; merge throws clause and result type |
770 Symbol mostSpecific; |
770 Type mst = mostSpecificReturnType(mt1, mt2); |
771 if (types.returnTypeSubstitutable(mt1, mt2)) |
771 if (mst == null) { |
772 mostSpecific = m1; |
|
773 else if (types.returnTypeSubstitutable(mt2, mt1)) |
|
774 mostSpecific = m2; |
|
775 else { |
|
776 // Theoretically, this can't happen, but it is possible |
772 // Theoretically, this can't happen, but it is possible |
777 // due to error recovery or mixing incompatible class files |
773 // due to error recovery or mixing incompatible class files |
778 return ambiguityError(m1, m2); |
774 return ambiguityError(m1, m2); |
779 } |
775 } |
|
776 Symbol mostSpecific = mst == mt1 ? m1 : m2; |
780 List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes()); |
777 List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes()); |
781 Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown); |
778 Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown); |
782 MethodSymbol result = new MethodSymbol( |
779 MethodSymbol result = new MethodSymbol( |
783 mostSpecific.flags(), |
780 mostSpecific.flags(), |
784 mostSpecific.name, |
781 mostSpecific.name, |
854 args.append(types.elemtype(varargsTypeTo)); |
851 args.append(types.elemtype(varargsTypeTo)); |
855 Type mtype = types.createMethodTypeWithParameters(to.type, args.toList()); |
852 Type mtype = types.createMethodTypeWithParameters(to.type, args.toList()); |
856 return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner); |
853 return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner); |
857 } else { |
854 } else { |
858 return to; |
855 return to; |
|
856 } |
|
857 } |
|
858 //where |
|
859 Type mostSpecificReturnType(Type mt1, Type mt2) { |
|
860 Type rt1 = mt1.getReturnType(); |
|
861 Type rt2 = mt2.getReturnType(); |
|
862 |
|
863 if (mt1.tag == FORALL && mt2.tag == FORALL) { |
|
864 //if both are generic methods, adjust return type ahead of subtyping check |
|
865 rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments()); |
|
866 } |
|
867 //first use subtyping, then return type substitutability |
|
868 if (types.isSubtype(rt1, rt2)) { |
|
869 return mt1; |
|
870 } else if (types.isSubtype(rt2, rt1)) { |
|
871 return mt2; |
|
872 } else if (types.returnTypeSubstitutable(mt1, mt2)) { |
|
873 return mt1; |
|
874 } else if (types.returnTypeSubstitutable(mt2, mt1)) { |
|
875 return mt2; |
|
876 } else { |
|
877 return null; |
859 } |
878 } |
860 } |
879 } |
861 //where |
880 //where |
862 Symbol ambiguityError(Symbol m1, Symbol m2) { |
881 Symbol ambiguityError(Symbol m1, Symbol m2) { |
863 if (((m1.flags() | m2.flags()) & CLASH) != 0) { |
882 if (((m1.flags() | m2.flags()) & CLASH) != 0) { |