Skip to content

java.lang.VerifyError with erased value #16943

Closed
@reftrans

Description

@reftrans

Compiler version

3.2.2 and also the actual latest git version 250757732398b92cb6fc8f02e50526573f1ba2b9.

Minimized code

@main
@annotation.experimental
def run(): Unit = fail(compiletime.erasedValue, 1)

@annotation.experimental
def fail(dumb: CanThrow[Exception], x: Int) = println(x)

Any erased type can be used, it does not have to be CanThrow[Exception].

Compile and run with scalac crash.scala && scala run.

Output

Compilation succeeds, runtime output is:

Exception in thread "main" java.lang.VerifyError: Bad local variable type
Exception Details:
  Location:
    crash$package$.fail()V @3: iload_1
  Reason:
    Type top (current frame, locals[1]) is not assignable to integer
  Current Frame:
    bci: @3
    flags: { }
    locals: { 'crash$package$' }
    stack: { 'scala/Predef$' }
  Bytecode:
    0000000: b200 231b b800 29b6 002d b1            

	at run.main(crash.scala:2)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at dotty.tools.runner.RichClassLoader$.run$extension$$anonfun$1(ScalaClassLoader.scala:36)
	at dotty.tools.runner.ScalaClassLoader$.asContext(ScalaClassLoader.scala:80)
	at dotty.tools.runner.RichClassLoader$.dotty$tools$runner$RichClassLoader$$$asContext$extension(ScalaClassLoader.scala:18)
	at dotty.tools.runner.RichClassLoader$.run$extension(ScalaClassLoader.scala:36)
	at dotty.tools.runner.CommonRunner.run(ObjectRunner.scala:23)
	at dotty.tools.runner.CommonRunner.run$(ObjectRunner.scala:13)
	at dotty.tools.runner.ObjectRunner$.run(ObjectRunner.scala:48)
	at dotty.tools.runner.CommonRunner.runAndCatch(ObjectRunner.scala:30)
	at dotty.tools.runner.CommonRunner.runAndCatch$(ObjectRunner.scala:13)
	at dotty.tools.runner.ObjectRunner$.runAndCatch(ObjectRunner.scala:48)
	at dotty.tools.MainGenericRunner$.run$1(MainGenericRunner.scala:215)
	at dotty.tools.MainGenericRunner$.process(MainGenericRunner.scala:270)
	at dotty.tools.MainGenericRunner$.main(MainGenericRunner.scala:281)
	at dotty.tools.MainGenericRunner.main(MainGenericRunner.scala)

It seems that the method def and call disagree on whether the erased parameter is erased or not. It is interesting, if the parameters are switched at the call site and def site, an incorrect compile error is produced instead:

4 |def run(): Unit = fail(1, compiletime.erasedValue)
  |                          ^^^^^^^^^^^^^^^^^^^^^^^
  |                          method erasedValue is declared as `erased`, but is in fact used
1 error found

Expectation

No crash, successful compilation.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions