Fixed bug in finally blocks lowering + test
Return type must be taken from the function
This commit is contained in:
+10
-4
@@ -26,9 +26,6 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
@@ -38,6 +35,7 @@ import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.builders.irGet
|
import org.jetbrains.kotlin.ir.builders.irGet
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
@@ -177,6 +175,14 @@ internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, Ir
|
|||||||
return performHighLevelJump(tryScopes, 0, jump, startOffset, endOffset, value)
|
return performHighLevelJump(tryScopes, 0, jump, startOffset, endOffset, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val IrReturnTarget.returnType: IrType
|
||||||
|
get() = when (this) {
|
||||||
|
is IrConstructor -> context.irBuiltIns.unitType
|
||||||
|
is IrFunction -> returnType
|
||||||
|
is IrReturnableBlock -> type
|
||||||
|
else -> error("Unknown ReturnTarget: $this")
|
||||||
|
}
|
||||||
|
|
||||||
private fun performHighLevelJump(tryScopes: List<TryScope>,
|
private fun performHighLevelJump(tryScopes: List<TryScope>,
|
||||||
index: Int,
|
index: Int,
|
||||||
jump: HighLevelJump,
|
jump: HighLevelJump,
|
||||||
@@ -188,7 +194,7 @@ internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, Ir
|
|||||||
|
|
||||||
val currentTryScope = tryScopes[index]
|
val currentTryScope = tryScopes[index]
|
||||||
currentTryScope.jumps.getOrPut(jump) {
|
currentTryScope.jumps.getOrPut(jump) {
|
||||||
val type = value.type
|
val type = (jump as? Return)?.target?.owner?.returnType ?: value.type
|
||||||
val symbol = getIrReturnableBlockSymbol(jump.toString(), type)
|
val symbol = getIrReturnableBlockSymbol(jump.toString(), type)
|
||||||
with(currentTryScope) {
|
with(currentTryScope) {
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
|
|||||||
@@ -1893,6 +1893,11 @@ task finally11(type: RunKonanTest) {
|
|||||||
source = "codegen/try/finally11.kt"
|
source = "codegen/try/finally11.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task finally_returnsDifferentTypes(type: RunKonanTest) {
|
||||||
|
goldValue = "zzz\n42\n"
|
||||||
|
source = "codegen/try/returnsDifferentTypes.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task scope1(type: RunKonanTest) {
|
task scope1(type: RunKonanTest) {
|
||||||
goldValue = "1\n"
|
goldValue = "1\n"
|
||||||
source = "codegen/dataflow/scope1.kt"
|
source = "codegen/dataflow/scope1.kt"
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package codegen.`try`.returnsDifferentTypes
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class ReceiveChannel<out E>
|
||||||
|
|
||||||
|
inline fun <E, R> ReceiveChannel<E>.consume(block: ReceiveChannel<E>.() -> R): R {
|
||||||
|
try {
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
println("zzz")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <E> ReceiveChannel<E>.elementAtOrElse(index: Int, defaultValue: (Int) -> E): E =
|
||||||
|
consume {
|
||||||
|
if (index < 0)
|
||||||
|
return defaultValue(index)
|
||||||
|
return 42 as E
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <E> ReceiveChannel<E>.elementAt(index: Int): E =
|
||||||
|
elementAtOrElse(index) { throw IndexOutOfBoundsException("qxx") }
|
||||||
|
|
||||||
|
@Test fun runTest() {
|
||||||
|
println(ReceiveChannel<Int>().elementAt(0))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user