From 127be9be03fe2111e256e1f21c97c03af7cce859 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 19 Jul 2019 13:33:20 +0300 Subject: [PATCH] psi2ir: Fix KT-30796 ErrorType for '?:' in OI --- .../kotlin/fir/Fir2IrTextTestGenerated.java | 5 + .../generators/OperatorExpressionGenerator.kt | 27 ++- .../ir/irText/expressions/kt30796.fir.txt | 161 ++++++++++++++++++ .../testData/ir/irText/expressions/kt30796.kt | 11 ++ .../ir/irText/expressions/kt30796.txt | 160 +++++++++++++++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 5 + 6 files changed, 367 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/ir/irText/expressions/kt30796.fir.txt create mode 100644 compiler/testData/ir/irText/expressions/kt30796.kt create mode 100644 compiler/testData/ir/irText/expressions/kt30796.txt diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index b508eeaaba8..9da6b6da652 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -1017,6 +1017,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/expressions/kt30020.kt"); } + @TestMetadata("kt30796.kt") + public void testKt30796() throws Exception { + runTest("compiler/testData/ir/irText/expressions/kt30796.kt"); + } + @TestMetadata("lambdaInCAO.kt") public void testLambdaInCAO() throws Exception { runTest("compiler/testData/ir/irText/expressions/lambdaInCAO.kt"); diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt index 3bc873fe4a9..07fec5a51cb 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* @@ -35,11 +36,14 @@ import org.jetbrains.kotlin.psi2ir.containsNull import org.jetbrains.kotlin.psi2ir.findSingleFunction import org.jetbrains.kotlin.psi2ir.intermediate.safeCallOnDispatchReceiver import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.checkers.PrimitiveNumericComparisonInfo import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.checker.intersectTypes import org.jetbrains.kotlin.types.isDynamic +import org.jetbrains.kotlin.types.isError import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable @@ -190,9 +194,28 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat } } + private fun getResultTypeForElvis(expression: KtExpression): KotlinType { + val binaryExpression = KtPsiUtil.safeDeparenthesize(expression) + val expressionType = context.bindingContext.getType(binaryExpression)!! + if (binaryExpression !is KtBinaryExpression || binaryExpression.operationToken != KtTokens.ELVIS) return expressionType + + val inferredType = getResolvedCall(binaryExpression)!!.resultingDescriptor.returnType!! + + // OI has a rather complex bug with constraint system for special call for '?:' that breaks IR-based back-ends. + // In NI this bug is fixed. + if (context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) return inferredType + + if (!inferredType.isError) return inferredType + + // Infer type for elvis manually. Take into account possibly nested elvises. + val rightType = getResultTypeForElvis(binaryExpression.right!!).unwrap() + val leftType = getResultTypeForElvis(binaryExpression.left!!).unwrap() + val leftNNType = intersectTypes(listOf(leftType, context.builtIns.anyType)) + return NewCommonSuperTypeCalculator.commonSuperType(listOf(rightType, leftNNType)) + } + private fun generateElvis(expression: KtBinaryExpression): IrExpression { - val specialCallForElvis = getResolvedCall(expression)!! - val resultType = specialCallForElvis.resultingDescriptor.returnType!!.toIrType() + val resultType = getResultTypeForElvis(expression).toIrType() val irArgument0 = expression.left!!.genExpr() val irArgument1 = expression.right!!.genExpr() diff --git a/compiler/testData/ir/irText/expressions/kt30796.fir.txt b/compiler/testData/ir/irText/expressions/kt30796.fir.txt new file mode 100644 index 00000000000..f5132924a43 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt30796.fir.txt @@ -0,0 +1,161 @@ +FILE fqName: fileName:/kt30796.kt + FUN name:magic visibility:public modality:FINAL () returnType:T of .magic + TYPE_PARAMETER name:T index:0 variance: superTypes:[] + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun magic (): T of .magic declared in ' + THROW type=kotlin.Nothing + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + FUN name:test visibility:public modality:FINAL (value:T of .test, value2:T of .test) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[] + VALUE_PARAMETER name:value index:0 type:T of .test + VALUE_PARAMETER name:value2 index:1 type:T of .test + BLOCK_BODY + VAR name:x1 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR name: type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Any value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x2 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR name: type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: BLOCK type=kotlin.Any origin=ELVIS + VAR name: type:T of .test [val] + GET_VAR 'value2: T of .test declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Any value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x3 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR name: type:T of .test [val] + BLOCK type=T of .test origin=ELVIS + VAR name: type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=T of .test origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: GET_VAR 'value2: T of .test declared in .test' type=T of .test origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Any value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x4 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR name: type:T of .test [val] + BLOCK type=T of .test origin=ELVIS + VAR name: type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=T of .test origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: GET_VAR 'value2: T of .test declared in .test' type=T of .test origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Any value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x5 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR name: type:kotlin.Nothing [val] + CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Nothing origin=null + : + WHEN type=kotlin.Any origin=ELVIS + 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 : kotlin.Nothing [val] declared in .test' type=kotlin.Nothing origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Any value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : kotlin.Nothing [val] declared in .test' type=kotlin.Nothing origin=null + VAR name:x6 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR name: type:T of .test [val] + BLOCK type=T of .test origin=ELVIS + VAR name: type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=T of .test origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Nothing origin=null + : + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Any value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x7 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR name: type:T of .test [val] + BLOCK type=T of .test origin=ELVIS + VAR name: type:kotlin.Nothing [val] + CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Nothing origin=null + : + WHEN type=T of .test origin=ELVIS + 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 : kotlin.Nothing [val] declared in .test' type=kotlin.Nothing origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : kotlin.Nothing [val] declared in .test' type=kotlin.Nothing origin=null + WHEN type=kotlin.Any origin=ELVIS + 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 : T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Any value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val : T of .test [val] declared in .test' type=T of .test origin=null diff --git a/compiler/testData/ir/irText/expressions/kt30796.kt b/compiler/testData/ir/irText/expressions/kt30796.kt new file mode 100644 index 00000000000..9340f19663c --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt30796.kt @@ -0,0 +1,11 @@ +fun magic(): T = throw Exception() + +fun test(value: T, value2: T) { + val x1: Any = value ?: 42 + val x2: Any = value ?: (value2 ?: 42) + val x3: Any = (value ?: value2) ?: 42 + val x4: Any = value ?: value2 ?: 42 + val x5: Any = magic() ?: 42 + val x6: Any = value ?: magic() ?: 42 + val x7: Any = magic() ?: value ?: 42 +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/kt30796.txt b/compiler/testData/ir/irText/expressions/kt30796.txt new file mode 100644 index 00000000000..e03786c0fee --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt30796.txt @@ -0,0 +1,160 @@ +FILE fqName: fileName:/kt30796.kt + FUN name:magic visibility:public modality:FINAL () returnType:T of .magic + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + BLOCK_BODY + THROW type=kotlin.Nothing + CONSTRUCTOR_CALL 'public constructor () declared in java.lang.Exception' type=java.lang.Exception origin=null + FUN name:test visibility:public modality:FINAL (value:T of .test, value2:T of .test) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:value index:0 type:T of .test + VALUE_PARAMETER name:value2 index:1 type:T of .test + BLOCK_BODY + VAR name:x1 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp0_elvis_lhs type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any 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 tmp0_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Int value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp0_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x2 type:kotlin.Any [val] + BLOCK type=kotlin.Any? origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp2_elvis_lhs type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any? 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 tmp2_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: BLOCK type=kotlin.Any? origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp1_elvis_lhs type:T of .test [val] + GET_VAR 'value2: T of .test declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any? 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 tmp1_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Int value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp1_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp2_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x3 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp4_elvis_lhs type:T of .test [val] + BLOCK type=T of .test origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp3_elvis_lhs type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=T of .test 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 tmp3_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: GET_VAR 'value2: T of .test declared in .test' type=T of .test origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp3_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any 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 tmp4_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Int value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp4_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x4 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp6_elvis_lhs type:T of .test [val] + BLOCK type=T of .test origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp5_elvis_lhs type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=T of .test 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 tmp5_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: GET_VAR 'value2: T of .test declared in .test' type=T of .test origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp5_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any 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 tmp6_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Int value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp6_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x5 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp7_elvis_lhs type:kotlin.Any? [val] + CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Any? origin=null + : kotlin.Any? + WHEN type=kotlin.Any 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 tmp7_elvis_lhs: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Int value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp7_elvis_lhs: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null + VAR name:x6 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp9_elvis_lhs type:T of .test [val] + BLOCK type=T of .test origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp8_elvis_lhs type:T of .test [val] + GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + WHEN type=T of .test 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 tmp8_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CALL 'public final fun magic (): T of .magic declared in ' type=T of .test origin=null + : T of .test + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp8_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + WHEN type=kotlin.Any 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 tmp9_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Int value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp9_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + VAR name:x7 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp11_elvis_lhs type:T of .test [val] + BLOCK type=T of .test origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp10_elvis_lhs type:T of .test? [val] + CALL 'public final fun magic (): T of .magic declared in ' type=T of .test? origin=null + : T of .test? + WHEN type=T of .test 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 tmp10_elvis_lhs: T of .test? [val] declared in .test' type=T of .test? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp10_elvis_lhs: T of .test? [val] declared in .test' type=T of .test? origin=null + WHEN type=kotlin.Any 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 tmp11_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Int type=kotlin.Int value=42 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp11_elvis_lhs: T of .test [val] declared in .test' type=T of .test origin=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 30603c5575e..bb64cc92a8a 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1017,6 +1017,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/expressions/kt30020.kt"); } + @TestMetadata("kt30796.kt") + public void testKt30796() throws Exception { + runTest("compiler/testData/ir/irText/expressions/kt30796.kt"); + } + @TestMetadata("lambdaInCAO.kt") public void testLambdaInCAO() throws Exception { runTest("compiler/testData/ir/irText/expressions/lambdaInCAO.kt");