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 27fb76fee5e..d450a6b19ee 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 @@ -587,8 +587,7 @@ class Fir2IrVisitor( fun irGetLhsValue(): IrGetValue = IrGetValueImpl(startOffset, endOffset, irLhsVariable.type, irLhsVariable.symbol) - // TODO: replace with .coneType - val originalType = firLhsVariable.returnTypeRef.coneTypeUnsafe() + val originalType = firLhsVariable.returnTypeRef.coneType val notNullType = originalType.withNullability(ConeNullability.NOT_NULL) val irBranches = listOf( IrBranchImpl( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index 166ab8f9f74..3618d271e6c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -216,9 +216,12 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran ): CompositeTransformResult { if (elvisExpression.calleeReference is FirResolvedNamedReference) return elvisExpression.compose() elvisExpression.transformAnnotations(transformer, data) - elvisExpression.transformLhs(transformer, ResolutionMode.ContextDependent) + val expectedArgumentType = + if (data is ResolutionMode.WithExpectedType && data.expectedType !is FirImplicitTypeRef) data + else ResolutionMode.ContextDependent + elvisExpression.transformLhs(transformer, expectedArgumentType) dataFlowAnalyzer.exitElvisLhs(elvisExpression) - elvisExpression.transformRhs(transformer, ResolutionMode.ContextDependent) + elvisExpression.transformRhs(transformer, expectedArgumentType) val result = syntheticCallGenerator.generateCalleeForElvisExpression(elvisExpression, resolutionContext)?.let { callCompleter.completeCall(it, data.expectedType).result diff --git a/compiler/testData/codegen/box/elvis/kt6694ExactAnnotationForElvis.kt b/compiler/testData/codegen/box/elvis/kt6694ExactAnnotationForElvis.kt index 5143289515e..af26c6e87f2 100644 --- a/compiler/testData/codegen/box/elvis/kt6694ExactAnnotationForElvis.kt +++ b/compiler/testData/codegen/box/elvis/kt6694ExactAnnotationForElvis.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR - interface PsiElement { fun findChildByType(i: Int): T? = if (i == 42) JetOperationReferenceExpression() as T else throw Exception() diff --git a/compiler/testData/ir/irText/expressions/kt30796.fir.kt.txt b/compiler/testData/ir/irText/expressions/kt30796.fir.kt.txt index 92347743b7d..78adb7af6f6 100644 --- a/compiler/testData/ir/irText/expressions/kt30796.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/kt30796.fir.kt.txt @@ -50,17 +50,17 @@ fun test(value: T, value2: T) { } } val x5: Any = { // BLOCK - val : Int? = magic() + val : Any = magic() when { EQEQ(arg0 = , arg1 = null) -> 42 - else -> /*as Int */ + else -> } } val x6: Any = { // BLOCK - val : T = { // BLOCK + val : Any = { // BLOCK val : T = value when { - EQEQ(arg0 = , arg1 = null) -> magic() + EQEQ(arg0 = , arg1 = null) -> magic() else -> } } @@ -70,11 +70,11 @@ fun test(value: T, value2: T) { } } val x7: Any = { // BLOCK - val : T = { // BLOCK - val : T? = magic() + val : Any = { // BLOCK + val : Any = magic() when { EQEQ(arg0 = , arg1 = null) -> value - else -> /*as T */ + else -> } } when { diff --git a/compiler/testData/ir/irText/expressions/kt30796.fir.txt b/compiler/testData/ir/irText/expressions/kt30796.fir.txt index 344efa7f284..3e33c57eb70 100644 --- a/compiler/testData/ir/irText/expressions/kt30796.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt30796.fir.txt @@ -96,68 +96,66 @@ FILE fqName: fileName:/kt30796.kt if: CONST Boolean type=kotlin.Boolean value=true then: GET_VAR 'val tmp_5: T of .test [val] declared in .test' type=T of .test origin=null VAR name:x5 type:kotlin.Any [val] - BLOCK type=kotlin.Int origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int? [val] - CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Int? origin=null - : kotlin.Int? - WHEN type=kotlin.Int origin=ELVIS + BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_7 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=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 tmp_7: kotlin.Int? [val] declared in .test' type=kotlin.Int? origin=null + arg0: GET_VAR 'val tmp_7: 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: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int - GET_VAR 'val tmp_7: kotlin.Int? [val] declared in .test' type=kotlin.Int? origin=null + then: GET_VAR 'val tmp_7: 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:tmp_8 type:T of .test [val] - BLOCK type=T of .test origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS VAR IR_TEMPORARY_VARIABLE name:tmp_9 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 + 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 tmp_9: 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 + then: CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Any origin=null + : kotlin.Any BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: GET_VAR 'val tmp_9: 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 tmp_8: T of .test [val] declared in .test' type=T of .test origin=null + arg0: GET_VAR 'val tmp_8: 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 tmp_8: T of .test [val] declared in .test' type=T of .test origin=null + then: GET_VAR 'val tmp_8: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null VAR name:x7 type:kotlin.Any [val] BLOCK type=kotlin.Any origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:T of .test [val] - BLOCK type=T of .test origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_11 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=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.Any [val] + BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_11 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=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 tmp_11: T of .test? [val] declared in .test' type=T of .test? origin=null + arg0: GET_VAR 'val tmp_11: kotlin.Any [val] declared in .test' type=kotlin.Any 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: TYPE_OP type=T of .test origin=IMPLICIT_CAST typeOperand=T of .test - GET_VAR 'val tmp_11: T of .test? [val] declared in .test' type=T of .test? origin=null + then: GET_VAR 'val tmp_11: kotlin.Any [val] declared in .test' type=kotlin.Any 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 tmp_10: T of .test [val] declared in .test' type=T of .test origin=null + arg0: GET_VAR 'val tmp_10: 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 tmp_10: T of .test [val] declared in .test' type=T of .test origin=null + then: GET_VAR 'val tmp_10: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null