"Chained" qualified instance creation expressions (diamond in qualifiers)

Georgiy Rakov georgiy.rakov at oracle.com
Wed May 6 14:06:23 UTC 2015


Hello,

let's consider following example:

    classD {}

    classOuter2<Q> {
         classOuter1<W> {
             classFoo<T> { }
         }
    }

    public classTest69 {

         public static voidtest(String argv[]) {
             Outer2<?superD>.Outer1<?superD>.Foo<?superD> f20 =newOuter2<>().newOuter1<>().newFoo<>() {
                 privateOuter2<Object>.Outer1<Object>.Foo<D> simpleMethod1() {return this; }//compiles Ok
                 //private Outer2<D>.Outer1<D>.Foo<D> simpleMethod2() { return this; } //causes compilation error
             };
         }
    }


JDK9b60 causes Q and W to be inferred as Object. This can be seen:
- from the fact that code above compiles successfully;
- from the fact that uncommenting the method above causes compilation 
failure.

So what we actually have is:
- Q is inferred as Object;
- W is inferred as Object;
- T is inferred as D.

However according to intuition it seems that Q and W should have been 
inferred as D as it happens to T.

I believe this corresponds to spec, the reasons presented below seem to 
cause this:

1. Following assertion from JLS 18.5.2 is not applied when JLS 15.9.3 is 
applied to new Outer2<>() and new Outer1<>():

    Otherwise, the constraint formula ‹Rθ→T› is reduced and incorporated
    with B_2 .

So for outer classes inference proceeds with no constraint formula 
actually causing inference variable in question to be inferred as D.

2. JLS 15.9.3 doesn't use type parameters from outer classes when 
processing new Foo<>(). Namely following assertion from JLS 15.9.3 
doesn't mention type parameters from possible outer classes:

    Let F_1 ...F_p be the type parameters of C, and let G_1 ...G_q be
    the type parameters (if any) of |c_j |.

So constraint formula created by JLS 18.5.2 assertion presented above 
engages just inference variable from Foo, i. e. T.

However I believe more broad change of spec will be required to 
implement this "intuition" than just modifying spec according to two 
points above.

So:
1. Could you please tell if I understand correctly that the fact that Q 
is inferred as Object, W is inferred as Object really corresponds to 
spec and it's not a JDK issue.
2. As for me it looks reasonable to enhance specification so that Q and 
W would be inferred as D too. Could you please tell if you agree. If you 
do would it be worth creating spec enhancement in Jira?

Thanks,
Georgiy.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150506/745c42ec/attachment-0001.html>
-------------- next part --------------
class D {}

class Outer2<Q> {
    class Outer1<W> {
        class Foo<T> { }
    }
}

public class Test69 {

    public static void test(String argv[]) {
        Outer2<? super D>.Outer1<? super D>.Foo<? super D> f20 = new Outer2<>().new Outer1<>().new Foo<>() {
            private Outer2<Object>.Outer1<Object>.Foo<D> simpleMethod1() { return this; } //compiles Ok
            //private Outer2<D>.Outer1<D>.Foo<D> simpleMethod2() { return this; } //causes compilation error
        };
    }
}


More information about the compiler-dev mailing list