[lworld] RFR: 8244982: [lworld] Javac does not compile test/jdk/valhalla/valuetypes/StreamTest.java anymore
jlaskey at openjdk.java.net
Fri May 15 11:51:15 UTC 2020
On Fri, 15 May 2020 05:06:46 GMT, Srikanth Adayapalam <sadayapalam at openjdk.org> wrote:
> Jim, could you please review this fix ? Here is some background:
> ATM, we infer (by design) Arrays.stream(X) to be a Stream<X.ref> (and not as
> Stream<X\> as the latter is malformed as of now) and so the method reference X::data
> ends up with a receiver type of X.ref instead of X.
> Until such time JLS 15.13.1 (Compile-Time Declaration of a Method Reference) is
> amended to account for inline widening/narrowing conversions, this is ilegal
> code (as there is no subtyping relationship between X.ref and X) and to make it
> work the test has to be changed to use X.ref::data instead of X::data
> With this change, the test code would compile, but in order to be able to run it
> we need a further tweak in LambdaToMethod. Since in the present code generation
> scheme, X$ref.class files are completely empty, lambda meta factory would go looking
> for a method data() in X$ref during bootstrap and this would result in a
> NoSuchMethodError. To workaround that, we use a tried and tested trick in javac
> land where we fold the method reference into a lambda and in the lambda body apply
> suitable inline conversions.
> So the method reference X.ref::data gets transformed into an equivalent lambda
> (Object rec$)->((X.ref)rec$).data()
> in com.sun.tools.javac.comp.LambdaToMethod.MemberReferenceToLambda#lambda
> This also has the "wrong" receiver, but we already have code in
> com.sun.tools.javac.jvm.TransValues#visitSelect to sharpen the receiver and
> make it ((X)(X.ref)rec$).data()
> Finally, there also a change in TransValues that is not essential to this fix,
> but is related. We were inadvertantly changing a local variable (only) without
> really changing the AST (as we should). This is corrected now.
> (If you are wondering how despite this things were working, that is because
> com.sun.tools.javac.jvm.Gen#binaryQualifier was covering for us. It is not
> incorrect to let com.sun.tools.javac.jvm.Gen#binaryQualifier handle it, but
> is a waste of resource in that it creates an additional clone, while we
> already have a clone handy)
Thanks for the explanation. Looks good. Love it when punting still yields a good result.
Marked as reviewed by jlaskey (no project role).
More information about the valhalla-dev