# HG changeset patch # User mcimadamore # Date 1370529220 -3600 # Node ID 349160289ba2d42a5f9074816ae546095b160fe4 # Parent 7889d1fe2597941c45422882853dd72a9e52256f 8008627: Compiler mishandles three-way return-type-substitutability Summary: Compiler should not enforce an order in how ambiguous methods should be resolved Reviewed-by: jjg, vromero diff -r 7889d1fe2597 -r 349160289ba2 src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Jun 06 15:32:41 2013 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Jun 06 15:33:40 2013 +0100 @@ -1924,24 +1924,11 @@ Symbol s3 = e.sym; if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue; Type st3 = types.memberType(site,s3); - if (types.overrideEquivalent(st3, st1) && types.overrideEquivalent(st3, st2)) { - if (s3.owner == site.tsym) { - return true; - } - List tvars1 = st1.getTypeArguments(); - List tvars2 = st2.getTypeArguments(); - List tvars3 = st3.getTypeArguments(); - Type rt1 = st1.getReturnType(); - Type rt2 = st2.getReturnType(); - Type rt13 = types.subst(st3.getReturnType(), tvars3, tvars1); - Type rt23 = types.subst(st3.getReturnType(), tvars3, tvars2); - boolean compat = - !rt13.isPrimitiveOrVoid() && - !rt23.isPrimitiveOrVoid() && - (types.covariantReturnType(rt13, rt1, types.noWarnings) && - types.covariantReturnType(rt23, rt2, types.noWarnings)); - if (compat) - return true; + if (types.overrideEquivalent(st3, st1) && + types.overrideEquivalent(st3, st2) && + types.returnTypeSubstitutable(st3, st1) && + types.returnTypeSubstitutable(st3, st2)) { + return true; } } } diff -r 7889d1fe2597 -r 349160289ba2 test/tools/javac/generics/rawOverride/T8008627.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/rawOverride/T8008627.java Thu Jun 06 15:33:40 2013 +0100 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8008627 + * @summary Compiler mishandles three-way return-type-substitutability + * @compile T8008627.java + */ + +class T8008627 { + + interface I { + Object m(Iterable l); + } + + interface J { + S m(Iterable l); + } + + interface K { + T m(Iterable l); + } + + @FunctionalInterface + interface Functional extends I, J, K {} +} diff -r 7889d1fe2597 -r 349160289ba2 test/tools/javac/lambda/funcInterfaces/NonSAM2.java --- a/test/tools/javac/lambda/funcInterfaces/NonSAM2.java Thu Jun 06 15:32:41 2013 +0100 +++ b/test/tools/javac/lambda/funcInterfaces/NonSAM2.java Thu Jun 06 15:33:40 2013 +0100 @@ -13,7 +13,7 @@ interface Foo1Bar1 extends Foo1, Bar1 {} //types Bar1 and Foo1 are incompatible; both define getAge(String), but with unrelated return types interface AC extends A, C {} //name clash: getOldest(List) in C and getOldest(List) in A have the same erasure, yet neither overrides the other -interface ABC extends A, B, C {} //name clash: getOldest(List) in C and getOldest(List) in A have the same erasure, yet neither overrides the other +interface ABC extends A, B, C {} //ok - raw override interface AD extends A, D {} //name clash: getOldest(List) in D and getOldest(List) in A have the same erasure, yet neither overrides the other interface Foo2 { void m(T arg);} diff -r 7889d1fe2597 -r 349160289ba2 test/tools/javac/lambda/funcInterfaces/NonSAM2.out --- a/test/tools/javac/lambda/funcInterfaces/NonSAM2.out Thu Jun 06 15:32:41 2013 +0100 +++ b/test/tools/javac/lambda/funcInterfaces/NonSAM2.out Thu Jun 06 15:33:40 2013 +0100 @@ -1,6 +1,5 @@ NonSAM2.java:13:1: compiler.err.types.incompatible.diff.ret: Bar1, Foo1, getAge(java.lang.String) NonSAM2.java:15:1: compiler.err.name.clash.same.erasure.no.override: getOldest(java.util.List), C, getOldest(java.util.List), A -NonSAM2.java:16:1: compiler.err.name.clash.same.erasure.no.override: getOldest(java.util.List), C, getOldest(java.util.List), A NonSAM2.java:17:1: compiler.err.name.clash.same.erasure.no.override: getOldest(java.util.List), D, getOldest(java.util.List), A NonSAM2.java:21:1: compiler.err.name.clash.same.erasure.no.override: m(S), Bar2, m(T), Foo2 -5 errors +4 errors