T? ?: break inference fixed

This commit is contained in:
Sergey Chernov 2026-04-26 21:42:36 +03:00
parent 79429d5f2d
commit 35f4c968a4
2 changed files with 20 additions and 2 deletions

View File

@ -4473,6 +4473,20 @@ class BytecodeCompiler(
} }
private fun compileElvis(ref: ElvisRef): CompiledValue? { private fun compileElvis(ref: ElvisRef): CompiledValue? {
fun isAbruptControlRef(candidate: ObjRef): Boolean {
var stmt = (candidate as? StatementRef)?.statement ?: return false
while (stmt is BytecodeStatement) {
stmt = stmt.original
}
return when (stmt) {
is net.sergeych.lyng.BreakStatement,
is net.sergeych.lyng.ContinueStatement,
is net.sergeych.lyng.ReturnStatement,
is net.sergeych.lyng.ThrowStatement -> true
else -> false
}
}
val leftValue = compileRefWithFallback(ref.left, null, Pos.builtIn) ?: return null val leftValue = compileRefWithFallback(ref.left, null, Pos.builtIn) ?: return null
val leftObj = ensureObjSlot(leftValue) val leftObj = ensureObjSlot(leftValue)
val resultSlot = allocSlot() val resultSlot = allocSlot()
@ -4489,9 +4503,12 @@ class BytecodeCompiler(
emitMove(leftObj, resultSlot) emitMove(leftObj, resultSlot)
builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(endLabel))) builder.emit(Opcode.JMP, listOf(CmdBuilder.Operand.LabelRef(endLabel)))
builder.mark(rightLabel) builder.mark(rightLabel)
val rightIsAbruptControl = isAbruptControlRef(ref.right)
val rightValue = compileRefWithFallback(ref.right, null, Pos.builtIn) ?: return null val rightValue = compileRefWithFallback(ref.right, null, Pos.builtIn) ?: return null
val rightObj = ensureObjSlot(rightValue) if (!rightIsAbruptControl) {
emitMove(rightObj, resultSlot) val rightObj = ensureObjSlot(rightValue)
emitMove(rightObj, resultSlot)
}
builder.mark(endLabel) builder.mark(endLabel)
updateSlotType(resultSlot, SlotType.OBJ) updateSlotType(resultSlot, SlotType.OBJ)
return CompiledValue(resultSlot, SlotType.OBJ) return CompiledValue(resultSlot, SlotType.OBJ)

View File

@ -148,6 +148,7 @@ class OptTest {
val x = t(cnt++) ?: break val x = t(cnt++) ?: break
assertEquals(100, x) assertEquals(100, x)
assertEquals(100, needInt(x)) assertEquals(100, needInt(x))
assertEquals(101, x + 1)
} }
assert( t(3) == null ) assert( t(3) == null )
assert( cnt == 4 ) assert( cnt == 4 )