I wanted to test the following snippet in Kotlin REPL in IDEA:
import java.util.EnumSet
inline fun <reified E : Enum<E>> E.next(): E {
val values = enumValues<E>()
val ordinal = (this.ordinal + 1) % values.size
return values[ordinal]
}
inline fun <reified E : Enum<E>> E.next(set: EnumSet<E>): E {
var element = this
do {
element = element.next()
} while (element !in set)
return element
}
enum class E { A, B, C, D }
val set = EnumSet.of(E.A, E.C)!!
println(E.A.next(set))
However, instead of C
, what I got was:
exception: java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
Line_0.<init>()V @76: invokevirtual
Reason:
Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'java/lang/Enum'
Current Frame:
bci: @76
flags: { }
locals: { 'Line_0', 'Line_0', 'java/lang/Enum', 'java/util/EnumSet', integer, 'java/lang/Object', 'java/lang/Object', 'Line_0', integer, '[LLine_0$E;', top, 'Line_0', 'Line_0' }
stack: { 'java/lang/Object' }
Bytecode:
0000000: 2ab7 0048 2a2a b200 4dc0 0019 b200 50c0
0000010: 0019 b800 5459 b800 58b5 003a 2a2a c000
0000020: 02b2 004d c000 194d 4c2a c000 02b4 003a
0000030: 4e3a 0c3a 0b03 3604 2c3a 052b 1905 3a06
0000040: 3a07 0336 08b8 005b 3a09 1906 b600 1d04
0000050: 6019 09be 7036 0a19 0915 0a32 3a05 2d19
0000060: 05b6 002e 99ff d719 053a 0d19 0b19 0c19
0000070: 0db5 005d b1
Stackmap Table:
full_frame(@59,{Object[#2],Object[#2],Object[#25],Object[#42],Integer,Object[#4],Top,Top,Top,Top,Top,Object[#2],Object[#2]},{})
at java.base/java.lang.Class.getDeclaredConstructors0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3215)
at java.base/java.lang.Class.getConstructor0(Class.java:3420)
at java.base/java.lang.Class.getConstructor(Class.java:2165)
at org.jetbrains.kotlin.cli.common.repl.GenericReplEvaluator.eval(GenericReplEvaluator.kt:88)
at org.jetbrains.kotlin.cli.common.repl.GenericReplCompilingEvaluatorBase.eval(GenericReplCompilingEvaluator.kt:76)
at org.jetbrains.kotlin.cli.common.repl.GenericReplCompilingEvaluatorBase.compileAndEval(GenericReplCompilingEvaluator.kt:51)
at org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplInterpreter.eval(ReplInterpreter.kt:97)
at org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplFromTerminal.eval(ReplFromTerminal.kt:103)
at org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplFromTerminal.one(ReplFromTerminal.kt:94)
at org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplFromTerminal.doRun(ReplFromTerminal.kt:59)
at org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplFromTerminal.access$doRun(ReplFromTerminal.kt:26)
at org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplFromTerminal$Companion.run(ReplFromTerminal.kt:159)
at org.jetbrains.kotlin.scripting.compiler.plugin.JvmCliReplShellExtension.run(JvmCliReplShellExtension.kt:24)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:109)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:51)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:86)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:44)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:98)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:76)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:45)
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:227)
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit$default(CLITool.kt:225)
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMain(CLITool.kt:214)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler$Companion.main(K2JVMCompiler.kt:262)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.main(K2JVMCompiler.kt)
Process finished with exit code 2
The same code works without a hitch from a scratch file (it returns C
, as I would expect).
At this point I’m curious as to what’s actually going on, and whether it’s a bug in Kotlin REPL or somewhere else.
Kotlin version 1.4.10 (JRE 14.0.2+12-46) (-Dkotlin.repl.ideMode=true -Dfile.encoding=UTF-8)