known translation issues related to JEP 482

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 20 15:15:52 UTC 2024


Hi,
I have put together a patch that overhauls the attribution checks for 
local and member inner class creation:

https://github.com/openjdk/jdk/compare/master...mcimadamore:jdk:refactor_encl_checks?expand=1

This was far more complex than I expected, as I faced issues not only in 
the implementation, but also in the JLS (see below). Let me attempt to 
summarize the rationale behind this fix.

Let’s start with member inner classes. Whenever we see |new M()| where 
|M| is a member inner class, we need to /infer/ an expression for |M|‘s 
enclosing instance, given none is provided. This inference problem is 
also present when checking a |super(...)| constructor call: if the 
superclass is a member inner class |M|, then validating the constructor 
call implies /inferring/ a suitable enclosing instance for |M|, as if we 
were checking |new M()|.

How should this inference process work? Well, it should look at /all/ 
the enclosing instances available to us, and pick the innermost 
enclosing instance of type |C| such that:

  * |C.this| is accessible (e.g. not in |C|‘s early construction
    context) and;
  * |C| is a subclass of |M|‘s enclosing class.

The crucial observation here is that there can be /multiple/ valid 
enclosing instances, and the innermost one might not be available due to 
early construction context, so we need to be able to skip that, and jump 
to the next. Consider this example:

|class Outer { class InnerSuperclass { } static class InnerOuter extends 
Outer { class InnerInnerOuter extends Outer { InnerInnerOuter() { class 
InnerSubclass extends InnerSuperclass { InnerSubclass() { super(); // 
(1) } } super(); } } } } |

This program doesn’t compile today. But should it? Yes: while it’s true 
that |InnerInnerOuter.this| cannot be accessed in (1), |InnerOuter.this| 
can, and that’s also a suitable enclosing instance (as |InnerOuter 
extends Outer|).

What about local classes? Should they undergo a similar check? The 
answer is no, as 15.9.2 is silent about this. What matters, for local 
classes, is that the local class creation expression occurs in a context 
where we can access local variables defined in the method in which the 
local class is defined.

With the new checks in place we can finally solve both:

  * https://bugs.openjdk.org/browse/JDK-8334248 and
  * https://bugs.openjdk.org/browse/JDK-8322882

Few notes:

  * |Lower| needs some updates to support programs like the the one
    above. That is, we have to teach |Lower| that the current class’
    |this| cannot be touched if the class is in early construction context;
  * the JLS text for member inner class creation seems lacking (in both
    15.9.2 and in 8.8.7.1). First, the JLS fails to recognize that a
    /subclass/ of the enclosing instance is still a suitable value for
    constructing the member class. Secondly, the JLS doesn’t seem to
    take early construction contexts into account (so might end up
    picking the wrong thing, or reporting an unnecessary error);
  * the JLS text for local inner class creation in 15.9.2 seems also
    lacking. The check for local classes seems too weak, which leaves
    out intersting cases such as JDK-8322882.

I think that this fix, coupled with the translation fixes I shared last 
week should implement JEP 482 “as intended” (of course, for some of the 
fixes described here, some JLS udpate is also required, as these are not 
“just” compiler bugs).

Cheers
Maurizio

On 14/06/2024 20:49, Archie Cobbs wrote:

    Thanks. Let’s transition this particular discussion to that PR. I
    added a rebuttal for you :)

    https://github.com/openjdk/jdk/pull/19705
    https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/19705__;!!ACWV5N9M2RV99hQ!IPTJtMcgd06MLFxVOwPycDr63fpHIABTrno8GoNywuev7W-GybSntWK-JnxR6AxfqkAm2yp8w79BYUoeki12fBoD2It17g$

    -Archie

    On Fri, Jun 14, 2024 at 12:56 PM Maurizio Cimadamore

    maurizio.cimadamore at oracle.com
    <http://mailto:maurizio.cimadamore@oracle.com> wrote:

    On 14/06/2024 18:51, Archie Cobbs wrote:

        So yes I also see the compiler crashing on that example but I
        think that may be separate from the issue above…? I don’t fully
        understand this one yet.

    I left an example of code that might defeat your fix in the PR.

    https://github.com/openjdk/jdk/pull/19705#issuecomment-2168497505
    https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/19705*issuecomment-2168497505__;Iw!!ACWV5N9M2RV99hQ!IPTJtMcgd06MLFxVOwPycDr63fpHIABTrno8GoNywuev7W-GybSntWK-JnxR6AxfqkAm2yp8w79BYUoeki12fBpkHh3GXQ$

    Maurizio

    — Archie L. Cobbs

​
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20240620/ee281a90/attachment-0001.htm>


More information about the amber-dev mailing list