JDK-6569074 : Type inference fails with bounded type parameters
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: linux
  • CPU: x86
  • Submitted: 2007-06-13
  • Updated: 2011-02-16
  • Resolved: 2010-10-27
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode)
 1.6.0_02-ea-b02

ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.18.5 #1 SMP i686 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
This is a superset of Bug 6468354.

Type inference on assignment often fails if one or more of the type parameters is bounded. For example:

  <E extends Comparable<? super E>>
  <K extends Comparable<K>, V extends Comparable<V>>
  <K extends Comparable<? super K>, V extends Comparable<? super V>>

See the test cases below for more concrete examples.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See the test case below for concrete examples.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The test case below should compile without errors. The compiler should be able to infer the correct type based on the assignment.
ACTUAL -
The test case fails to compile. See the error messages below.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Foo.java:4: incompatible types; no instance(s) of type variable(s) E exist so that Set<E> conforms to Set<java.lang.String>
found   : <E>Set<E>
required: Set<java.lang.String>
    Set<String> set1 = newSet1(); // fails
                              ^
Foo.java:7: incompatible types; no instance(s) of type variable(s) K,V exist so that Map<K,V> conforms to Map<java.lang.String,java.lang.Integer>
found   : <K,V>Map<K,V>
required: Map<java.lang.String,java.lang.Integer>
    Map<String, Integer> map1 = newMap1(); // fails
                                       ^
Foo.java:8: incompatible types; no instance(s) of type variable(s) K,V exist so that Map<K,V> conforms to Map<java.lang.String,java.lang.Integer>
found   : <K,V>Map<K,V>
required: Map<java.lang.String,java.lang.Integer>
    Map<String, Integer> map2 = newMap2(); // fails
                                       ^
3 errors


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Foo {

  public static void main(String[] args) {
    Set<String> set1 = newSet1(); // fails
    Set<String> set2 = newSet2(); // succeeds

    Map<String, Integer> map1 = newMap1(); // fails
    Map<String, Integer> map2 = newMap2(); // fails
    Map<String, Integer> map3 = newMap3(); // succeeds
  }

  static <E extends Comparable<? super E>> Set<E> newSet1() {
    return new Set<E>();
  }

  static <E extends Comparable<E>> Set<E> newSet2() {
    return new Set<E>();
  }

  static <K extends Comparable<? super K>, V extends Comparable<? super V>>
      Map<K,V> newMap1() {
    return new Map<K,V>();
  }

  static <K extends Comparable<K>, V extends Comparable<V>> Map<K,V> newMap2() {
    return new Map<K,V>();
  }

  static <K extends Comparable<K>, V extends Comparable<?>> Map<K,V> newMap3() {
    return new Map<K,V>();
  }

}

class Set<E> {}

class Map<K,V> {}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
The test case includes an example work-around, which is to declare the type parameters as:

  <K extends Comparable<K>, V extends Comparable<?>>

This is obviously undesirable, as it doesn't fully express the type constraints for a Map that contains self-comparable keys and values. The K parameter is bound too tightly, and the V parameter is bound too loosely!

An even looser work around is:

  <K,V>

which simply gives up trying to enforce that the K and V types are comparable.

Comments
EVALUATION Not reproducible after the fix of 6650759.
27-10-2010