changeset 961:32565546784b

7022054: Invalid compiler error on covariant overriding methods with the same erasure Summary: Rules for method clash use notion of subsignature, which is sometimes too strict and incompatible with JDK 6 Reviewed-by: jjg
author mcimadamore
date Thu, 03 Mar 2011 17:34:58 +0000
parents c15d788cb381
children 8fb48a9ac9ec
files src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Check.java test/tools/javac/generics/7022054/T7022054neg1.java test/tools/javac/generics/7022054/T7022054neg1.out test/tools/javac/generics/7022054/T7022054neg2.java test/tools/javac/generics/7022054/T7022054neg2.out test/tools/javac/generics/7022054/T7022054pos1.java test/tools/javac/generics/7022054/T7022054pos2.java
diffstat 8 files changed, 146 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Mar 03 17:32:35 2011 +0000
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Mar 03 17:34:58 2011 +0000
@@ -1992,7 +1992,11 @@
      * @return true if t is a sub signature of s.
      */
     public boolean isSubSignature(Type t, Type s) {
-        return hasSameArgs(t, s) || hasSameArgs(t, erasure(s));
+        return isSubSignature(t, s, true);
+    }
+
+    public boolean isSubSignature(Type t, Type s, boolean strict) {
+        return hasSameArgs(t, s, strict) || hasSameArgs(t, erasure(s), strict);
     }
 
     /**
@@ -2129,10 +2133,24 @@
      * where correspondence is by position in the type parameter list.
      */
     public boolean hasSameArgs(Type t, Type s) {
+        return hasSameArgs(t, s, true);
+    }
+
+    public boolean hasSameArgs(Type t, Type s, boolean strict) {
+        return hasSameArgs(t, s, strict ? hasSameArgs_strict : hasSameArgs_nonstrict);
+    }
+
+    private boolean hasSameArgs(Type t, Type s, TypeRelation hasSameArgs) {
         return hasSameArgs.visit(t, s);
     }
     // where
-        private TypeRelation hasSameArgs = new TypeRelation() {
+        private class HasSameArgs extends TypeRelation {
+
+            boolean strict;
+
+            public HasSameArgs(boolean strict) {
+                this.strict = strict;
+            }
 
             public Boolean visitType(Type t, Type s) {
                 throw new AssertionError();
@@ -2147,7 +2165,7 @@
             @Override
             public Boolean visitForAll(ForAll t, Type s) {
                 if (s.tag != FORALL)
-                    return false;
+                    return strict ? false : visitMethodType(t.asMethodType(), s);
 
                 ForAll forAll = (ForAll)s;
                 return hasSameBounds(t, forAll)
@@ -2159,6 +2177,10 @@
                 return false;
             }
         };
+
+        TypeRelation hasSameArgs_strict = new HasSameArgs(true);
+        TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false);
+
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="subst">
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Mar 03 17:32:35 2011 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Mar 03 17:34:58 2011 +0000
@@ -2114,7 +2114,7 @@
                 if (s1 == s2 || !sym.overrides(s2, site.tsym, types, false)) continue;
                 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
                 //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
-                if (!types.isSubSignature(sym.type, types.memberType(site, s1)) &&
+                if (!types.isSubSignature(sym.type, types.memberType(site, s1), false) &&
                         types.hasSameArgs(s1.erasure(types), s2.erasure(types))) {
                     sym.flags_field |= CLASH;
                     String key = s2 == sym ?
@@ -2146,7 +2146,7 @@
         for (Symbol s : types.membersClosure(site).getElementsByName(sym.name, cf)) {
             //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
             //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
-            if (!types.isSubSignature(sym.type, types.memberType(site, s)) &&
+            if (!types.isSubSignature(sym.type, types.memberType(site, s), false) &&
                     types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
                 log.error(pos,
                         "name.clash.same.erasure.no.hide",
@@ -2667,7 +2667,7 @@
                 if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
                     varargsDuplicateError(pos, sym, e.sym);
                     return true;
-                } else if (sym.kind == MTH && !hasSameSignature(sym.type, e.sym.type)) {
+                } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, e.sym.type, false)) {
                     duplicateErasureError(pos, sym, e.sym);
                     sym.flags_field |= CLASH;
                     return true;
@@ -2679,15 +2679,6 @@
         }
         return true;
     }
-    //where
-        boolean hasSameSignature(Type mt1, Type mt2) {
-            if (mt1.tag == FORALL && mt2.tag == FORALL) {
-                ForAll fa1 = (ForAll)mt1;
-                ForAll fa2 = (ForAll)mt2;
-                mt2 = types.subst(fa2, fa2.tvars, fa1.tvars);
-            }
-            return types.hasSameArgs(mt1.asMethodType(), mt2.asMethodType());
-        }
 
     /** Report duplicate declaration error.
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/7022054/T7022054neg1.java	Thu Mar 03 17:34:58 2011 +0000
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7022054
+ *
+ * @summary  Invalid compiler error on covariant overriding methods with the same erasure
+ * @compile/fail/ref=T7022054neg1.out -XDrawDiagnostics T7022054neg1.java
+ *
+ */
+
+class T7022054neg1 {
+    static class A {
+        A m(String s) { return null; }
+    }
+    static class B extends A {
+        <X extends String> A m(X s) { return null; }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/7022054/T7022054neg1.out	Thu Mar 03 17:34:58 2011 +0000
@@ -0,0 +1,2 @@
+T7022054neg1.java:15:30: compiler.err.name.clash.same.erasure.no.override: <X>m(X), T7022054neg1.B, m(java.lang.String), T7022054neg1.A, <X>m(X), T7022054neg1.B
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/7022054/T7022054neg2.java	Thu Mar 03 17:34:58 2011 +0000
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7022054
+ *
+ * @summary  Invalid compiler error on covariant overriding methods with the same erasure
+ * @compile/fail/ref=T7022054neg2.out -XDrawDiagnostics T7022054neg2.java
+ *
+ */
+
+class T7022054neg2 {
+    static class A {
+        static A m(String s) { return null; }
+    }
+    static class B extends A {
+        static <X extends String> A m(X s) { return null; }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/7022054/T7022054neg2.out	Thu Mar 03 17:34:58 2011 +0000
@@ -0,0 +1,2 @@
+T7022054neg2.java:15:37: compiler.err.name.clash.same.erasure.no.hide: <X>m(X), T7022054neg2.B, m(java.lang.String), T7022054neg2.A
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/7022054/T7022054pos1.java	Thu Mar 03 17:34:58 2011 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 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 7022054
+ *
+ * @summary  Invalid compiler error on covariant overriding methods with the same erasure
+ * @compile T7022054pos1.java
+ *
+ */
+
+class T7022054pos1 {
+    static class A {
+        A m(String s) { return null; }
+    }
+    static class B extends A {
+        <X extends B> X m(String s) { return null; }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/7022054/T7022054pos2.java	Thu Mar 03 17:34:58 2011 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 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 7022054
+ *
+ * @summary  Invalid compiler error on covariant overriding methods with the same erasure
+ * @compile T7022054pos2.java
+ *
+ */
+
+class T7022054pos2 {
+    static class A {
+        static A m(String s) { return null; }
+    }
+    static class B extends A {
+        static <X extends B> X m(String s) { return null; }
+    }
+}