### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java,v retrieving revision 1.611 diff -u -r1.611 GenericTypeTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java 13 Apr 2007 14:55:45 -0000 1.611 +++ src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java 20 Apr 2007 19:10:15 -0000 @@ -11170,7 +11170,7 @@ ^ */ } - public void test0384() { + public void test0384a() { this.runConformTest( new String[] { "X.java", @@ -11186,6 +11186,8 @@ "}\n" }, ""); + } + public void test0384b() { this.runNegativeTest( new String[] { "X.java", Index: src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java,v retrieving revision 1.121 diff -u -r1.121 MethodVerifyTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java 28 Mar 2007 04:52:16 -0000 1.121 +++ src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java 20 Apr 2007 19:10:16 -0000 @@ -7544,4 +7544,183 @@ "Type safety: The return type Enum for foo() from the type X.B needs unchecked conversion to conform to U from the type X.A\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789 +public void test128() { + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " U foo(Object o, V v);\n" + + "}\n" + + "public class X implements I {\n" + + " public Object foo(Object o, Object v) { return null; }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 5)\n" + + " public Object foo(Object o, Object v) { return null; }\n" + + " ^^^^^^\n" + + "Type safety: The return type Object for foo(Object, Object) from the type X needs unchecked conversion to conform to U from the type I\n" + + "----------\n" + ); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789 +// variant - Object is not a subtype of Z +public void test129() { + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " U foo(Object o, V v);\n" + + "}\n" + + "public class X implements I {\n" + + " public Object foo(Object o, Object v) { return null; }\n" + + "}\n" + + "class Z {}" + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " public Object foo(Object o, Object v) { return null; }\n" + + " ^^^^^^\n" + + "The return type is incompatible with I.foo(Object, V)\n" + + "----------\n" + ); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789 +// ** variant - Z is not a subtype of Z, and |Z| = Z, not Z +public void test130() { + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " Z foo(Object o, V v);\n" + + "}\n" + + "public class X implements I {\n" + + " public Z foo(Object o, Object v) { return null; }\n" + + "}\n" + + "class Z {}" + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " public Z foo(Object o, Object v) { return null; }\n" + + " ^^^^^^^^^\n" + + "The return type is incompatible with I.foo(Object, V)\n" + + "----------\n" + ); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789 +// variant - two interfaces +public void test131() { + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " U foo();\n" + + " U foo(Object o, V v);\n" + + "}\n" + + "interface X extends I {\n" + + " Object foo();\n" + + " Object foo(Object o, Object v);\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " Object foo();\n" + + " ^^^^^^\n" + + "The return type is incompatible with I.foo()\n" + + "----------\n" + + "2. WARNING in X.java (at line 7)\n" + + " Object foo(Object o, Object v);\n" + + " ^^^^^^\n" + + "Type safety: The return type Object for foo(Object, Object) from the type X needs unchecked conversion to conform to U from the type I\n" + + "----------\n" + ); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789 +// variant - type identity vs type equivalence +public void test132() { + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " U foo(I p);\n" + + " U foo2(I p);\n" + + "}\n" + + "public class X implements I {\n" + + " public Object foo(I p) { return null; }\n" + + " public Object foo2(I p) { return null; }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " public Object foo(I p) { return null; }\n" + + " ^^^^^^\n" + + "The return type is incompatible with I.foo(I)\n" + + "----------\n" + + "2. ERROR in X.java (at line 7)\n" + + " public Object foo2(I p) { return null; }\n" + + " ^^^^^^\n" + + "The return type is incompatible with I.foo2(I)\n" + + "----------\n" + ); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789 +// variant - if we detect a return type incompatibility, then skip any @Override errors +public void test133() { + this.runNegativeTest( + new String[] { + "A.java", + "class A {\n" + + " U foo() { return null; }\n" + + " U foo(U one) { return null; }\n" + + " U foo(U one, U two) { return null; }\n" + + "}\n" + + "class B extends A {\n" + + " @Override // does not override error\n" + + " Object foo() { return null; } // cannot override foo(), incompatible return type error\n" + + " @Override // does not override error\n" + + " Object foo(Object one) { return null; } // unchecked conversion warning\n" + + " @Override // does not override error\n" + + " Object foo(Object one, U two) { return null; }\n" + + "}\n" + + "class C extends A {\n" + + " @Override // does not override error\n" + + " Object foo(U one) { return null; } // cannot override foo(U), incompatible return type error\n" + + " @Override // does not override error\n" + + " Object foo(U one, U two) { return null; } // cannot override foo(U), incompatible return type error\n" + + "}" + }, + "----------\n" + + "1. ERROR in A.java (at line 8)\n" + + " Object foo() { return null; } // cannot override foo(), incompatible return type error\n" + + " ^^^^^^\n" + + "The return type is incompatible with A.foo()\n" + + "----------\n" + + "2. WARNING in A.java (at line 10)\n" + + " Object foo(Object one) { return null; } // unchecked conversion warning\n" + + " ^^^^^^\n" + + "Type safety: The return type Object for foo(Object) from the type B needs unchecked conversion to conform to U from the type A\n" + + "----------\n" + + "3. ERROR in A.java (at line 12)\n" + + " Object foo(Object one, U two) { return null; }\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Name clash: The method foo(Object, U) of type B has the same erasure as foo(U, U) of type A but does not override it\n" + + "----------\n" + + "4. ERROR in A.java (at line 12)\n" + + " Object foo(Object one, U two) { return null; }\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "The method foo(Object, U) of type B must override a superclass method\n" + + "----------\n" + + "5. ERROR in A.java (at line 16)\n" + + " Object foo(U one) { return null; } // cannot override foo(U), incompatible return type error\n" + + " ^^^^^^\n" + + "The return type is incompatible with A.foo(U)\n" + + "----------\n" + + "6. ERROR in A.java (at line 18)\n" + + " Object foo(U one, U two) { return null; } // cannot override foo(U), incompatible return type error\n" + + " ^^^^^^\n" + + "The return type is incompatible with A.foo(U, U)\n" + + "----------\n" + ); +} } #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java,v retrieving revision 1.74 diff -u -r1.74 MethodVerifier15.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java 17 Apr 2007 14:34:08 -0000 1.74 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java 20 Apr 2007 19:10:18 -0000 @@ -769,6 +769,18 @@ return copy; } boolean reportIncompatibleReturnTypeError(MethodBinding currentMethod, MethodBinding inheritedMethod) { + // JLS 3 §8.4.5: more are accepted, with an unchecked conversion + if (currentMethod.returnType == inheritedMethod.returnType.erasure()) { + TypeBinding[] currentParams = currentMethod.parameters; + TypeBinding[] inheritedParams = inheritedMethod.parameters; + for (int i = 0, l = currentParams.length; i < l; i++) { + if (!areTypesEqual(currentParams[i], inheritedParams[i])) { + problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, inheritedMethod, this.type); + return false; + } + } + } + if (currentMethod.typeVariables == Binding.NO_TYPE_VARIABLES && inheritedMethod.original().typeVariables != Binding.NO_TYPE_VARIABLES && currentMethod.returnType.erasure().findSuperTypeWithSameErasure(inheritedMethod.returnType.erasure()) != null) {