JDK-7190296 : unsoundness in type-containment implementation
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: unknown
  • Submitted: 2012-08-09
  • Updated: 2016-01-15
  • Resolved: 2015-12-17
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.
9 b99Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
The following program does not compile with javac - but is accepted by Eclipse

interface Foo<X extends Comparable<X>> {
   List<X> getList();

class Test {
   <T extends Comparable<? super T>> List<T> m(List<T> arg) { return null; }
   void test(Foo<?> foo) {

Bug has been fixed, but I'm going to push the test, since it's different than the other cases covered by JDK-8033718.

Was fixed with JDK-8033718.

Deferring to 9 - while this is an unsoundness in the implementation, fixing it would break several assertions in the implementation, so more investigation work is required.

EVALUATION The problem is caused by a bug in type-containment implementation. The compiler infers #1 for T - but the subsequent bound check fails - here's what the bound check looks like: #1 <: [T = #1]Comparable<? super T> == Comparable<? super #1> [where #1 <: Object] Comparable<#1> <: Comparable<? super #1> Now, here's where the unsoundness occur - javac does the following: #1 <: ? super #1 #1 <: lower(#1) //<---------- #1 <: <nulltype> false. There is an extra application of 'lower' on the LHS of the type-containment test. The right thing (as per JLS) would be the following: #1 <: ? super #1 #1 <: #1 true. Note: removing upper/lower bound calculation from type-containment can easily result in type-inference side-effects (i.e. because a type that used to be inferred as lower(T) would now be inferred as T). So, any change to the way in which javac performs type-containment will likely need to be compensated by a change in how bounds are set on inference variables [esp. when one side of the inference constraint is a captured type-variable].