Closed
Description
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.