JDK-6476073 : Capture using super wildcard of type variables doesn't work
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P5
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-09-28
  • Updated: 2010-04-02
  • Resolved: 2006-10-19
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b99)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b99, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
The test code doesn't compile with javac but
compiles with eclipse. It seems for me that javac in wrong in this case.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile the test case

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
it should compile
ACTUAL -
it doesn't compile

ERROR MESSAGES/STACK TRACES THAT OCCUR :
JavacSuperBug.java:7: <B>m(java.util.List<? super B>,java.util.Collection<? super B>) in JavacSuperBug cannot be applied to (java.util.List<capture#293 of ? super B>,java.util.Collection<capture#954 of ? super B>)
        m(list,coll);
        ^
1 error


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.Collection;
import java.util.List;

public class JavacSuperBug {
    public static <B> void m(List<? super B> list,Collection<? super B> coll) {
        m(list,coll);
    }
}
---------- END SOURCE ----------

Comments
EVALUATION Actually this program deserves a detailed evaluation. This should't have been marked as a duplicate of 6302954 because it's not - it is possible that the fix of 6302954 also fix this problem, but the underlying issue is totally different. According to JLS3 the submitted test case should NOT compile. In fact we have that JLS3 (sections 15.12.2.2, 15.12.2.3 and 15.12.2.4) mandate that a final sanity check should be carried out in order to determine method's applicability after type-inference: "The method m is applicable by subtyping if and only if both of the following conditions hold: * For 1in, either: o Ai is a subtype (��4.10) of Si (Ai <: Si) or o Ai is convertible to some type Ci by unchecked conversion (��5.1.9), and Ci <: Si. * If m is a generic method as described above then Ul <: Bl[R1 = U1, ..., Rp = Up], 1lp." In this case, the type of B cannot be inferred neither from 15.12.2.7 (as no constraints lead to a lower bound for B) nor from 15.12.2.8 (as no return type context is present here). It follows that B is inferred to be Object. But Object is not a valid substitute for the method parameter's B; in fact we have that: List<? super B'> <: [B:=Object] List<? super B> = List<? super Object> Object <: B does not hold. As such, the generic method m is NOT applicable by subtyping (neither it is by method invocation conversion/varargs). So javac was right (well I should say compliant with the JLS) in issuing a compilation error. This program could be formally acepted once JLS3 will include propagation of <: and == constraints from 15.12.2.7 to 15.12.2.8; in this case the following constraints should be propagated: B_formal <: #CAP1, where lower-bound(#CAP1) = B_actual B_formal <: #CAP2, where lower-bound(#CAP2) = B_actual When we pass these constraints on to 15.12.2.8 we should infer: B_formal = glb(#CAP1, #CAP2) = #CAP1 & #CAP2 The method is applicable (by 15.12.2.3/4/5): 1) [argument 1] List<#CAP1> <: [B = #CAP1&CAP2]List<? super B> = List<? super #CAP1&CAP2> #CAP1&#CAP2 <: #CAP1 OK 2) [argument 2] List<#CAP2> <: [B = #CAP1&CAP2]List<? super B> = List<? super #CAP1&CAP2> #CAP1&#CAP2 <: #CAP2 OK
10-03-2009