Compiler erroneously reports incompatible types in code using the ?: operator

XMLWordPrintable

    • x86
    • linux

      FULL PRODUCT VERSION :
      java version "1.5.0_05"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
      Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)

      (identical version info on Linux and Windows)

      ADDITIONAL OS VERSION INFORMATION :
      Linux bl-chem-iumsc23.chem.indiana.edu 2.6.12-1.1381_FC3 #1 Fri Oct 21 03:46:55 EDT 2005 i686 i686 i386 GNU/Linux

      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      The compiler wrongly reports incompatible types in some assignments when the left-hand side has a wildcard type and the right-hand side an intersection type arising from a ternary expression. It likewise wrongly rejects enhanced for loop control statements having similar construction. The compiler messages (see below) don't even make sense: how is it that test.Generic<capture of ? extends java.lang.Object&java.io.Serializable&test.Super> is not a subtype of test.Generic<? extends test.Super> ?


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      The problem can be reproduced by compiling the provided sample code (below) with javac 1.5.0_05.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The code should compile successfully and without warnings.
      ACTUAL -
      The compiler reported these errors:

      test/Test.java:32: incompatible types
      found : test.Generic<capture of ? extends java.lang.Object&java.io.Serializable&test.Super>
      required: test.Generic<? extends test.Super>
              generic = (flag ? new Generic<Sub3>() : new Generic<Sub4>());
                              ^
      test/Test.java:38: incompatible types
      found : java.lang.Object&java.io.Serializable&test.Super
      required: test.Super
              for (Super sup : (flag ? list3 : list4)) {}
                               ^
      2 errors


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      As reported above.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      /*
       * An example file hilighting a javac (1.5.0_05) bug related to type capture
       * and the ternary operator
       */

      package test;

      import java.util.List;
      import java.io.Serializable;

      class Super {}
      class Sub1 extends Super {}
      class Sub2 extends Super {}
      class Sub3 extends Super implements Serializable {}
      class Sub4 extends Super implements Serializable {}
      class Generic<T> {}

      public class Test {

          List<Sub1> list1;
          List<Sub2> list2;
          List<Sub3> list3;
          List<Sub4> list4;

          public void test1(boolean flag) {
              Generic<? extends Super> generic;

              // This works
              generic = (flag ? new Generic<Sub1>() : new Generic<Sub2>());

              // This fails because of (supposed) incompatible types
              generic = (flag ? new Generic<Sub3>() : new Generic<Sub4>());

              // This works
              for (Super sup : (flag ? list1 : list2)) {}

              // This fails because of (supposed) incompatible types
              for (Super sup : (flag ? list3 : list4)) {}
          }

      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      An explicit cast can be used to avoid the error, but it still causes javac to emit an "unchecked cast" warning, and should not in any case be necessary.

            Assignee:
            Peter Ahe
            Reporter:
            Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: