RFR: 8334248: Invalid error for early construction local class constructor method reference [v3]

Maurizio Cimadamore mcimadamore at openjdk.org
Mon Jun 17 18:07:15 UTC 2024


On Sat, 15 Jun 2024 15:28:40 GMT, Archie Cobbs <acobbs at openjdk.org> wrote:

>> The new "flexible constructors" JEP 482 specifies that a local class declared in an early construction context does not have an immediate outer instance, i.e., it has the same behavior as an anonymous class would in that situation.
>> 
>> However, the compiler still (incorrectly) tries to verify that an outer instance exists in the case of a method reference to the local class' constructor.
>> 
>> Example:
>> 
>> 
>> 
>> import java.util.function.Supplier;
>> 
>> class EarlyLocalCtorRef {
>> 
>>     EarlyLocalCtorRef() {
>>         class InnerLocal { }
>>         this(InnerLocal::new);
>>     }
>> 
>>     EarlyLocalCtorRef(Supplier<Object> s) {
>>     }
>> }
>> 
>> 
>> Expected output: Successful compilation.
>> 
>> Actual output:
>> 
>> 
>> EarlyLocalCtorRef.java:5: error: cannot reference this before supertype constructor has been called
>>         this(InnerLocal::new);
>>              ^ 
>> 
>> 
>> The fix is to not look for an implicit outer instance for classes that don't have one when encountering a constructor method reference.
>> 
>> **NOTE:** The test added here will fail until [JDK-8333313](https://bugs.openjdk.org/browse/JDK-8333313) is fixed.
>
> Archie Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains five additional commits since the last revision:
> 
>  - Refactor resolveImplicitThis() to respect actual outer instance.
>  - Add Maurizio's innermostAccessibleEnclosingClass() and hasOuterInstance().
>  - Merge branch 'master' into JDK-8334248
>  - Future-proof bug fix vs. new & improved semantics of hasOuterInstance().
>  - Don't require outer instance for early construction local class method ref.

Btw, as I was looking at this area, I realized that the following code:


class EarlyLocalClass {
   EarlyLocalClass() {
      class Local {
         void foo() {
            EarlyLocalClass.this.hashCode();    // this should FAIL
         }
      }
}


Fails as expected. But, interestingly, the error is issued very late (in `Lower` rather than in `Attr`). This has to do with the logic that sets `AttrContext::ctorPrologue`: this field is set to `false` as soon as we encounter a local class. So, by the time we see the reference to `EarlyLocalClass.this.hashCode()`, `ctorPrologue` is not set, and no error is issued. This is a bug, and again kind of related to the code you are touching in this PR.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/19705#issuecomment-2174013289


More information about the compiler-dev mailing list