diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt index 06c56ba98ec..b679005a6d2 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt @@ -59,10 +59,10 @@ class Fir2IrConversionScope { return function } - private val propertyStack = mutableListOf() + private val propertyStack = mutableListOf>() - fun withProperty(property: IrProperty, f: IrProperty.() -> Unit): IrProperty { - propertyStack += property + fun withProperty(property: IrProperty, firProperty: FirProperty? = null, f: IrProperty.() -> Unit): IrProperty { + propertyStack += (property to firProperty) property.f() propertyStack.removeAt(propertyStack.size - 1) return property @@ -99,6 +99,15 @@ class Fir2IrConversionScope { val irTarget = (firTarget as? FirFunction)?.let { when (it) { is FirConstructor -> declarationStorage.getCachedIrConstructor(it) + is FirPropertyAccessor -> { + for ((property, firProperty) in propertyStack.asReversed()) { + if (firProperty?.getter === firTarget) { + return@let property.getter + } else if (firProperty?.setter === firTarget) { + return@let property.setter + } + } + } else -> declarationStorage.getCachedIrFunction(it) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 8b418059d09..b6f40c35c39 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -269,7 +269,7 @@ class Fir2IrVisitor( override fun visitProperty(property: FirProperty, data: Any?): IrElement { if (property.isLocal) return visitLocalVariable(property) val irProperty = declarationStorage.getCachedIrProperty(property)!! - return conversionScope.withProperty(irProperty) { + return conversionScope.withProperty(irProperty, property) { memberGenerator.convertPropertyContent(irProperty, property, containingClass = conversionScope.containerFirClass()) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index f3c2639dfce..18602971925 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -41,7 +41,7 @@ class FakeOverrideGenerator( } private fun IrProperty.withProperty(f: IrProperty.() -> Unit): IrProperty { - return conversionScope.withProperty(this, f) + return conversionScope.withProperty(this, firProperty = null, f) } private fun FirCallableMemberDeclaration<*>.allowsToHaveFakeOverrideIn(klass: FirClass<*>): Boolean { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java index 03704c65aac..7bd135d100f 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java @@ -2182,6 +2182,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/firProblems/recursiveCapturedTypeInPropertyReference.kt"); } + @Test + @TestMetadata("SafeLetWithReturn.kt") + public void testSafeLetWithReturn() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt"); + } + @Test @TestMetadata("SameJavaFieldReferences.kt") public void testSameJavaFieldReferences() throws Exception { diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/fromInterfaceDefaultGetter.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/fromInterfaceDefaultGetter.kt index 3931a5b00e5..8f2b2734c17 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/fromInterfaceDefaultGetter.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/fromInterfaceDefaultGetter.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/propertyAccessors.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/propertyAccessors.kt index c7229da93c3..275024ae34f 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/propertyAccessors.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/propertyAccessors.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.kt.txt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.kt.txt new file mode 100644 index 00000000000..3bf28334e98 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.kt.txt @@ -0,0 +1,52 @@ +fun foo(s: String?): String { + { // BLOCK + val tmp0_safe_receiver: String? = s + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + return "" +} + +fun bar(s: String?, t: String?): String { + { // BLOCK + val tmp1_safe_receiver: String? = s + when { + EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null + else -> tmp1_safe_receiver.let(block = local fun (it: String): Nothing? { + return { // BLOCK + val tmp2_safe_receiver: String? = t + when { + EQEQ(arg0 = tmp2_safe_receiver, arg1 = null) -> null + else -> tmp2_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } + } +) + } + } /*~> Unit */ + return "" +} + +val String?.baz: String + get(): String { + { // BLOCK + val tmp3_safe_receiver: String? = + when { + EQEQ(arg0 = tmp3_safe_receiver, arg1 = null) -> null + else -> tmp3_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + return "" + } + diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.txt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.txt new file mode 100644 index 00000000000..4a50937c199 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.txt @@ -0,0 +1,105 @@ +FILE fqName: fileName:/SafeLetWithReturn.kt + FUN name:foo visibility:public modality:FINAL <> (s:kotlin.String?) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.String? [val] + GET_VAR 's: kotlin.String? declared in .foo' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .foo' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .foo' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun foo (s: kotlin.String?): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in .foo.' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun foo (s: kotlin.String?): kotlin.String declared in ' + CONST String type=kotlin.String value="" + FUN name:bar visibility:public modality:FINAL <> (s:kotlin.String?, t:kotlin.String?) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String? + VALUE_PARAMETER name:t index:1 type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.String? [val] + GET_VAR 's: kotlin.String? declared in .bar' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .bar' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing? origin=null + : kotlin.String + : kotlin.Nothing? + $receiver: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .bar' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing? + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.String): kotlin.Nothing? declared in .bar' + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.String? [val] + GET_VAR 't: kotlin.String? declared in .bar' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .bar.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .bar.' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun bar (s: kotlin.String?, t: kotlin.String?): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in .bar..' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun bar (s: kotlin.String?, t: kotlin.String?): kotlin.String declared in ' + CONST String type=kotlin.String value="" + PROPERTY name:baz visibility:public modality:FINAL [val] + FUN name: visibility:public modality:FINAL <> ($receiver:kotlin.String?) returnType:kotlin.String + correspondingProperty: PROPERTY name:baz visibility:public modality:FINAL [val] + $receiver: VALUE_PARAMETER name: type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.String? [val] + GET_VAR ': kotlin.String? declared in .' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_3: kotlin.String? [val] declared in .' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_3: kotlin.String? [val] declared in .' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in ..' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + CONST String type=kotlin.String value="" diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt new file mode 100644 index 00000000000..a1944d97ff4 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt @@ -0,0 +1,25 @@ +// WITH_RUNTIME + +fun foo(s: String?): String { + s?.let { it -> + return it + } + return "" +} + +fun bar(s: String?, t: String?): String { + s?.let { + t?.let { + return it + } + } + return "" +} + +val String?.baz: String + get() { + this?.let { + return it + } + return "" + } \ No newline at end of file diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt.txt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt.txt new file mode 100644 index 00000000000..aca6153a0e8 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt.txt @@ -0,0 +1,52 @@ +fun foo(s: String?): String { + { // BLOCK + val tmp0_safe_receiver: String? = s + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + return "" +} + +fun bar(s: String?, t: String?): String { + { // BLOCK + val tmp0_safe_receiver: String? = s + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing? { + { // BLOCK + val tmp0_safe_receiver: String? = t + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + } +) + } + } /*~> Unit */ + return "" +} + +val String?.baz: String + get(): String { + { // BLOCK + val tmp0_safe_receiver: String? = + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + return "" + } + diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.txt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.txt new file mode 100644 index 00000000000..78487630cb9 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.txt @@ -0,0 +1,105 @@ +FILE fqName: fileName:/SafeLetWithReturn.kt + FUN name:foo visibility:public modality:FINAL <> (s:kotlin.String?) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.String? [val] + GET_VAR 's: kotlin.String? declared in .foo' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .foo' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .foo' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun foo (s: kotlin.String?): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in .foo.' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun foo (s: kotlin.String?): kotlin.String declared in ' + CONST String type=kotlin.String value="" + FUN name:bar visibility:public modality:FINAL <> (s:kotlin.String?, t:kotlin.String?) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String? + VALUE_PARAMETER name:t index:1 type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.String? [val] + GET_VAR 's: kotlin.String? declared in .bar' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .bar' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing? origin=null + : kotlin.String + : kotlin.Nothing? + $receiver: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .bar' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing? + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.String? [val] + GET_VAR 't: kotlin.String? declared in .bar' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .bar.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .bar.' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun bar (s: kotlin.String?, t: kotlin.String?): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in .bar..' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun bar (s: kotlin.String?, t: kotlin.String?): kotlin.String declared in ' + CONST String type=kotlin.String value="" + PROPERTY name:baz visibility:public modality:FINAL [val] + FUN name: visibility:public modality:FINAL <> ($receiver:kotlin.String?) returnType:kotlin.String + correspondingProperty: PROPERTY name:baz visibility:public modality:FINAL [val] + $receiver: VALUE_PARAMETER name: type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.String? [val] + GET_VAR ': kotlin.String? declared in .' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_3: kotlin.String? [val] declared in .' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_3: kotlin.String? [val] declared in .' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in ..' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + CONST String type=kotlin.String value="" diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java index 9f6dbe9f456..47055458097 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java @@ -2182,6 +2182,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest { runTest("compiler/testData/ir/irText/firProblems/recursiveCapturedTypeInPropertyReference.kt"); } + @Test + @TestMetadata("SafeLetWithReturn.kt") + public void testSafeLetWithReturn() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt"); + } + @Test @TestMetadata("SameJavaFieldReferences.kt") public void testSameJavaFieldReferences() throws Exception {