8046977: ClassCastException: typing information needed for method reference bridging not preserved
authorjfranck
Tue, 20 Jan 2015 21:49:55 +0100
changeset 28591 25f1384324ae
parent 28590 9069a3bf5900
child 28592 4f1da6e809b0
8046977: ClassCastException: typing information needed for method reference bridging not preserved Reviewed-by: mcimadamore Contributed-by: srikanth.adayapalam@oracle.com
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Jan 20 12:00:25 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Jan 20 21:49:55 2015 +0100
@@ -2783,7 +2783,8 @@
 
     @SuppressWarnings("fallthrough")
     void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) {
-        Type returnType = checkContext.inferenceContext().asUndetVar(descriptor.getReturnType());
+        InferenceContext inferenceContext = checkContext.inferenceContext();
+        Type returnType = inferenceContext.asUndetVar(descriptor.getReturnType());
 
         Type resType;
         switch (tree.getMode()) {
@@ -2812,10 +2813,20 @@
         if (incompatibleReturnType != null) {
             checkContext.report(tree, diags.fragment("incompatible.ret.type.in.mref",
                     diags.fragment("inconvertible.types", resType, descriptor.getReturnType())));
+        } else {
+            if (inferenceContext.free(refType)) {
+                // we need to wait for inference to finish and then replace inference vars in the referent type
+                inferenceContext.addFreeTypeListener(List.of(refType),
+                        instantiatedContext -> {
+                            tree.referentType = instantiatedContext.asInstType(refType);
+                        });
+            } else {
+                tree.referentType = refType;
+            }
         }
 
         if (!speculativeAttr) {
-            List<Type> thrownTypes = checkContext.inferenceContext().asUndetVars(descriptor.getThrownTypes());
+            List<Type> thrownTypes = inferenceContext.asUndetVars(descriptor.getThrownTypes());
             if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) {
                 log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes());
             }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Jan 20 12:00:25 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Jan 20 21:49:55 2015 +0100
@@ -889,7 +889,9 @@
                     convertArgs(tree.sym, args.toList(), tree.varargsElement)).
                     setType(tree.sym.erasure(types).getReturnType());
 
-            apply = transTypes.coerce(apply, localContext.generatedRefSig().getReturnType());
+            apply = transTypes.coerce(attrEnv, apply,
+                    types.erasure(localContext.tree.referentType.getReturnType()));
+
             setVarargsIfNeeded(apply, tree.varargsElement);
             return apply;
         }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue Jan 20 12:00:25 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue Jan 20 21:49:55 2015 +0100
@@ -2101,6 +2101,7 @@
         public PolyKind refPolyKind;
         public boolean ownerAccessible;
         public OverloadKind overloadKind;
+        public Type referentType;
 
         public enum OverloadKind {
             OVERLOADED,