JDK-6835428 : regression: return-type inference rejects valid code
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: unknown
  • Submitted: 2009-04-29
  • Updated: 2012-01-13
  • Resolved: 2012-01-13
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 7
7 b64Fixed
Related Reports
Relates :  
Relates :  
Description
import java.util.Comparator;
import java.util.List;

class Test {
   <T extends Comparable<? super T>> Comparator<List<T>> comparator() { return null; }
   static <T extends Comparable<? super T>> void f() {
      Comparator<List<T>> comparator = comparator();  // [*]
   }
}


this program is rejected with the following error message:

 type parameters of <T>java.util.Comparator<java.util.List<T>> cannot be determined;
    no unique maximal instance exists for type variable T with upper bounds java.lang.Comparable<? super T>



See also http://www.netbeans.org/issues/show_bug.cgi?id=163967
http://www.netbeans.org/issues/show_bug.cgi?id=163969

Comments
SUGGESTED FIX A webrev of this fix is available at the following URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/3ac205ad1f05
16-06-2009

EVALUATION Note that this the problem of undetvar's upper bound possibly containing 'naked' type-variables is also addressed by 6369605 (in a more complete way). In fact, the following silightly different test case does not work on both jdk 6 and jdk 7: class Test<T> { <T extends Comparable<? super T>> Test<T> m() { return null; } <T extends Comparable<? super T>> void test() { Test<T> t = m(); } } The underlying reason is the same (a subtyping test is failing because two unrelated type vars are compared). This CR only restores the pre-6315770 behavior; for a more complete fix we should wait for 6369605
29-04-2009

EVALUATION This is a regression introduced by fix of 6315770. A redundant subtype test is causing the compiler to fail. In particular, the compiler manages to infer T = T' (where T is the formal type parameter of the method comparator(), and T' is the formal parameter of f()). As a sanity check the compiler checks that the inferred type is a subtype of all the undetvar's upper bounds. In this case there's just one upper bound which is Comparable<? super T>. The test proceed as follows: T' <: Comparable<? super T> upper(T') = Comparable<? super T'> <: Comparable<? super T> T <: T' which is false as T and T' are distinct type variables! The redundant subtyping test should be either (i) removed [as the fix of 6315570 makes it unnecessary] or (ii) fixed so that actual types are replaced inside undetvars' upper bounds so that the test can succeed. However doing (ii) is complex, as not all the types have been inferred when the sanity check is run - which means that we might still have some formal type variables in the upper bounds which could lead the subtype test to fail. The test could be safely removed as: *) if the undetvar has just one bound T, then it is true that the inferred type glb(T) = T <: T *) if the undetvar has two bounds S and T, then it is true that the inferred type glb(S, T) is a subtype of both S and T (if glb is defined, by construction of glb). *) the observation above can be extended in the general case where there is more than two type variables [by induction and by observing that glb(T1, T2, T3) = glb(glb(T1, T2), T3))
29-04-2009