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

Dan Smith daniel.smith at oracle.com
Tue May 19 20:57:34 UTC 2015


> On May 8, 2015, at 4:52 AM, Srikanth <srikanth.adayapalam at oracle.com> wrote:
> 
> On Wednesday 06 May 2015 07:36 PM, Georgiy Rakov wrote:
>> Hello,
>> 
>> let's consider following example:
>> 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
>> 
>>         };
>>     }
>> }
>> 
>> 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 B2. 
>> 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 F1...Fp be the type parameters of C, and let G1...Gq be the type parameters (if any) of cj. 
>> 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.
> 
> Hi Georgiy,
> 
> My original response is good enough for this part - The target type from the LHS i.e 
> Outer2<? super D>.Outer1<? super D>.Foo<? super 
> D>
> 
> 
> gets imposed on
> new Foo<>() { ... }
> and the specification does not mandate/require/sanction/allow a qualified instance creation expression 
> to propagate the target type or any part thereof to any enclosing instance creation expression (qualified
> or otherwise).
> 
> So Q and W being inferred as Object is the right behaviour per the current specification.

Yep, agreed.  The qualifier of a ClassInstanceCreationExpression (15.9) is always a standalone expression (15.2) -- it is not in an assignment context or an invocation context (15.9, 15.12, etc.).  (Note that the qualifier is an arbitrary expression, not necessarily another class instance creation.)

>> 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?
> 
> This part which have you described as being "intuitive", I'll request Dan Smith to answer the reasons for the state of the art - I don't readily know what canons of type system theory would require it to be
> the way it is - i.e why would we not allow the qualified allocation expression to propagate suitable target types to the enclosing expressions - and whether this is something amenable to tinkering.

Allowing an arbitrary receiver expression to use context for inference is something we've looked at, but it's harder than it might seem when looking at this limited example.  You might see references to "chained inference" in, e.g., Lambda documents.  Maybe someday, but it's a full-fledged new feature, not a bug fix.

—Dan


More information about the compiler-dev mailing list