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.IrStatement
|
||||
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.descriptors.IrTemporaryVariableDescriptorImpl
|
||||
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.types.IrType
|
||||
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.util.defaultType
|
||||
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)
|
||||
}
|
||||
|
||||
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>,
|
||||
index: Int,
|
||||
jump: HighLevelJump,
|
||||
@@ -188,7 +194,7 @@ internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, Ir
|
||||
|
||||
val currentTryScope = tryScopes[index]
|
||||
currentTryScope.jumps.getOrPut(jump) {
|
||||
val type = value.type
|
||||
val type = (jump as? Return)?.target?.owner?.returnType ?: value.type
|
||||
val symbol = getIrReturnableBlockSymbol(jump.toString(), type)
|
||||
with(currentTryScope) {
|
||||
irBuilder.run {
|
||||
|
||||
@@ -1893,6 +1893,11 @@ task finally11(type: RunKonanTest) {
|
||||
source = "codegen/try/finally11.kt"
|
||||
}
|
||||
|
||||
task finally_returnsDifferentTypes(type: RunKonanTest) {
|
||||
goldValue = "zzz\n42\n"
|
||||
source = "codegen/try/returnsDifferentTypes.kt"
|
||||
}
|
||||
|
||||
task scope1(type: RunKonanTest) {
|
||||
goldValue = "1\n"
|
||||
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