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

JLS 15.12.2.7: Generic type inference fails with once-removed interface impl

    XMLWordPrintable

Details

    • x86
    • windows_8

    Description

      FULL PRODUCT VERSION :
      java version "1.7.0_65"
      Java(TM) SE Runtime Environment (build 1.7.0_65-b19)
      Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Windows 8 64-bit: Microsoft Windows [Version 6.2.9200]

      Originally discovered on Ubuntu, JDK 7u45 (box not accessible at the time)

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Nothing relevant (pure compiler bug)

      A DESCRIPTION OF THE PROBLEM :
      The generic type inference seems to break down in the example code below. When a class is declared as generic with a bound on the type parameter and also implements an interface with the same parameter, the bound should also apply to the interface. Succinctly, if class C<T extend B> implements I2<T>, then C<?> should be assignable to I2<? extends B>, since the parameter is known by definition to extend B. Naturally, if I2<T> extends I1<T> as well, then C<?> should be assignable to I1<? extends B>.

      The compiler inference does work for this case (as evidenced by the test3() call), but seems to break down when this exact case occurs in a generic type parameter instead. In particular, the compiler fails to verify that List<C<?>> is a subtype of List<? extends I1<? extends B>> during method invocation conversion. Oddly enough, the compiler is okay with the conversion through an intermediate type List<? extends I2<? extends B>>, which is correct, but seems to limit an arbitrary bound on the supertype type-search.

      Linked original discussion: http://stackoverflow.com/questions/24817306/java-bounded-generics-type-inference-bug-method-invocation-jls-15-12-2-7

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile the following code with

      javac Main.java

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The code compiles correctly.
      ACTUAL -
      The compilation fails with the error below.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Main.java:12: error: method test2 in class Main cannot be applied to given types;
              test2((List<BoundedI2<?>>) null);
              ^
        required: List<? extends Interface1<? extends Bound>>
        found: List<BoundedI2<?>>
        reason: actual argument List<BoundedI2<?>> cannot be converted to List<? extends Interface1<? extends Bound>> by method invocation conversion
      1 error

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.List;

      public class Main {
          interface Interface1<T> {}
          interface Interface2<T> extends Interface1<T> {}
          static class Bound {}
          interface BoundedI1<T extends Bound> extends Interface1<T> {}
          interface BoundedI2<T extends Bound> extends Interface2<T> {}

          public static void main(String[] args) {
              test((List<BoundedI2<?>>) null);
              test2((List<BoundedI2<?>>) null);
              test3((BoundedI2<?>) null);
          }

          public static void test(List<? extends Interface2<? extends Bound>> list) { test2(list); }
          public static void test2(List<? extends Interface1<? extends Bound>> list) {}
          public static void test3(Interface1<? extends Bound> instance) {}
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      The compiler is okay if the type BoundedI2<?> is declared with the redundant bound specification BoundedI2<? extends Bound>, though the latter adds quite a bit of unnecessary verbosity if the type is widely used and if the bound in question is nontrivial to specify.

      Attachments

        Issue Links

          Activity

            People

              dlsmith Dan Smith
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated: