Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8133936

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

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2
    • Resolution: Not an Issue
    • Affects Version/s: 9
    • Fix Version/s: 9
    • Component/s: tools

      Description

      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 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.

      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>

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                dlsmith Dan Smith
                Reporter:
                grakov Georgiy Rakov (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: