RFR: 8334248: Invalid error for early construction local class constructor method reference [v3]
Archie Cobbs
acobbs at openjdk.org
Tue Jun 18 15:39:14 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.
> But note that the flag is also (c) set to false inside Attr::visitClassDef. I believe this was done to avoid an inner class "inherit" the state from the parent class. But the operation of setting the flag to false occurs on the same "env" as the enclosing class (as we have not yet accessed/created the env for the inner class, that will happen in Attr::attribClass). I think this is probably solved by just moving the code for (c) around.
Ah - gotcha. Interestingly, this bug doesn't change which programs compile, but it does change the error message that gets generaged - and during which phase of compilation it is generated (another `Attr` vs. `Lower` thing). I've created [JDK-8334488](https://bugs.openjdk.org/browse/JDK-8334488) to track this and will fix.
> I'm happy to take a look.
Great - thanks. Let me know if I can help.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/19705#issuecomment-2176403210
More information about the compiler-dev
mailing list