Subtyping constraint and unchecked conversion

Georgiy Rakov georgiy.rakov at oracle.com
Fri Sep 11 18:06:32 UTC 2015


Hello,

let's consider following example:

    class MyList<T> { }
    class Foo<T> { }

    public class Test36 {
         public static <U> MyList<U> m1(U item) {return null; }

         public static <T extends Foo<Integer>>void m2(MyList<?extends T> l) { }

         public static void run() {
             m2(m1(new Foo()));
         }
    }

It compiles successfully on JDK9b80. However according to my 
understanding compilation should fail, because:

1. Originally we have following bounds:

    U <: Object;
    T <: Foo<Integer>

and constraints:

    Foo <: U
    MyList<U> <: MyList<? extends T>

2. The last constraint is reduced as it follows:

    MyList<U> <: MyList<? extends T> =>
    U <= ? extends T =>
    U <: T

3. When U <: T is created following transitivity chain appears:

    Foo <: U, U <: T, T <: Foo<Integer>

so incorporating U <: T implies following constraint:

    Foo <: Foo<Integer>

4. Since raw type is not a subtype of corresponding generic type 
parameterization, and unchecked conversion is not applied here too, 
compile time error should occur, but it doesn't. If it were a type 
compatibility constraint then it will be reduced to true, but this is a 
subtyping constraint.

Additionally, Xlint outputs following:

    javac  -Xlint:unchecked Test36.java
    Test36.java:10: warning: [unchecked] unchecked method invocation:
    method m2 in class Test36 is applied to given types
             m2(m1(new Foo()));
               ^
       required: MyList<? extends T>
       found: MyList<Foo>
       where T is a type-variable:
         T extends Foo<Integer> declared in method <T>m2(MyList<?
    extends T>)
    1 warning


But it's not clear why unchecked conversion occurs here. What is 
reported by Xlint is that the parameterized type is converted to another 
paramterized type, the former has a raw type as its type argument but 
it's not clear what spec assertions specify how unchecked conversion is 
applied to these type arguments.

In general this looks like a javac bug. Could you please tell if it 
really is.

Thank you,
Georgiy.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150911/3ca68451/attachment.html>
-------------- next part --------------
class MyList<T> { }
class Foo<T> { }

public class Test36 {
    public static <U> MyList<U> m1(U item) { return null; }
    public static <T extends Foo<Integer>> void m2(MyList<? extends T> l) { }

    public static void run() {
        m2(m1(new Foo()));
    }
}


More information about the compiler-dev mailing list