JDK-8219318 (???): inferred type does not conform to upper bound(s) when collecting to a HashMap

B. Blaser bsrbnd at gmail.com
Fri Dec 13 19:46:44 UTC 2019


Hi,

I looked at the following interesting issue [1]:

public static void main(String... args) {
    Map<Integer, Integer> destination = null;
    Map<Integer, Integer> source = null;

    destination.putAll( source.entrySet().stream().collect(
Collectors.toMap( e -> 0, e -> 0, ( e1, e2 ) -> 0, HashMap::new ) ) );
}

Javac fails to infer the above expression during overload resolution
of 'putAll()' when checking the return type of the partially inferred
method 'collect()' whereas avoiding it succeeds:

    Map<? extends Integer, ? extends Integer> broker =
source.entrySet().stream().collect( Collectors.toMap( e -> 0, e -> 0,
( e1, e2 ) -> 0, HashMap::new ) );

It seems that the inference context is missing constraints from
'HashMap::new' when checking the partially inferred method return type
because of [2].

Removing the line 'stuck = true' as here under makes the above example
succeed but a couple of tests like [3] are then failing as statements
like 'g4(MethodReference46::m)' are no more ambiguous which would be,
at my mind, a good thing.

What do you think, is the current behavior correct or should we fix
this issue with something like below?

Thanks,
Bernard

[1] https://bugs.openjdk.java.net/browse/JDK-8219318
[2] http://hg.openjdk.java.net/jdk/jdk/file/cec148db7b55/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java#l1280
[3] http://hg.openjdk.java.net/jdk/jdk/file/cec148db7b55/test/langtools/tools/javac/lambda/MethodReference46.java#l43

diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
@@ -1276,9 +1276,9 @@
         @Override
         public void visitReference(JCMemberReference tree) {
             super.visitReference(tree);
-            if (tree.getOverloadKind() !=
JCMemberReference.OverloadKind.UNOVERLOADED) {
-                stuck = true;
-            }
+//            if (tree.getOverloadKind() !=
JCMemberReference.OverloadKind.UNOVERLOADED) {
+//                stuck = true;
+//            }
         }
     }


More information about the compiler-dev mailing list