For users, the upshot is that is there were certain methods in the Java reflection API that weren’t callable from Scala 3 — but now they are, as of Scala 3.3.0.
But the blog post goes into detail about those methods and about how we implemented support for them. It may be of interest to JVM aficionados, Scala and Java language mavens, and compiler hackers.
[…] users are not allowed to define their own signature polymorphic methods. Only the Java standard library can do that, and so far, the creators of Java have only used the feature in these two classes [MethodHandle and VarHandle].
But only because Java can’t do something doesn’t mean Scala can’t do it. (My understanding of “users” here was “Java users”.)
I didn’t look up the details until now. Maybe someone could quickly explain: How does the “magic” work? Does the Java std.lib get recognized by the JVM in any way? How? What does it do exactly to use this feature?
invoke/invokeExact/… are native methods with custom implementations hardcoded in HotSpot, there’s nothing we can do to repurpose that at the bytecode level.
Thank you for the explanation. I’d like to ask if changes in compiler (adding TASTY node) is reflected in macro APIs. If I understand it correctly compiler Apply node can be enriched with synthetized MethodType, but I don’t see a way how to do in macros (Scala 3.3.1). Am I missing something?
My attempts to invoke MethodHandle.invokeExact in macro (something like Apply(Select(Ref(handleSymbol), invokeSymbol), argRefs)) ends either with compiler complaining about pickling types or with java.lang.invoke.WrongMethodTypeException at runtime.