JDK-8219318 : error at compile time:inferred type does not conform to upper bound(s) when collecting to a HashMap
  • Type: Bug
  • Component: specification
  • Affected Version: 8,11,12,13
  • Priority: P4
  • Status: In Progress
  • Resolution: Unresolved
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2019-02-18
  • Updated: 2019-12-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_majorUnresolved
Description
A DESCRIPTION OF THE PROBLEM :
Attached code does not compile.
I use Guava 27.0-jre.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
paste the code into any main method and try to compile it with javac

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
program compiles
ACTUAL -
incompatible types: inferred type does not conform to upper bound(s)
inferred: com.google.common.collect.Table<java.lang.Object,java.lang.Object,java.lang.Object>
upper bound(s): com.google.common.collect.Table<java.lang.Object,java.lang.Object,java.lang.Object>,com.google.common.collect.Table<? extends java.lang.Integer,? extends java.lang.Integer,? extends java.lang.Integer>,java.lang.Object

---------- BEGIN SOURCE ----------
final Table<Integer, Integer, Integer> destination = HashBasedTable.create();
final Map<Integer, Integer> source = new HashMap<>();

// doesn't compile
destination.putAll( source.entrySet().stream().collect( Tables.toTable( e -> 0, e -> 0, e -> 0, ( e1, e2 ) -> 0, HashBasedTable::create ) ) );
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
final Table<Integer, Integer, Integer> destination = HashBasedTable.create();
final Map<Integer, Integer> source = new HashMap<>();

// compiles
final Table<Integer, Integer, Integer> broker = source.entrySet().stream().collect( Tables.toTable( e -> 0, e -> 0, e -> 0, ( e1, e2 ) -> 0, HashBasedTable::create ) );
destination.putAll( broker );

FREQUENCY : always



Comments
Potential specification and compiler fix, see: http://mail.openjdk.java.net/pipermail/compiler-dev/2019-December/014113.html http://mail.openjdk.java.net/pipermail/compiler-dev/2019-December/014114.html
19-12-2019

Assigning it to the specification team.
17-12-2019

Seems not to be a compiler issue, see: http://mail.openjdk.java.net/pipermail/compiler-dev/2019-December/014100.html
17-12-2019

Related thread: http://mail.openjdk.java.net/pipermail/compiler-dev/2019-December/014085.html
13-12-2019

Following is the error thrown when compiling the test case provided by the submitter: ==================================================================== >D:\jdk-13\bin\javac -Xdiags:verbose JDK8219318.java JDK8219318.java:16: error: method putAll in interface Map<K,V> cannot be applied to given types; destination.putAll( source.entrySet().stream().collect( Collecto rs.toMap( e -> 0, e -> 0, ( e1, e2 ) -> 0, HashMap::new ) ) ); ^ required: Map<? extends Integer,? extends Integer> found: Map<Object,Object> reason: argument mismatch; inferred type does not conform to upper bound(s) inferred: Map<Object,Object> upper bound(s): Map<Object,Object>,Map<? extends Integer,? extends Integer >,Object where K,V are type-variables: K extends Object declared in interface Map V extends Object declared in interface Map 1 error ================================================================= If I modify the test case to either : destination.putAll( source.entrySet().stream().collect( Collectors.toMap( e -> 0, e -> 0, ( e1, e2 ) -> 0 ) ) ); or destination.putAll( source.entrySet().stream().collect( Collectors.toMap( e -> 0, e -> 0, ( e1, e2 ) -> 0, () ->new HashMap<Integer,Integer>() ) ) ); the test case compiles without any error , so a user will expect the original test case to compile as well.
02-04-2019

From submitter: Please consider the following test case: final Map<Integer, Integer> destination = new HashMap<>(); final Map<Integer, Integer> source = new HashMap<>(); // compiles final Map<Integer, Integer> broker = source.entrySet().stream().collect( Collectors.toMap( e -> 0, e -> 0 ) ); destination.putAll( broker ); // does not compile destination.putAll( source.entrySet().stream().collect( Collectors.toMap( e -> 0, e -> 0, ( e1, e2 ) -> 0, HashMap::new ) ) );
02-04-2019

To submitter: Are you able to reproduce the issue using JDK APIs on Oracle/Open JDK ? Can you please provide a test case for that.
19-02-2019