void return type check in method reference to PolymorphicSignature method

Paul Sandoz paul.sandoz at oracle.com
Thu Oct 1 23:33:48 UTC 2020


Hi Tagir,

I think it is a regression introduced by:

8203488: Remove error generation from TransTypes

I managed to fix it by ensuring the sig poly method's return type dominates if its not Object (polymorphic in its return type), which then results in a compilation error. However, it needs someone with more expertise that I in javac to ensure that the fix is correct.

Paul.



diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
index 6fd598340b7..dbc176b751c 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -2747,6 +2747,18 @@ public class Resolve {
             }
         }
 
+        Type spReturnType = spMethod.asType().getReturnType();
+        if (types.isSameType(spReturnType, syms.objectType)) {
+            // Polymorphic return, pass through mtype
+        } else if (!types.isSameType(spReturnType, mtype.getReturnType())) {
+            // Retain the sig poly method's return type, which differs from that of mtype
+            // Should result in compilation error later
+            mtype = new MethodType(mtype.getParameterTypes(),
+                    spReturnType,
+                    mtype.getThrownTypes(),
+                    syms.methodClass);
+        }
+
         // Create the desired method
         // Retain static modifier is to support invocations to
         // MethodHandle.linkTo* methods


> On Oct 1, 2020, at 4:29 AM, Tagir Valeev <amaembo at gmail.com> wrote:
> 
> Hello!
> 
> I've found that this code is not compilable in Java 9 and Java 10, but
> compilable in Java 11 or later (yet fails at runtime):
> 
> import java.lang.invoke.MethodHandles;
> import java.lang.invoke.VarHandle;
> import java.util.Arrays;
> 
> class Test {
>  interface VH {
>    int set(int[] arr, int idx, int val);
>  }
> 
>  public static void main(String[] args) {
>    VarHandle vh = MethodHandles.arrayElementVarHandle(int[].class);
>    //VH mr = (arr, idx, val) -> vh.set(arr, idx, val); // not compilable
>    VH mr = vh::set; // compilable but runtime error
>    int[] data = {0};
>    mr.set(data, 0, 2);
>    System.out.println(Arrays.toString(data));
>  }
> }
> 
> Fails with
> 
> Exception in thread "main" java.lang.NoSuchMethodError:
> VarHandle.set(int[],int,int)int
> at java.base/java.lang.invoke.MethodHandleNatives.newNoSuchMethodErrorOnVarHandle(MethodHandleNatives.java:589)
> at java.base/java.lang.invoke.MethodHandleNatives.varHandleOperationLinkerMethod(MethodHandleNatives.java:542)
> at java.base/java.lang.invoke.MethodHandleNatives.linkMethodImpl(MethodHandleNatives.java:475)
> at java.base/java.lang.invoke.MethodHandleNatives.linkMethod(MethodHandleNatives.java:463)
> at Test.main(Test.java:15)
> 
> However, very similar lambda is expectedly not compilable. Is it
> expected behavior? Looks like a regression to me. I don't see any
> changes in JLS 15.13 between Java 10 and Java 11. Am I missing
> something?
> 
> With best regards,
> Tagir Valeev



More information about the compiler-dev mailing list