1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jul 22 21:31:14 2011 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jul 27 19:00:53 2011 +0100 1.3 @@ -767,16 +767,13 @@ 1.4 m2.erasure(types).getParameterTypes())) 1.5 return ambiguityError(m1, m2); 1.6 // both abstract, neither overridden; merge throws clause and result type 1.7 - Symbol mostSpecific; 1.8 - if (types.returnTypeSubstitutable(mt1, mt2)) 1.9 - mostSpecific = m1; 1.10 - else if (types.returnTypeSubstitutable(mt2, mt1)) 1.11 - mostSpecific = m2; 1.12 - else { 1.13 + Type mst = mostSpecificReturnType(mt1, mt2); 1.14 + if (mst == null) { 1.15 // Theoretically, this can't happen, but it is possible 1.16 // due to error recovery or mixing incompatible class files 1.17 return ambiguityError(m1, m2); 1.18 } 1.19 + Symbol mostSpecific = mst == mt1 ? m1 : m2; 1.20 List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes()); 1.21 Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown); 1.22 MethodSymbol result = new MethodSymbol( 1.23 @@ -859,6 +856,28 @@ 1.24 } 1.25 } 1.26 //where 1.27 + Type mostSpecificReturnType(Type mt1, Type mt2) { 1.28 + Type rt1 = mt1.getReturnType(); 1.29 + Type rt2 = mt2.getReturnType(); 1.30 + 1.31 + if (mt1.tag == FORALL && mt2.tag == FORALL) { 1.32 + //if both are generic methods, adjust return type ahead of subtyping check 1.33 + rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments()); 1.34 + } 1.35 + //first use subtyping, then return type substitutability 1.36 + if (types.isSubtype(rt1, rt2)) { 1.37 + return mt1; 1.38 + } else if (types.isSubtype(rt2, rt1)) { 1.39 + return mt2; 1.40 + } else if (types.returnTypeSubstitutable(mt1, mt2)) { 1.41 + return mt1; 1.42 + } else if (types.returnTypeSubstitutable(mt2, mt1)) { 1.43 + return mt2; 1.44 + } else { 1.45 + return null; 1.46 + } 1.47 + } 1.48 + //where 1.49 Symbol ambiguityError(Symbol m1, Symbol m2) { 1.50 if (((m1.flags() | m2.flags()) & CLASH) != 0) { 1.51 return (m1.flags() & CLASH) == 0 ? m1 : m2;