### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.compiler 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 18 Apr 2007 08:32:11 -0000 @@ -5302,18 +5302,16 @@ // warning: create() in HashOrder overrides create() in DoubleHash; return type requires unchecked conversion ); } - //https://bugs.eclipse.org/bugs/show_bug.cgi?id=125956 - public void test081() { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=125956 + public void test081a() { this.runNegativeTest( new String[] { "X.java", "public abstract class X implements I {\n" + " public A foo() { return null; }\n" + - " public A bar() { return null; }\n" + "}\n" + "interface I {\n" + " A foo();\n" + - " A bar();\n" + "}\n" + "class A {}" }, @@ -5322,14 +5320,28 @@ " public A foo() { return null; }\r\n" + " ^\n" + "Type safety: The return type A for foo() from the type X needs unchecked conversion to conform to A from the type I\n" + + "----------\n" + ); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=125956 + public void test081b() { + this.runNegativeTest( + new String[] { + "X.java", + "public abstract class X implements I {\n" + + " public A bar() { return null; }\n" + + "}\n" + + "interface I {\n" + + " A bar();\n" + + "}\n" + + "class A {}" + }, "----------\n" + - "2. ERROR in X.java (at line 3)\r\n" + + "1. ERROR in X.java (at line 2)\r\n" + " public A bar() { return null; }\r\n" + " ^^^^\n" + "The return type is incompatible with I.bar()\n" + "----------\n" - // bar() in X cannot implement bar() in I; attempting to use incompatible return type - // warning: foo() in X implements foo() in I; return type requires unchecked conversion ); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=105339 @@ -7544,4 +7556,213 @@ "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) {\n" + + " return null;\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 5)\n" + + " public 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 - 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) {\n" + + " return null;\n" + + " }\n" + + "}\n" + + "class Z {\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " public Object foo(Object o, Object v) {\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) {\n" + + " return null;\n" + + " }\n" + + "}\n" + + "class Z {\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " public Z foo(Object o, Object v) {\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(Object o, V v);\n" + + "}\n" + + "interface X extends I {\n" + + " Object foo(Object o, Object v);\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 5)\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 - simpler test case +public void test132() { + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " U foo();\n" + + "}\n" + + "public class X implements I {\n" + + " public Object foo() {\n" + + " return null;\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " public Object foo() {\n" + + " ^^^^^^\n" + + "The return type is incompatible with I.foo()\n" + + "----------\n"); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789 +// variant +public void test133() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " U foo() {\n" + + " return null;\n" + + " }\n" + + "}\n" + + "class Y extends X {\n" + + " public Z foo() {\n" + + " return null;\n" + + " }\n" + + "}\n" + + "class Z {\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " public Z foo() {\n" + + " ^\n" + + "The return type is incompatible with X.foo()\n" + + "----------\n" + + "2. WARNING in X.java (at line 7)\n" + + " public Z foo() {\n" + + " ^^^^^\n" + + "The method foo() of type Y should be tagged with @Override since it actually overrides a superclass method\n" + + "----------\n"); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789 +// variant - unchecked conversion of ZC to ZC that is a subtype of Z +public void test134() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " Z foo() {\n" + + " return null;\n" + + " }\n" + + "}\n" + + "class Y extends X {\n" + + " public ZC foo() {\n" + + " return null;\n" + + " }\n" + + "}\n" + + "class Z {\n" + + "}\n" + + "class ZC extends Z {\n" + + "}" + }, + "----------\n" + + "1. WARNING in X.java (at line 7)\n" + + " public ZC foo() {\n" + + " ^^\n" + + "ZC is a raw type. References to generic type ZC should be parameterized\n" + + "----------\n" + + "2. WARNING in X.java (at line 7)\n" + + " public ZC foo() {\n" + + " ^^\n" + + "Type safety: The return type ZC for foo() from the type Y needs unchecked conversion to conform to Z from the type X\n" + + "----------\n" + + "3. WARNING in X.java (at line 7)\n" + + " public ZC foo() {\n" + + " ^^^^^\n" + + "The method foo() of type Y should be tagged with @Override since it actually overrides a superclass method\n" + + "----------\n"); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789 +// variant - cast is not appropriate +public void test135() { + this.runNegativeTest( + new String[] { + "X.java", + "interface I {\n" + + " U foo(Object o, V v);\n" + + "}\n" + + "interface J extends I {\n" + + " Object foo(Object o, V v);\n" + + "}\n" + + "class X {\n" + + " J m1;\n" + + " I m2 = (I) m1;\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " Object foo(Object o, V v);\n" + + " ^^^^^^\n" + + "The return type is incompatible with I.foo(Object, V)\n" + + "----------\n" + + "2. WARNING in X.java (at line 9)\n" + + " I m2 = (I) m1;\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Unnecessary cast from J to I\n" + + "----------\n"); +} } 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 18 Apr 2007 08:32:10 -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", @@ -11210,7 +11212,6 @@ "The return type is incompatible with Y.foo2()\n" + "----------\n"); } - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=77496 public void test0385() { this.runNegativeTest( #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 18 Apr 2007 08:32:20 -0000 @@ -71,7 +71,25 @@ } boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) { if (one.returnType == two.returnType) return true; - return areReturnTypesCompatible0(one, two); + if (areReturnTypesCompatible0(one, two)) { + return true; + } + // JLS 3 §8.4.5: more are accepted, with an unchecked conversion + // this case is handled by areReturnTypesCompatible0 + // if (one.returnType.isRawType() && one.returnType.findSuperTypeWithSameErasure(two.returnType) != null) { + // problemReporter(one).unsafeReturnTypeOverride(one, two, this.type); + // return true; + // } + if (one.returnType.equals(two.returnType.erasure())) { + int parametersCount = one.parameters.length; + for (int i = 0; i < parametersCount; i++) { + if (! one.parameters[i].equals(two.parameters[i])) { + problemReporter(one).unsafeReturnTypeOverride(one, two, this.type); + return true; + } + } + } + return false; } boolean areTypesEqual(TypeBinding one, TypeBinding two) { if (one == two) return true;