6985719: Alike methods in interfaces (Inheritance and Overriding)
Summary: javac should report error when interface inherits unrelated method with same erasure
Reviewed-by: jjg
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Sun Nov 14 07:16:46 2010 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Nov 15 13:50:53 2010 +0000
@@ -1510,14 +1510,7 @@
Type t1,
Type t2,
Type site) {
- Symbol sym = firstIncompatibility(t1, t2, site);
- if (sym != null) {
- log.error(pos, "types.incompatible.diff.ret",
- t1, t2, sym.name +
- "(" + types.memberType(t2, sym).getParameterTypes() + ")");
- return false;
- }
- return true;
+ return firstIncompatibility(pos, t1, t2, site) == null;
}
/** Return the first method which is defined with same args
@@ -1528,7 +1521,7 @@
* @param site The most derived type.
* @returns symbol from t2 that conflicts with one in t1.
*/
- private Symbol firstIncompatibility(Type t1, Type t2, Type site) {
+ private Symbol firstIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
Map<TypeSymbol,Type> interfaces1 = new HashMap<TypeSymbol,Type>();
closure(t1, interfaces1);
Map<TypeSymbol,Type> interfaces2;
@@ -1539,7 +1532,7 @@
for (Type t3 : interfaces1.values()) {
for (Type t4 : interfaces2.values()) {
- Symbol s = firstDirectIncompatibility(t3, t4, site);
+ Symbol s = firstDirectIncompatibility(pos, t3, t4, site);
if (s != null) return s;
}
}
@@ -1568,7 +1561,7 @@
}
/** Return the first method in t2 that conflicts with a method from t1. */
- private Symbol firstDirectIncompatibility(Type t1, Type t2, Type site) {
+ private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
Symbol s1 = e1.sym;
Type st1 = null;
@@ -1592,7 +1585,18 @@
(types.covariantReturnType(rt1, rt2, Warner.noWarnings) ||
types.covariantReturnType(rt2, rt1, Warner.noWarnings)) ||
checkCommonOverriderIn(s1,s2,site);
- if (!compat) return s2;
+ if (!compat) {
+ log.error(pos, "types.incompatible.diff.ret",
+ t1, t2, s2.name +
+ "(" + types.memberType(t2, s2).getParameterTypes() + ")");
+ return s2;
+ }
+ } else if (!checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
+ log.error(pos,
+ "name.clash.same.erasure.no.override",
+ s1, s1.location(),
+ s2, s2.location());
+ return s2;
}
}
}
@@ -1644,32 +1648,52 @@
log.error(tree.pos(), "enum.no.finalize");
return;
}
- for (Type t = types.supertype(origin.type); t.tag == CLASS;
+ for (Type t = origin.type; t.tag == CLASS;
t = types.supertype(t)) {
- TypeSymbol c = t.tsym;
- Scope.Entry e = c.members().lookup(m.name);
- while (e.scope != null) {
- if (m.overrides(e.sym, origin, types, false))
- checkOverride(tree, m, (MethodSymbol)e.sym, origin);
- else if (e.sym.kind == MTH &&
- e.sym.isInheritedIn(origin, types) &&
- (e.sym.flags() & SYNTHETIC) == 0 &&
- !m.isConstructor()) {
- Type er1 = m.erasure(types);
- Type er2 = e.sym.erasure(types);
- if (types.isSameTypes(er1.getParameterTypes(),
- er2.getParameterTypes())) {
- log.error(TreeInfo.diagnosticPositionFor(m, tree),
- "name.clash.same.erasure.no.override",
- m, m.location(),
- e.sym, e.sym.location());
- }
- }
- e = e.next();
+ if (t != origin.type) {
+ checkOverride(tree, t, origin, m);
+ }
+ for (Type t2 : types.interfaces(t)) {
+ checkOverride(tree, t2, origin, m);
}
}
}
+ void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
+ TypeSymbol c = site.tsym;
+ Scope.Entry e = c.members().lookup(m.name);
+ while (e.scope != null) {
+ if (m.overrides(e.sym, origin, types, false)) {
+ if ((e.sym.flags() & ABSTRACT) == 0) {
+ checkOverride(tree, m, (MethodSymbol)e.sym, origin);
+ }
+ }
+ else if (!checkNameClash(origin, e.sym, m)) {
+ log.error(tree,
+ "name.clash.same.erasure.no.override",
+ m, m.location(),
+ e.sym, e.sym.location());
+ }
+ e = e.next();
+ }
+ }
+
+ private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
+ if (s1.kind == MTH &&
+ s1.isInheritedIn(origin, types) &&
+ (s1.flags() & SYNTHETIC) == 0 &&
+ !s2.isConstructor()) {
+ Type er1 = s2.erasure(types);
+ Type er2 = s1.erasure(types);
+ if (types.isSameTypes(er1.getParameterTypes(),
+ er2.getParameterTypes())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
/** Check that all abstract members of given class have definitions.
* @param pos Position to be used for error reporting.
* @param c The class.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719a.java Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719a.out -XDrawDiagnostics T6985719a.java
+ */
+
+import java.util.List;
+
+class T6985719a {
+ interface A { void f(List<String> ls); }
+ interface B { void f(List<Integer> ls); }
+ interface C extends A,B {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719a.out Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,2 @@
+T6985719a.java:14:5: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719a.B, f(java.util.List<java.lang.String>), T6985719a.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719b.java Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719b.out -XDrawDiagnostics T6985719b.java
+ */
+
+import java.util.List;
+
+class T6985719b {
+ abstract class A { abstract void f(List<String> ls); }
+ interface B { void f(List<Integer> ls); }
+ abstract class C extends A implements B {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719b.out Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,2 @@
+T6985719b.java:14:14: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719b.B, f(java.util.List<java.lang.String>), T6985719b.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719c.java Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719c.out -XDrawDiagnostics T6985719c.java
+ */
+
+import java.util.List;
+
+class T6985719c {
+ interface A { void f(List<String> ls); }
+ interface B<X> { void f(List<X> ls); }
+ interface C extends A,B<Integer> {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719c.out Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,2 @@
+T6985719c.java:14:5: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<X>), T6985719c.B, f(java.util.List<java.lang.String>), T6985719c.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719d.java Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719d.out -XDrawDiagnostics T6985719d.java
+ */
+
+import java.util.List;
+
+class T6985719d {
+ abstract class A { abstract void f(List<String> ls); }
+ interface B<X> { void f(List<X> ls); }
+ abstract class C extends A implements B<Integer> {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719d.out Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,2 @@
+T6985719d.java:14:14: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<X>), T6985719d.B, f(java.util.List<java.lang.String>), T6985719d.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719e.java Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719e.out -XDrawDiagnostics T6985719e.java
+ */
+
+import java.util.List;
+
+class T6985719e {
+ interface A { void f(List<String> ls); }
+ interface B extends A { void f(List<Integer> ls); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719e.out Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,2 @@
+T6985719e.java:13:34: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719e.B, f(java.util.List<java.lang.String>), T6985719e.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719f.java Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719f.out -XDrawDiagnostics T6985719f.java
+ */
+
+import java.util.List;
+
+class T6985719f {
+ abstract class A { abstract void f(List<String> ls); }
+ abstract class B extends A { void f(List<Integer> ls); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719f.out Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,2 @@
+T6985719f.java:13:39: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719f.B, f(java.util.List<java.lang.String>), T6985719f.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719g.java Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719g.out -XDrawDiagnostics T6985719g.java
+ */
+
+import java.util.List;
+
+class T6985719g {
+ interface A<X> { void f(List<X> ls); }
+ interface B extends A<String> { void f(List<Integer> ls); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719g.out Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,2 @@
+T6985719g.java:13:42: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719g.B, f(java.util.List<X>), T6985719g.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719h.java Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719h.out -XDrawDiagnostics T6985719h.java
+ */
+
+import java.util.List;
+
+class T6985719h {
+ abstract class A<X> { abstract void f(List<X> ls); }
+ abstract class B extends A<String> { abstract void f(List<Integer> ls); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719h.out Mon Nov 15 13:50:53 2010 +0000
@@ -0,0 +1,2 @@
+T6985719h.java:13:56: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719h.B, f(java.util.List<X>), T6985719h.A
+1 error