psi2ir: Fix KT-30796 ErrorType for '?:' in OI

This commit is contained in:
Dmitry Petrov
2019-07-19 13:33:20 +03:00
parent 959b720e3f
commit 127be9be03
6 changed files with 367 additions and 2 deletions
@@ -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");
@@ -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()
+161
View File
@@ -0,0 +1,161 @@
FILE fqName:<root> fileName:/kt30796.kt
FUN name:magic visibility:public modality:FINAL <T> () returnType:T of <root>.magic
TYPE_PARAMETER name:T index:0 variance: superTypes:[]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun magic <T> (): T of <root>.magic declared in <root>'
THROW type=kotlin.Nothing
ERROR_CALL 'Unresolved reference: <Ambiguity: Exception, [java/lang/Exception.Exception, java/lang/Exception.Exception]>#' type=IrErrorType
FUN name:test visibility:public modality:FINAL <T> (value:T of <root>.test, value2:T of <root>.test) returnType:kotlin.Unit
TYPE_PARAMETER name:T index:0 variance: superTypes:[]
VALUE_PARAMETER name:value index:0 type:T of <root>.test
VALUE_PARAMETER name:value2 index:1 type:T of <root>.test
BLOCK_BODY
VAR name:x1 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x2 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: BLOCK type=kotlin.Any origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x3 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x4 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x5 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS
VAR name:<elvis> type:kotlin.Nothing [val]
CALL 'public final fun magic <T> (): T of <root>.magic declared in <root>' type=kotlin.Nothing origin=null
<T>: <none>
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 <elvis>: kotlin.Nothing [val] declared in <root>.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 <elvis>: kotlin.Nothing [val] declared in <root>.test' type=kotlin.Nothing origin=null
VAR name:x6 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: CALL 'public final fun magic <T> (): T of <root>.magic declared in <root>' type=kotlin.Nothing origin=null
<T>: <none>
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x7 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS
VAR name:<elvis> type:T of <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS
VAR name:<elvis> type:kotlin.Nothing [val]
CALL 'public final fun magic <T> (): T of <root>.magic declared in <root>' type=kotlin.Nothing origin=null
<T>: <none>
WHEN type=T of <root>.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 <elvis>: kotlin.Nothing [val] declared in <root>.test' type=kotlin.Nothing origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val <elvis>: kotlin.Nothing [val] declared in <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <elvis>: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
+11
View File
@@ -0,0 +1,11 @@
fun <T> magic(): T = throw Exception()
fun <T> 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
}
+160
View File
@@ -0,0 +1,160 @@
FILE fqName:<root> fileName:/kt30796.kt
FUN name:magic visibility:public modality:FINAL <T> () returnType:T of <root>.magic
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
BLOCK_BODY
THROW type=kotlin.Nothing
CONSTRUCTOR_CALL 'public constructor <init> () declared in java.lang.Exception' type=java.lang.Exception origin=null
FUN name:test visibility:public modality:FINAL <T> (value:T of <root>.test, value2:T of <root>.test) returnType:kotlin.Unit
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
VALUE_PARAMETER name:value index:0 type:T of <root>.test
VALUE_PARAMETER name:value2 index:1 type:T of <root>.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 <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val]
GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp2_elvis_lhs: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp3_elvis_lhs type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp3_elvis_lhs: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp5_elvis_lhs type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp5_elvis_lhs: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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> (): T of <root>.magic declared in <root>' type=kotlin.Any? origin=null
<T>: 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 <root>.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 <root>.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 <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp8_elvis_lhs type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: CALL 'public final fun magic <T> (): T of <root>.magic declared in <root>' type=T of <root>.test origin=null
<T>: T of <root>.test
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp8_elvis_lhs: T of <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp10_elvis_lhs type:T of <root>.test? [val]
CALL 'public final fun magic <T> (): T of <root>.magic declared in <root>' type=T of <root>.test? origin=null
<T>: T of <root>.test?
WHEN type=T of <root>.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 <root>.test? [val] declared in <root>.test' type=T of <root>.test? origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp10_elvis_lhs: T of <root>.test? [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.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 <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
@@ -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");