eclipse-jdt / eclipse.jdt.core

Eclipse Public License 2.0
165 stars 130 forks source link

Unreported "illegal reference to static field from initializer" in relation to javac #1590

Open nlisker opened 1 year ago

nlisker commented 1 year ago

Copied and updated from https://bugs.eclipse.org/bugs/show_bug.cgi?id=577373:

Originally I mentioned this in https://bugs.eclipse.org/bugs/show_bug.cgi?id=533475#c3, but it seems to be a different error since that bug was fixed and this one remains.

The code

enum MyEnum {
;

    private static MyEnum selected;

    private MyEnum() {
        Supplier<MyEnum> s = () -> selected = this;
    }
}

compiles fine in Eclipse, but using Gradle I get the error:

C:\ZSwitch\src\main\java\switchTests\SwitchTest.java:39: error: illegal reference to static field from initializer
                            Supplier<MyEnum> s = () -> selected = this;
                                                       ^

I don't know which compiler is correct, but unless the specifications are lenient, these should be aligned.

I first encountered it with Java 10 and Eclipse 4.7.3, and it's the same with Java 21 and Eclipse 4.29.

jukzi commented 11 months ago

quoting https://stackoverflow.com/questions/29174345/illegal-reference-to-static-field-from-initializer From Java Language Specification:

It is a compile-time error to reference a static field of an enum type that is not a constant variable (§4.12.4) from constructors, instance initializer blocks, or instance variable initializer expressions of that type.

nlisker commented 1 month ago

Tested with 4.33 in case something changed. Incorrect behavior as well.

srikanth-sankaran commented 4 weeks ago

JLS 23: 8.9.2 Enum Body Declarations

It is a compile-time error to refer to a static field of an enum class from a constructor, instance initializer, or instance variable initializer in the enum declaration of the class, unless the field is a constant variable ((§4.12.4).

srikanth-sankaran commented 4 weeks ago

I think we should "make haste slowly" - whether an intervening lambda alters the context is to be studied more thoroughly. Javac behavior is not very consistent: See that the following code issues only one error:

import java.util.function.Supplier;
import java.util.HashSet;

enum MyEnum {
;

    private static MyEnum selected;

    private MyEnum() {
        Supplier<MyEnum> s = () -> selected = this;
    }

    public HashSet<MyEnum> vals = new HashSet<MyEnum>(){{
        add(selected);
      }};
}

javac has some open tickets in this space:

https://bugs.openjdk.org/browse/JDK-8173165