6557199: Fails to reject bad override of generic method
Summary: Javac does not correctly implement JLS3 8.4.5
Reviewed-by: jjg
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jan 20 17:49:09 2009 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jan 20 17:49:49 2009 +0000
@@ -2933,32 +2933,16 @@
* Language Specification, Third Ed. (8.4.5)</a>
*/
public boolean returnTypeSubstitutable(Type r1, Type r2) {
+ return returnTypeSubstitutable(r1, r2, Warner.noWarnings);
+ }
+ //where
+ public boolean returnTypeSubstitutable(Type r1, Type r2, Warner warner) {
if (hasSameArgs(r1, r2))
- return resultSubtype(r1, r2, Warner.noWarnings);
+ return resultSubtype(r1, r2, warner);
else
return covariantReturnType(r1.getReturnType(),
- erasure(r2.getReturnType()),
- Warner.noWarnings);
- }
-
- public boolean returnTypeSubstitutable(Type r1,
- Type r2, Type r2res,
- Warner warner) {
- if (isSameType(r1.getReturnType(), r2res))
- return true;
- if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
- return false;
-
- if (hasSameArgs(r1, r2))
- return covariantReturnType(r1.getReturnType(), r2res, warner);
- if (!source.allowCovariantReturns())
- return false;
- if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
- return true;
- if (!isSubtype(r1.getReturnType(), erasure(r2res)))
- return false;
- warner.warnUnchecked();
- return true;
+ r2.getReturnType(),
+ warner);
}
/**
@@ -2966,12 +2950,24 @@
* method that returns s?
*/
public boolean covariantReturnType(Type t, Type s, Warner warner) {
- return
- isSameType(t, s) ||
- source.allowCovariantReturns() &&
+ //are return types identical?
+ if (isSameType(t, s))
+ return true;
+ //if t and s are both reference types...
+ else if(source.allowCovariantReturns() &&
!t.isPrimitive() &&
- !s.isPrimitive() &&
- isAssignable(t, s, warner);
+ !s.isPrimitive()) {
+ //check that t is some unchecked subtype of s
+ if (isSubtypeUnchecked(t, s, warner))
+ return true;
+ //otherwise check that t = |s|
+ else if (isSameType(t, erasure(s))) {
+ warner.warnUnchecked();
+ return true;
+ }
+ }
+ //otherwise t is not return type substitutable for s
+ return false;
}
// </editor-fold>
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Jan 20 17:49:09 2009 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Jan 20 17:49:49 2009 +0000
@@ -1163,7 +1163,7 @@
overrideWarner.warned = false;
boolean resultTypesOK =
- types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
+ types.covariantReturnType(mtres, otres, overrideWarner);
if (!resultTypesOK) {
if (!source.allowCovariantReturns() &&
m.owner != origin &&
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/rawOverride/6557199/T6557199.java Tue Jan 20 17:49:49 2009 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6557199
+ * @summary Fails to reject bad override of generic method
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=T6557199.out T6557199.java -XDrawDiagnostics
+ */
+
+class T6557199 {
+ static class X<S> {
+ public static <U> X<U> test() {
+ return null;
+ }
+ }
+
+ static class B extends X<B> {
+ public static B test() {
+ return null;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/rawOverride/6557199/T6557199.out Tue Jan 20 17:49:49 2009 +0000
@@ -0,0 +1,2 @@
+T6557199.java:40:25: compiler.err.prob.found.req: (- compiler.misc.override.incompatible.ret: (- compiler.misc.cant.override: test(), T6557199.B, <U>test(), T6557199.X)), T6557199.B, T6557199.X<U>
+1 error