-
Bug
-
Resolution: Fixed
-
P4
-
8, 8u40, 9
-
b25
public class InterfaceMethodref {
interface I { void m(); }
abstract class C implements I {}
public void test(C arg) {
Runnable r = arg::m;
}
}
The method reference 'arg::m' compiles to:
6: invokedynamic #3, 0 // InvokeDynamic #0:run:(LInterfaceMethodref$C;)Ljava/lang/Runnable;
With bootstrap method:
0: #22 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#23 ()V
#24 invokeinterface InterfaceMethodref$I.m:()V
#23 ()V
Note that the metafactory call's implMethod is "invokeinterface InterfaceMethodref$I.m:()V", not "invokevirtual InterfaceMethodref$C.m:()V". This is incorrect: the compiler must refer to the type of the receiver, not the type of the declaring class/interface, per JLS 13.1 (see "the qualifying type of the method invocation").
Also, FWIW, this combination of implMethod and invokedType violates the invariants claimed to be enforced by LambdaMetafactory (specifically, referring to the Javadoc, D1 != A1). Apparently this isn't currently enforced.
interface I { void m(); }
abstract class C implements I {}
public void test(C arg) {
Runnable r = arg::m;
}
}
The method reference 'arg::m' compiles to:
6: invokedynamic #3, 0 // InvokeDynamic #0:run:(LInterfaceMethodref$C;)Ljava/lang/Runnable;
With bootstrap method:
0: #22 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#23 ()V
#24 invokeinterface InterfaceMethodref$I.m:()V
#23 ()V
Note that the metafactory call's implMethod is "invokeinterface InterfaceMethodref$I.m:()V", not "invokevirtual InterfaceMethodref$C.m:()V". This is incorrect: the compiler must refer to the type of the receiver, not the type of the declaring class/interface, per JLS 13.1 (see "the qualifying type of the method invocation").
Also, FWIW, this combination of implMethod and invokedType violates the invariants claimed to be enforced by LambdaMetafactory (specifically, referring to the Javadoc, D1 != A1). Apparently this isn't currently enforced.
- csr for
-
JDK-8295975 Method reference compilation uses incorrect qualifying type
-
- Closed
-
- relates to
-
JDK-8301046 Method reference compilation uses incorrect qualifying type
-
- Open
-
-
JDK-8143647 Javac compiles method reference that allows results in an IllegalAccessError
-
- Closed
-
-
JDK-8154236 Deserialization of lambda causes ClassCastException
-
- Open
-
-
JDK-8300623 Lambda deserialization regression involving Enum method reference
-
- Closed
-
-
JDK-8049898 BootstrapMethodError is thrown for method reference with intersection type bound
-
- Closed
-
(1 relates to, 2 links to)