The return type of instance creation expression with diamond and class body should be anonymous class type

Georgiy Rakov georgiy.rakov at oracle.com
Wed Aug 19 12:31:24 UTC 2015


Hello,

FYI: I've filed the issue about this:

https://bugs.openjdk.java.net/browse/JDK-8133936

Thanks,
Georgiy.

On 06.08.2015 19:07, Georgiy Rakov wrote:
> Hello,
>
> let's consider following example:
> class List<T> {
> List() {}
> List<T> getThis() {
> return new List();
> }
> }
>
> class Foo<T> {
> public Foo(T a1){}
> }
>
> public class Test25 {
> public static <T> List<T> m1(T item) {
> List l = new List();
> return l;
> }
> public static <U> void m2(List<U> list1, List<U> list2) { }
> public static void test() {
> m2(new List<Foo<String>>(), m1(new Foo<>("str"){ }).getThis());
> }
> }
>
> This example compiles successfully on JDK9b75. But according to my 
> understanding the compilation should have failed. The reasons for this 
> are presented below:
>
> 1. JDK-8073593 
> <https://bugs.openjdk.java.net/browse/JDK-8073593?focusedCommentId=13622110&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13622110> 
> specifies following assertion:
>
>     ***If C is an anonymous class, then the chosen constructor is the
>     constructor of the anonymous class. The return type is the
>     anonymous class type.***
>
> current JLS 9 15.9.1 spec defines following assertion:
>
>     The type of the class instance creation expression is the return
>     type of the chosen constructor, as defined above.
>
> so together these assertions lead to the fact that the type of 
> instance creation expression "new Foo<>("str"){ } " is anonymous class 
> type, let's denote it as "anonymous Foo<String>".
>
> 2. Thus when m1 is invoked, that is "m1(new Foo<>("str"){ })", the 
> invocation return type is List<anonymous Foo<String>>.
>
> 3. Hence when getThis is invoked, that is "m1(new Foo<>("str"){ 
> }).getThis()", the invocation return type is List<anonymous 
> Foo<String>> as well.
>
> 4. Finally when m2 method is invoked type inference cause two equality 
> constraints to be created that is: U = Foo<String> and U = (anonymous 
> Foo<String>), together they should lead to compilation failure, but 
> compilation succeeds.
>
> This seems to be a javac bug. Could you please confirm if it really is.
>
> Please note, that if diamond is replaced with String type argument, 
> that is "new Foo<String>("str"){ }" the compilation fails as expected:
>
>     Error:(19, 9) java: method m2 in class Test25 cannot be applied to
>     given types;
>       required: List<U>,List<U>
>       found: List<Foo<java.lang.String>>,List<<anonymous
>     Foo<java.lang.String>>>
>       reason: inference variable U has incompatible equality
>     constraints <anonymous Foo<java.lang.String>>,Foo<java.lang.String>
>
> Thank you,
> Georgiy.
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150819/313693f3/attachment.html>


More information about the compiler-dev mailing list