JDK-8048526 : Well-formed wild-carded parameterized type of Iface fails to compile
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2014-06-27
  • Updated: 2015-12-11
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.
Other
tbd_majorUnresolved
Related Reports
Blocks :  
Blocks :  
Description
Following code fails to compile:

public class Test10 {
    interface Iface<T extends U, U> { }
    public static void main(String argv[]) {
        Iface<? extends Integer, ? super Number> i = null;
    }
}

however according to JLS8 4.5:

"A parameterized type C<T1,...,Tn> is well-formed if ... 	when subjected to capture conversion (��5.1.10) resulting in the type C<X1,...,Xn>, each type argument Xi is a subtype of S[F1:=X1,...,Fn:=Xn] for each bound type S in Bi."

In this case, given 'CAP1 extends Integer' and 'CAP2 super Number', Iface<CAP1, CAP2> is within its bounds -- CAP1 is a subtype of CAP2.

Swapping T and U causes compilation to succeed:

public class Test11 {
    interface Iface2<U, T extends U > { }
    public static void main(String argv[]) {
        Iface2<? super Number, ? extends Integer> i2 = null;
    }
}

The code above is attached.
Comments
Need to resolve spec issues JDK-8039222 and JDK-8043351 in order to know how to resolve this in javac.
11-12-2015

The above analysis leaves out the fact that the 2nd capture variable participates in the bound of the first. This is probably the source of problems and order dependency (because the bounds are presumably computed in left-to-right order). Per JLS 5.1.10: capture(Iface<? extends Integer, ? super Number>) = Iface<CAP1, CAP2> where: CAP1 extends glb(CAP2, Integer) CAP2 super Number The spec fails to explain how glb is computed here (is it really just the intersection 'CAP2 & Integer'?) and whether the resulting type is well-formed or not.
11-12-2015

Note that there's an unusual dependency on type parameter order: public class WellFormedWildcard { interface I<T extends U, U> { } interface J<U, T extends U> { } void test() { I<? extends Integer, ? super Number> i = null; // error J<? super Number, ? extends Integer> j = null; // no error } }
30-06-2014

Reducing priority to P4: this is longstanding behavior and is not a customer-reported issue. ILW: Impact=medium (won't compile, but not a regression) Likelihood=low (class declarations of this form are unusual) Workaround=medium (can typically rewrite to avoid wildcards, possibly with unchecked casts) I'm also removing the deferral request, since it is no longer necessary.
30-06-2014