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

Wildcard type information lost causing invalid assignment

XMLWordPrintable

    • generic
    • generic

      FULL PRODUCT VERSION :
      java version "1.8.0_92"
      Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
      Java HotSpot(TM) Server VM (build 25.92-b14, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      OS should not matter, but this was tested on Ubuntu 14.04 32 bit,

      A DESCRIPTION OF THE PROBLEM :
      Information about whether a type has a wildcard upper bound seems to get lost for programs which contain a certain combination of generic methods. The result is that incorrect programs type check without warnings, which might lead to heap pollution and unexpected ClassCastExceptions.

      I have tried this with Eclipse 4.5.2 (realeased version) and Eclipse 4.6 (Build id: I20160525-2000). JDK 1.8.0_77 also has the same behaviour.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the example program from the description section.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The compilation should fail with a compilation error, for example:

      LostWildCardCompilerBug.java:58: error: incompatible types: inference variable T has incompatible bounds
              Set<List<Number>> numbetListSet1 = Collections.singleton(toWildcardGeneric(integerList));
                                                                      ^
          equality constraints: List<Number>
          lower bounds: List<CAP#1>
        where T is a type-variable:
          T extends Object declared in method <T>singleton(T)
        where CAP#1 is a fresh type-variable:
          CAP#1 extends Integer from capture of ? extends Integer
      1 error

      ACTUAL -
      The program compiles without warnings. When run it crashes the a ClassCastException and gives the following output:

      Exception in thread "main" java.lang.ClassCastException: java.lang.Float cannot be cast to java.lang.Integer
      at LostWildCardCompilerBug.main(LostWildCardCompilerBug.java:50)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.List;
      import java.util.Set;

      class JavacLostWildCardCompilerBug {
          public static void main(String[] args) {
              List<Integer> integerList = new ArrayList<>();
              // This assignment should not be allowed
              Set<List<Number>> numbetListSet = Collections.singleton(toWildcardGeneric(integerList));
              numbetListSet.iterator().next().add(new Float(1.0));
              Integer i = integerList.get(0); // Throws ClassCastException
          }
          
          static <T> List<? extends T> toWildcardGeneric(List<T> l) {
              return l;
          }
          
      }

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

            mcimadamore Maurizio Cimadamore
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: