diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReturnsInsertionLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReturnsInsertionLowering.kt index 35d443b3576..51c845647ed 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReturnsInsertionLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReturnsInsertionLowering.kt @@ -40,8 +40,14 @@ internal class ReturnsInsertionLowering(val context: Context) : FileLoweringPass } } is IrBlockBody -> { - if (declaration is IrConstructor || declaration.returnType == context.irBuiltIns.unitType) + if (declaration is IrConstructor || declaration.returnType == context.irBuiltIns.unitType) { body.statements += irReturn(irGetObject(symbols.unit)) + } else if (declaration.returnType == context.irBuiltIns.nothingNType) { + val typeOperatorCall = body.statements.singleOrNull() as? IrTypeOperatorCall + if (typeOperatorCall?.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) { + body.statements[0] = irReturn(typeOperatorCall.argument) + } + } } } } diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index 7764bf2cdb5..e3404314fce 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -530,6 +530,16 @@ task sum_3const(type: KonanLocalTest) { source = "codegen/function/sum_3const.kt" } +standaloneTest("function_nothingN_returning_safe_call1") { + flags = ["-g", "-entry", "codegen.function.nothingN_returning_safe_call1.main"] + source = "codegen/function/nothingNReturningSafeCall1.kt" +} + +standaloneTest("function_nothingN_returning_safe_call2") { + flags = ["-g", "-entry", "codegen.function.nothingN_returning_safe_call2.main"] + source = "codegen/function/nothingNReturningSafeCall2.kt" +} + task codegen_controlflow_for_loops(type: KonanLocalTest) { source = "codegen/controlflow/for_loops.kt" goldValue = "01234\n0123\n43210\n\n024\n02\n420\n\n036\n03\n630\n\n024\n02\n420\n\n" diff --git a/kotlin-native/backend.native/tests/codegen/function/nothingNReturningSafeCall1.kt b/kotlin-native/backend.native/tests/codegen/function/nothingNReturningSafeCall1.kt new file mode 100644 index 00000000000..7bcaebc6396 --- /dev/null +++ b/kotlin-native/backend.native/tests/codegen/function/nothingNReturningSafeCall1.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package codegen.function.nothingN_returning_safe_call1 + +import kotlin.test.* + +fun Any.nothing(): Nothing { + while (true) {} +} + +fun foo(obj: Any?): Nothing? = obj?.nothing() + +fun main() { + foo(null) +} diff --git a/kotlin-native/backend.native/tests/codegen/function/nothingNReturningSafeCall2.kt b/kotlin-native/backend.native/tests/codegen/function/nothingNReturningSafeCall2.kt new file mode 100644 index 00000000000..4d2adac4d08 --- /dev/null +++ b/kotlin-native/backend.native/tests/codegen/function/nothingNReturningSafeCall2.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package codegen.function.nothingN_returning_safe_call2 + +import kotlin.test.* + +fun Any.nothing(): Nothing { + while (true) {} +} + +fun foo() { + val block: (Any?) -> Nothing? = { + it?.nothing() + } + block(null) +} + +fun main() { + foo() +}