Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"VerifyError: Bad type on operand stack" when Class with var extends class with lambda #13630

Closed
jlprat opened this issue Sep 29, 2021 · 2 comments · Fixed by #13639
Closed

Comments

@jlprat
Copy link

jlprat commented Sep 29, 2021

It seems that when we have a class with a var as a member that extends a class that has a lambda as a member the class is not instantiable at runtime.
I check current reported bugs and this is not like any of the others already reported for "Bad type on operand stack".

Compiler version

3.0.2 and 3.1.0-RC2

Minimized code

This code compiles in Scala 3 and in Scala 2. You can find a reproducer here

class ClassWithLambda(sup: () => Long)
class ClassWithVar(var msg: String) extends ClassWithLambda(() => 1)
val _ = new ClassWithVar("foo")

def main(args: Array[String]): Unit = {
  println("it worked")
}

Output

When we run the previous code in Scala 3.x we get the following output.

[error] (run-main-a) java.lang.VerifyError: Bad type on operand stack
[error] Exception Details:
[error]   Location:
[error]     example/Reproducer$ClassWithVar.<init>(Ljava/lang/String;)V @10: invokevirtual
[error]   Reason:
[error]     Type uninitializedThis (current frame, stack[2]) is not assignable to 'example/Reproducer$ClassWithVar'
[error]   Current Frame:
[error]     bci: @10
[error]     flags: { flagThisUninit }
[error]     locals: { uninitializedThis, 'java/lang/String' }
[error]     stack: { uninitializedThis, 'example/Reproducer$', uninitializedThis }
[error]   Bytecode:
[error]     0x0000000: 2a2b b500 0f2a b200 152a b600 18b6 001c
[error]     0x0000010: b700 1fb1
[error] java.lang.VerifyError: Bad type on operand stack
[error] Exception Details:
[error]   Location:
[error]     example/Reproducer$ClassWithVar.<init>(Ljava/lang/String;)V @10: invokevirtual
[error]   Reason:
[error]     Type uninitializedThis (current frame, stack[2]) is not assignable to 'example/Reproducer$ClassWithVar'
[error]   Current Frame:
[error]     bci: @10
[error]     flags: { flagThisUninit }
[error]     locals: { uninitializedThis, 'java/lang/String' }
[error]     stack: { uninitializedThis, 'example/Reproducer$', uninitializedThis }
[error]   Bytecode:
[error]     0x0000000: 2a2b b500 0f2a b200 152a b600 18b6 001c
[error]     0x0000010: b700 1fb1
[error]
[error] 	at example.Reproducer$.<clinit>(Reproducer.scala:19)
[error] 	at example.main.main(Reproducer.scala:21)
[error] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] 	at java.lang.reflect.Method.invoke(Method.java:498)

Expectation

Code should run in Scala 3 (3.0.2 and 3.1.0-RC2) as it runs in Scala 2.

it worked

Notes

Please note that the following does compile and run in Scala 3.x and 2.13.

class ClassWithLambda(sup: () => Long)
class ClassWithoutVar(msg: String) extends ClassWithLambda(() => 1)

class ClassWithoutLambda(something: Int)
class ClassWithVarExtendingNotLambda(var msg: String) extends ClassWithoutLambda(1)

val _ = new ClassWithoutVar("foo") // This can be instantiated at runtime
val _ = new ClassWithVarExtendingNotLambda("foo") // This can be instantiated at runtime

def main(args: Array[String]): Unit = {
  println("it worked")
}
@smarter
Copy link
Member

smarter commented Sep 29, 2021

Workaround:

class ClassWithLambda(sup: () => Long)
class ClassWithVar(_msg: String) extends ClassWithLambda(() => 1) {
  var msg: String = _msg
}

@jlprat
Copy link
Author

jlprat commented Sep 29, 2021

Yes true! I forgot to add the workaround. I came up with the same one.

odersky added a commit to dotty-staging/dotty that referenced this issue Sep 29, 2021
Accesses to var parameters in super calls need to refer to the constructor
parameter, not the getter.

Fixes scala#13630
@odersky odersky assigned dwijnand and unassigned dwijnand Sep 30, 2021
jlprat added a commit to jlprat/kafka that referenced this issue Oct 8, 2021
olsdavis pushed a commit to olsdavis/dotty that referenced this issue Apr 4, 2022
Accesses to var parameters in super calls need to refer to the constructor
parameter, not the getter.

Fixes scala#13630
@Kordyjan Kordyjan added this to the 3.1.1 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants