Fix VerifyError for by-name default args in object super calls #24983
+76
−20
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #24201
An object with
cause a
VerifyErrorat runtime because compiler generates a static method that incorrectly tries to accessthisbefore initialization.The
Bazin above Scala code, and it's compiled to the following JVM bytecode:The JVM verifier rejects this because
aload_0at offset 8 loads an uninitializedthisreference, andinvokespecialat offset 9 tries to call an instance method on it before the super constructor completes.Problem
After Typer, the Baz constructor looks like this:
And, after
ElimByName+HoistSuperArgs:HoistSuperArgscreates a static helper method that evaluates complex super call arguments outside the constructor context.So it creates:
And the super call becomes:
The Tree
However, to pass
defaultValue$1as an argument to this static method, the compiler generatesthis.defaultValue$1(), which requiresthisto be initialized. So even though the static method itself doesn't usethis, the call site accessthisbefore initializatin.This commit fixes the invalid code generation by inlining
defaultValue$1's body directly into the static method, and now we don't need to referencethisat the call site.In HoistSuperArgs, detect lifted by-name methods (synthetic methods with ExprType info) in the super call Block, store their bodies, and inline references to them in the hoisted static method. This avoids passing instance method references to static methods during super call evaluation.