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