Summary: | Invalid incompatible return type error | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Product: | [Eclipse Project] JDT | Reporter: | Divyanshu Sharma <divyanshu.sharma> | ||||||||
Component: | Core | Assignee: | Kent Johnson <kent_johnson> | ||||||||
Status: | VERIFIED FIXED | QA Contact: | |||||||||
Severity: | critical | ||||||||||
Priority: | P3 | CC: | david_audel, Olivier_Thomann, philippe_mulet | ||||||||
Version: | 3.3.2 | ||||||||||
Target Milestone: | 3.4 M7 | ||||||||||
Hardware: | PC | ||||||||||
OS: | Windows XP | ||||||||||
Whiteboard: | |||||||||||
Attachments: |
|
Description
Divyanshu Sharma
2008-03-25 17:30:28 EDT
The test case is incomplete. The package test.intf is missing. What are your compiler settings for your project ? Did you set the compliance to be 1.5 ? Need more info. Created attachment 93581 [details]
Test case
Apologies for missing package. Compiler Compliance level set to 5.0
Please find below the missing package interfaces:
-----------------------------------------------------------------------
package test.intf;
public interface SubOne<Owner> extends SuperType<Owner>
{
public SubOne<Owner> plus(SubOne addend);
public SubTwo<Owner> plus(SubTwo addend);
}
-------------------------------------------------------------------------
package test.intf;
public interface SubTwo<Owner> extends SuperType<Owner>
{
public SubTwo<Owner> plus(SubOne addend);
public SubTwo<Owner> plus(SubTwo addend);
}
--------------------------------------------------------------------------
package test.intf;
public interface SuperType<Owner>
{
public SuperType<Owner> plus(SubOne addend);
public SuperType<Owner> plus(SubTwo addend);
}
---------------------------------------------------------------------------
Reproduced with HEAD. We issue 2 complaints against SubSubOneImpl ---------- 1. ERROR in test\impl\SubSubOneImpl.java (at line 3) public abstract class SubSubOneImpl extends SubOneImpl { ^^^^^^^^^^^^^ The return type is incompatible with SuperTypeExtend.plus(SubTwo), SubOne.plus(SubTwo) ---------- 2. ERROR in test\impl\SubSubOneImpl.java (at line 3) public abstract class SubSubOneImpl extends SubOneImpl { ^^^^^^^^^^^^^ The return type is incompatible with SuperTypeExtend.plus(SubOne), SubOne.plus(SubOne) ---------- Added (disabled) MethodVerifierTest#_test153 Kent - putting all in one file makes the problem go away... !? abstract class SubOneImpl extends SuperTypeExtendImpl implements test.intf.SubOne { public SubOneImpl plus(test.intf.SubOne attribute) { throw new RuntimeException("foo"); } public SubTwoImpl plus(SubTwo attribute) { throw new RuntimeException("foo"); } } abstract class SubSubOneImpl extends SubOneImpl { } abstract class SubTwoImpl extends SuperTypeExtendImpl implements test.intf.SubTwo { public SubTwoImpl plus(SubOne attribute) { throw new RuntimeException("foo"); } public SubTwoImpl plus(test.intf.SubTwo attribute) { throw new RuntimeException("foo"); } } interface SuperTypeExtend extends test.intf.SuperType { public SuperTypeExtend plus(SubOne addend); public SuperTypeExtend plus(SubTwo addend); } abstract class SuperTypeExtendImpl implements SuperTypeExtend { } interface SubOne<Owner> extends SuperType<Owner> { public SubOne<Owner> plus(SubOne addend); public SubTwo<Owner> plus(SubTwo addend); } interface SubTwo<Owner> extends SuperType<Owner> { public SubTwo<Owner> plus(SubOne addend); public SubTwo<Owner> plus(SubTwo addend); } interface SuperType<Owner> { public SuperType<Owner> plus(SubOne addend); public SuperType<Owner> plus(SubTwo addend); } Ignore my last comment, I had left some qualifier in some type names, all in one file does reproduce the issue. abstract class SubOneImpl extends SuperTypeExtendImpl implements SubOne { public SubOneImpl plus(SubOne attribute) { throw new RuntimeException("foo"); } public SubTwoImpl plus(SubTwo attribute) { throw new RuntimeException("foo"); } } abstract class SubSubOneImpl extends SubOneImpl { } abstract class SubTwoImpl extends SuperTypeExtendImpl implements SubTwo { public SubTwoImpl plus(SubOne attribute) { throw new RuntimeException("foo"); } public SubTwoImpl plus(SubTwo attribute) { throw new RuntimeException("foo"); } } interface SuperTypeExtend extends SuperType { public SuperTypeExtend plus(SubOne addend); public SuperTypeExtend plus(SubTwo addend); } abstract class SuperTypeExtendImpl implements SuperTypeExtend { } interface SubOne<Owner> extends SuperType<Owner> { public SubOne<Owner> plus(SubOne addend); public SubTwo<Owner> plus(SubTwo addend); } interface SubTwo<Owner> extends SuperType<Owner> { public SubTwo<Owner> plus(SubOne addend); public SubTwo<Owner> plus(SubTwo addend); } interface SuperType<Owner> { public SuperType<Owner> plus(SubOne addend); public SuperType<Owner> plus(SubTwo addend); } Simpler testcase: import java.io.Serializable; interface AFoo { Serializable foo(); Serializable bar(); } interface BFoo { Cloneable foo(); Cloneable bar(); } interface C extends Serializable, Cloneable {} class Root { public C foo() { return null; } } public abstract class X extends Root implements AFoo, BFoo { } javac reports 1 error (against #bar()), we report 2 (#bar() and #foo()). Method verifier seems to go too deep in inherited method chain. It should stop investigation when noticing super method definition Root#foo(). If such a method got defined, then it supercedes the other ones if it looks like an implementation for these. Also added MethodVerifierTest#test154-158 (some disabled) Created attachment 93830 [details]
Proposed patch with testcase
Created attachment 93854 [details]
Updated patch
Released into HEAD for 3.4M7 Verified for 3.4M7 using I20080427-2000 |