JDK-8015101 : Covariance of return type implied by upper bounding on type parameter is ignored
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7u7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-03-20
  • Updated: 2014-11-17
  • Resolved: 2014-06-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u20Fixed 9 b19Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
1.7.0_07
1.7.0_09
8.0.0_ea_b65

ADDITIONAL OS VERSION INFORMATION :
Ubuntu 12.10 - 64 bit
Windows 7

A DESCRIPTION OF THE PROBLEM :
The following two interfaces should (and do) compile just fine.

    interface Property<C, S extends C> extends PropertyConst<C> {
        public S get();
    }

    interface PropertyConst<C> {
        public C get();
    }

Here the method 'get()' in 'Property' is covariant wrt to 'get()' in 'PropertyConst' due to the direct upper bounding of the overriding return type by the overridden return type.

In most circumstances this is okay, but in at least one use case the compiler 'forgets' about some aspect of the existing and well defined relationship between the methods in our two interfaces and gives an error indicating that the return types are incompatible, even though we know that this is necessarily never the case.

In particular, the compiler gives an error when we try to use the 'Property' interface as an upper bound on another type parameter, as in:

    <X extends Property<?, ?> & Anything>

Where Anything can be replaced with any interface.

REGRESSION.  Last worked in version 6u31

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to compile the provided test case code as it is. It is the most minimal reduction of the problem I could find.

The implication of this is that when the additional upper bound of 'Anything' is removed from the code it will compile just fine, even though the error has nothing to do with it in any way which is immediately apparent. (On the other hand, 'Anything' can be replaced by any other interface and the code will give the same error.)

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should compile...
ACTUAL -
...But it does not compile.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
  Bug.java:3: error: types PropertyConst<?> and Property<?,?> are incompatible; both define get(), but with unrelated return types
public class Bug<X extends Property<?, ?> & Anything> {
                 ^
1 error

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Bug<X extends Property<?, ?> & Anything> {
}

interface Property<C, S extends C> extends PropertyConst<C> {
    @Override
    public S get();
}

interface PropertyConst<C> {
    public C get();
}

interface Anything {
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use the Eclipse JDT for now ;), it compiles okay there in Juno.

Aside from that I can think of none. Not other than changing design, which I'm not willing to do for the moment.
Comments
Ultimately, the specification for members of intersections involving wildcards needs to be sorted out (JDK-7034922).
05-05-2014

This is related to wildcards types in the component of an intersection type. This is related to the ongoing effort to clarify semantics for intersection types.
23-08-2013

Yes this is reproducible in 7u40 as well as latest 8, it does compile ie 6u31, seems to me it may be yet another type system issue.
07-06-2013