You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix Java enum forwarders to pull from companion on initialization
Fixes#12637
Previously, Java enum forwarders were initialized to null when the companion's static initializer was triggered before the Java enum forwarder class's static initializer.
For example, when `enum Testme extends java.lang.Enum[Testme]` is accessed from Scala (which accesses `Testme$.Hello`):
- `Testme$.<clinit>` is triggered
- The static initializer creates enum values by calling `Testme$.new(...)`
- It constructs `Testme$$anon$1` (which represents `Hello`), a subtype of `Testme`
- Therefore, `Testme.<clinit>` is triggered
- `Testme.<clinit>` tries to initialize its `Testme.Hello` field by pulling from `Testme$.Hello`
- However, it's still null during the companion's static initialization!
See: #12637 (comment)
```scala
// Testme.scala
object TestenumS:
def go() = println("Scala: Testme Hello= " + Testme.Hello)
enum Testme extends java.lang.Enum[Testme]:
case Hello
// TestenumJ.java
public class TestenumJ {
public static void main(String[] args) {
TestenumS.go();
System.out.println("Java: Testme Hello= " + Testme.Hello);
}
}
```
This commit fixes the initialization problem by having the companion object's static initializer push enum values to the forwarders after it finishes initializing the enum value fields.
**When the companion is accessed first:**
- Companion's `<clinit>` runs and creates enum values
- During initialization, the forwarder's `<clinit>` is triggered
- Forwarders pull from the companion (value will be null)
- Companion's `<clinit>` pushes final values to forwarders at the end
**When the forwarder is accessed first:**
- Enum class's `<clinit>` tries to initialize the forwarder via `getstatic` from the companion
- This triggers the companion's `<clinit>` first
- Companion's `<clinit>` pushes values to the forwarders
- The original `putstatic` completes (resulting in double assignment, but with the correct value)
**Drawbacks:**
- We assign the forwarder field twice, making it slightly slower than before
- **We changed the Java enum forwarder fields to be non-final**
0 commit comments