diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index bb51c956b4c..7e2ca5a9370 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -34894,6 +34894,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("complexExplicitReceiver.kt") + public void testComplexExplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt"); + } + @Test @TestMetadata("complexImplicitReceiver.kt") public void testComplexImplicitReceiver() throws Exception { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt index 04e7d2b1c84..4c68686a54a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt @@ -280,31 +280,29 @@ class Fir2IrImplicitCastInserter( return implicitCastOrExpression(data as IrExpression, expressionWithSmartcast.typeRef) } - internal fun convertToImplicitCastExpression( - expressionWithSmartcast: FirExpressionWithSmartcast, calleeReference: FirReference + internal fun implicitCastFromDispatchReceiver( + original: IrExpression, + originalTypeRef: FirTypeRef, + calleeReference: FirReference, ): IrExpression { - val originalExpression = expressionWithSmartcast.originalExpression - val value = visitor.convertToIrExpression(originalExpression) - - val typeRef = expressionWithSmartcast.typeRef val referencedDeclaration = ((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirCallableSymbol<*>)?.unwrapCallRepresentative() - ?.fir as FirCallableMemberDeclaration<*> + ?.fir as? FirCallableMemberDeclaration<*> val dispatchReceiverType = - referencedDeclaration.dispatchReceiverType as? ConeClassLikeType - ?: return implicitCastOrExpression(value, typeRef) + referencedDeclaration?.dispatchReceiverType as? ConeClassLikeType + ?: return implicitCastOrExpression(original, originalTypeRef) val starProjectedDispatchReceiver = dispatchReceiverType.replaceArgumentsWithStarProjections() - val castType = typeRef.coneTypeSafe() - castType?.intersectedTypes?.forEach { type -> - if (AbstractTypeChecker.isSubtypeOf(session.typeContext, type, starProjectedDispatchReceiver)) { - return implicitCastOrExpression(value, type) + val castType = originalTypeRef.coneTypeSafe() + castType?.intersectedTypes?.forEach { componentType -> + if (AbstractTypeChecker.isSubtypeOf(session.typeContext, componentType, starProjectedDispatchReceiver)) { + return implicitCastOrExpression(original, componentType) } } - return implicitCastOrExpression(value, typeRef) + return implicitCastOrExpression(original, originalTypeRef) } private fun implicitCastOrExpression(original: IrExpression, castType: ConeKotlinType): IrExpression { 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 5f0f3703d44..8b418059d09 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 @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.resolve.isIteratorNext import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.impl.* @@ -476,10 +477,10 @@ class Fir2IrVisitor( callableReferenceAccess: FirCallableReferenceAccess? = null ): IrExpression? { return when (expression) { - null -> null + null -> return null is FirResolvedQualifier -> callGenerator.convertToGetObject(expression, callableReferenceAccess) - is FirExpressionWithSmartcast -> implicitCastInserter.convertToImplicitCastExpression(expression, calleeReference) - is FirFunctionCall, is FirThisReceiverExpression, is FirCallableReferenceAccess -> convertToIrExpression(expression) + is FirFunctionCall, is FirThisReceiverExpression, is FirCallableReferenceAccess, is FirExpressionWithSmartcast -> + convertToIrExpression(expression) else -> if (expression is FirQualifiedAccessExpression && expression.explicitReceiver == null) { val variableAsFunctionMode = calleeReference is FirResolvedNamedReference && calleeReference.name != OperatorNameConventions.INVOKE && @@ -491,6 +492,10 @@ class Fir2IrVisitor( } else { convertToIrExpression(expression) } + }?.run { + if (expression is FirQualifiedAccessExpression && expression.calleeReference is FirSuperReference) return@run this + + implicitCastInserter.implicitCastFromDispatchReceiver(this, expression.typeRef, calleeReference) } } diff --git a/compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt b/compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt new file mode 100644 index 00000000000..7f0c4b6fb0a --- /dev/null +++ b/compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt @@ -0,0 +1,26 @@ +abstract class A { + abstract fun o(): String +} + +interface B { + fun k(): String +} + +fun id(x: T): T = x + +fun foo(a: A?): String { + if (a is B) { + return id(a).o() + a!!.k() + } + + return "fail" +} + +class Impl : A(), B { + override fun o(): String = "O" + override fun k(): String = "K" +} + +fun box(): String { + return foo(Impl()) +} diff --git a/compiler/testData/ir/irText/expressions/bangbang.fir.kt.txt b/compiler/testData/ir/irText/expressions/bangbang.fir.kt.txt index dd8140cc05f..d217c5919f6 100644 --- a/compiler/testData/ir/irText/expressions/bangbang.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/bangbang.fir.kt.txt @@ -7,7 +7,7 @@ fun test2(a: Any?): Int { val tmp0_safe_receiver: Any? = a when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.hashCode() + else -> tmp0_safe_receiver /*as Any */.hashCode() } }) } diff --git a/compiler/testData/ir/irText/expressions/bangbang.fir.txt b/compiler/testData/ir/irText/expressions/bangbang.fir.txt index cca5d161680..dc9d1daf00b 100644 --- a/compiler/testData/ir/irText/expressions/bangbang.fir.txt +++ b/compiler/testData/ir/irText/expressions/bangbang.fir.txt @@ -24,7 +24,8 @@ FILE fqName: fileName:/bangbang.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun hashCode (): kotlin.Int declared in kotlin.Any' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .test2' type=kotlin.Any? origin=null + $this: TYPE_OP type=kotlin.Any origin=IMPLICIT_CAST typeOperand=kotlin.Any + GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .test2' type=kotlin.Any? origin=null FUN name:test3 visibility:public modality:FINAL (a:X of .test3) returnType:X of .test3 TYPE_PARAMETER name:X index:0 variance: superTypes:[kotlin.Any?] VALUE_PARAMETER name:a index:0 type:X of .test3 diff --git a/compiler/testData/ir/irText/expressions/chainOfSafeCalls.kt.txt b/compiler/testData/ir/irText/expressions/chainOfSafeCalls.kt.txt index 7a94b51e0c0..24b10edc3dd 100644 --- a/compiler/testData/ir/irText/expressions/chainOfSafeCalls.kt.txt +++ b/compiler/testData/ir/irText/expressions/chainOfSafeCalls.kt.txt @@ -23,23 +23,22 @@ fun test(nc: C?): C? { val tmp0_safe_receiver: C? = nc when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.foo() + else -> tmp0_safe_receiver /*as C */.foo() } } when { EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null - else -> tmp1_safe_receiver.bar() + else -> tmp1_safe_receiver /*as C */.bar() } } when { EQEQ(arg0 = tmp2_safe_receiver, arg1 = null) -> null - else -> tmp2_safe_receiver.foo() + else -> tmp2_safe_receiver /*as C */.foo() } } when { EQEQ(arg0 = tmp3_safe_receiver, arg1 = null) -> null - else -> tmp3_safe_receiver.foo() + else -> tmp3_safe_receiver /*as C */.foo() } } } - diff --git a/compiler/testData/ir/irText/expressions/chainOfSafeCalls.txt b/compiler/testData/ir/irText/expressions/chainOfSafeCalls.txt index ed8e621b69d..461a12bf19f 100644 --- a/compiler/testData/ir/irText/expressions/chainOfSafeCalls.txt +++ b/compiler/testData/ir/irText/expressions/chainOfSafeCalls.txt @@ -50,7 +50,8 @@ FILE fqName: fileName:/chainOfSafeCalls.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun foo (): .C declared in .C' type=.C origin=null - $this: GET_VAR 'val tmp_3: .C? [val] declared in .test' type=.C? origin=null + $this: TYPE_OP type=.C origin=IMPLICIT_CAST typeOperand=.C + GET_VAR 'val tmp_3: .C? [val] declared in .test' type=.C? origin=null WHEN type=.C? 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 @@ -60,7 +61,8 @@ FILE fqName: fileName:/chainOfSafeCalls.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun bar (): .C? declared in .C' type=.C? origin=null - $this: GET_VAR 'val tmp_2: .C? [val] declared in .test' type=.C? origin=null + $this: TYPE_OP type=.C origin=IMPLICIT_CAST typeOperand=.C + GET_VAR 'val tmp_2: .C? [val] declared in .test' type=.C? origin=null WHEN type=.C? 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 @@ -70,7 +72,8 @@ FILE fqName: fileName:/chainOfSafeCalls.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun foo (): .C declared in .C' type=.C origin=null - $this: GET_VAR 'val tmp_1: .C? [val] declared in .test' type=.C? origin=null + $this: TYPE_OP type=.C origin=IMPLICIT_CAST typeOperand=.C + GET_VAR 'val tmp_1: .C? [val] declared in .test' type=.C? origin=null WHEN type=.C? 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 @@ -80,4 +83,5 @@ FILE fqName: fileName:/chainOfSafeCalls.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun foo (): .C declared in .C' type=.C origin=null - $this: GET_VAR 'val tmp_0: .C? [val] declared in .test' type=.C? origin=null + $this: TYPE_OP type=.C origin=IMPLICIT_CAST typeOperand=.C + GET_VAR 'val tmp_0: .C? [val] declared in .test' type=.C? origin=null diff --git a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.kt.txt b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.kt.txt index 2d878235e87..4f3d8236800 100644 --- a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.kt.txt @@ -14,14 +14,14 @@ fun test3() { val tmp0_safe_receiver: PrintStream? = #out when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.println(p0 = "Hello,") + else -> tmp0_safe_receiver /*as @FlexibleNullability PrintStream */.println(p0 = "Hello,") } } /*~> Unit */ { // BLOCK val tmp1_safe_receiver: PrintStream? = #out when { EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null - else -> tmp1_safe_receiver.println(p0 = "world!") + else -> tmp1_safe_receiver /*as @FlexibleNullability PrintStream */.println(p0 = "world!") } } /*~> Unit */ } diff --git a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.txt b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.txt index 18e3854f53c..f96009bc4cc 100644 --- a/compiler/testData/ir/irText/expressions/coercionToUnit.fir.txt +++ b/compiler/testData/ir/irText/expressions/coercionToUnit.fir.txt @@ -34,7 +34,8 @@ FILE fqName: fileName:/coercionToUnit.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun println (p0: kotlin.String?): kotlin.Unit declared in java.io.PrintStream' type=kotlin.Unit origin=null - $this: GET_VAR 'val tmp_0: java.io.PrintStream? [val] declared in .test3' type=java.io.PrintStream? origin=null + $this: TYPE_OP type=@[FlexibleNullability] java.io.PrintStream origin=IMPLICIT_CAST typeOperand=@[FlexibleNullability] java.io.PrintStream + GET_VAR 'val tmp_0: java.io.PrintStream? [val] declared in .test3' type=java.io.PrintStream? origin=null p0: CONST String type=kotlin.String value="Hello," TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit BLOCK type=kotlin.Unit? origin=SAFE_CALL @@ -49,5 +50,6 @@ FILE fqName: fileName:/coercionToUnit.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun println (p0: kotlin.String?): kotlin.Unit declared in java.io.PrintStream' type=kotlin.Unit origin=null - $this: GET_VAR 'val tmp_1: java.io.PrintStream? [val] declared in .test3' type=java.io.PrintStream? origin=null + $this: TYPE_OP type=@[FlexibleNullability] java.io.PrintStream origin=IMPLICIT_CAST typeOperand=@[FlexibleNullability] java.io.PrintStream + GET_VAR 'val tmp_1: java.io.PrintStream? [val] declared in .test3' type=java.io.PrintStream? origin=null p0: CONST String type=kotlin.String value="world!" diff --git a/compiler/testData/ir/irText/expressions/dotQualified.kt.txt b/compiler/testData/ir/irText/expressions/dotQualified.kt.txt index e155ea3c2ee..550df1664ee 100644 --- a/compiler/testData/ir/irText/expressions/dotQualified.kt.txt +++ b/compiler/testData/ir/irText/expressions/dotQualified.kt.txt @@ -7,8 +7,7 @@ fun lengthN(s: String?): Int? { val tmp0_safe_receiver: String? = s when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.() + else -> tmp0_safe_receiver /*as String */.() } } } - diff --git a/compiler/testData/ir/irText/expressions/dotQualified.txt b/compiler/testData/ir/irText/expressions/dotQualified.txt index 7d730a47d3b..f33bb88ffcd 100644 --- a/compiler/testData/ir/irText/expressions/dotQualified.txt +++ b/compiler/testData/ir/irText/expressions/dotQualified.txt @@ -21,4 +21,5 @@ FILE fqName: fileName:/dotQualified.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun (): kotlin.Int declared in kotlin.String' type=kotlin.Int origin=GET_PROPERTY - $this: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .lengthN' type=kotlin.String? origin=null + $this: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String + GET_VAR 'val tmp_0: kotlin.String? [val] declared in .lengthN' type=kotlin.String? origin=null diff --git a/compiler/testData/ir/irText/expressions/kt30020.fir.kt.txt b/compiler/testData/ir/irText/expressions/kt30020.fir.kt.txt index fd3b77edb9d..5cfdce35f5a 100644 --- a/compiler/testData/ir/irText/expressions/kt30020.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/kt30020.fir.kt.txt @@ -15,14 +15,14 @@ fun test(x: X, nx: X?) { val tmp0_safe_receiver: X? = nx when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.() + else -> tmp0_safe_receiver /*as X */.() } }).plusAssign(element = 5) CHECK_NOT_NULL>(arg0 = { // BLOCK val tmp1_safe_receiver: X? = nx when { EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null - else -> tmp1_safe_receiver.f() + else -> tmp1_safe_receiver /*as X */.f() } }).plusAssign(element = 6) } diff --git a/compiler/testData/ir/irText/expressions/kt30020.fir.txt b/compiler/testData/ir/irText/expressions/kt30020.fir.txt index 1c57f6ea4a7..e9197fa4366 100644 --- a/compiler/testData/ir/irText/expressions/kt30020.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt30020.fir.txt @@ -62,7 +62,8 @@ FILE fqName: fileName:/kt30020.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public abstract fun (): kotlin.collections.MutableList declared in .X' type=kotlin.collections.MutableList origin=GET_PROPERTY - $this: GET_VAR 'val tmp_0: .X? [val] declared in .test' type=.X? origin=null + $this: TYPE_OP type=.X origin=IMPLICIT_CAST typeOperand=.X + GET_VAR 'val tmp_0: .X? [val] declared in .test' type=.X? origin=null element: CONST Int type=kotlin.Int value=5 CALL 'public final fun plusAssign (element: T of kotlin.collections.CollectionsKt.plusAssign): kotlin.Unit [inline,operator] declared in kotlin.collections.CollectionsKt' type=kotlin.Unit origin=null : kotlin.Int @@ -80,7 +81,8 @@ FILE fqName: fileName:/kt30020.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public abstract fun f (): kotlin.collections.MutableList declared in .X' type=kotlin.collections.MutableList origin=null - $this: GET_VAR 'val tmp_1: .X? [val] declared in .test' type=.X? origin=null + $this: TYPE_OP type=.X origin=IMPLICIT_CAST typeOperand=.X + GET_VAR 'val tmp_1: .X? [val] declared in .test' type=.X? origin=null element: CONST Int type=kotlin.Int value=6 FUN name:testExtensionReceiver visibility:public modality:FINAL <> ($receiver:kotlin.collections.MutableList) returnType:kotlin.Unit $receiver: VALUE_PARAMETER name: type:kotlin.collections.MutableList diff --git a/compiler/testData/ir/irText/expressions/safeAssignment.fir.kt.txt b/compiler/testData/ir/irText/expressions/safeAssignment.fir.kt.txt index a44b20dfee8..58c85e4987b 100644 --- a/compiler/testData/ir/irText/expressions/safeAssignment.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/safeAssignment.fir.kt.txt @@ -17,7 +17,7 @@ fun test(nc: C?) { val tmp0_safe_receiver: C? = nc when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.( = 42) + else -> tmp0_safe_receiver /*as C */.( = 42) } } /*~> Unit */ } diff --git a/compiler/testData/ir/irText/expressions/safeAssignment.fir.txt b/compiler/testData/ir/irText/expressions/safeAssignment.fir.txt index 4491357a6c7..0a8cf9d7346 100644 --- a/compiler/testData/ir/irText/expressions/safeAssignment.fir.txt +++ b/compiler/testData/ir/irText/expressions/safeAssignment.fir.txt @@ -54,5 +54,6 @@ FILE fqName: fileName:/safeAssignment.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .C' type=kotlin.Unit origin=EQ - $this: GET_VAR 'val tmp_0: .C? [val] declared in .test' type=.C? origin=null + $this: TYPE_OP type=.C origin=IMPLICIT_CAST typeOperand=.C + GET_VAR 'val tmp_0: .C? [val] declared in .test' type=.C? origin=null : CONST Int type=kotlin.Int value=42 diff --git a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.kt.txt b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.kt.txt index ea0d8518045..23d15a98d7a 100644 --- a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.kt.txt @@ -21,7 +21,7 @@ operator fun Int?.inc(): Int? { val tmp0_safe_receiver: Int? = when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.inc() + else -> tmp0_safe_receiver /*as Int */.inc() } } } @@ -38,14 +38,14 @@ fun testProperty(nc: C?) { val tmp1_safe_receiver: C? = nc when { EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null - else -> tmp1_safe_receiver.() + else -> tmp1_safe_receiver /*as C */.() } } { // BLOCK val tmp2_safe_receiver: C? = nc when { EQEQ(arg0 = tmp2_safe_receiver, arg1 = null) -> null - else -> tmp2_safe_receiver.(value = .inc()) + else -> tmp2_safe_receiver /*as C */.(value = .inc()) } } /*~> Unit */ /*~> Unit */ @@ -56,7 +56,7 @@ fun testArrayAccess(nc: C?) { val tmp3_safe_receiver: C? = nc when { EQEQ(arg0 = tmp3_safe_receiver, arg1 = null) -> null - else -> tmp3_safe_receiver.() + else -> tmp3_safe_receiver /*as C */.() } } val : Int = 0 diff --git a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt index d7c526ea61c..5f63dcb38aa 100644 --- a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt +++ b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt @@ -46,7 +46,8 @@ FILE fqName:test fileName:/safeCallWithIncrementDecrement.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_0: kotlin.Int? [val] declared in test.inc' type=kotlin.Int? origin=null + $this: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int + GET_VAR 'val tmp_0: kotlin.Int? [val] declared in test.inc' type=kotlin.Int? origin=null FUN name:get visibility:public modality:FINAL <> ($receiver:kotlin.Int?, index:kotlin.Int) returnType:kotlin.Int [operator] $receiver: VALUE_PARAMETER name: type:kotlin.Int? VALUE_PARAMETER name:index index:0 type:kotlin.Int @@ -74,7 +75,8 @@ FILE fqName:test fileName:/safeCallWithIncrementDecrement.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun (): kotlin.Int declared in test' type=kotlin.Int origin=GET_PROPERTY - $receiver: GET_VAR 'val tmp_2: test.C? [val] declared in test.testProperty' type=test.C? origin=null + $receiver: TYPE_OP type=test.C origin=IMPLICIT_CAST typeOperand=test.C + GET_VAR 'val tmp_2: test.C? [val] declared in test.testProperty' type=test.C? origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit BLOCK type=kotlin.Unit? origin=SAFE_CALL VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:test.C? [val] @@ -88,7 +90,8 @@ FILE fqName:test fileName:/safeCallWithIncrementDecrement.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun (value: kotlin.Int): kotlin.Unit declared in test' type=kotlin.Unit origin=EQ - $receiver: GET_VAR 'val tmp_3: test.C? [val] declared in test.testProperty' type=test.C? origin=null + $receiver: TYPE_OP type=test.C origin=IMPLICIT_CAST typeOperand=test.C + GET_VAR 'val tmp_3: test.C? [val] declared in test.testProperty' type=test.C? origin=null value: CALL 'public final fun inc (): kotlin.Int? [operator] declared in test' type=kotlin.Int? origin=null $receiver: GET_VAR 'val tmp_1: kotlin.Int? [val] declared in test.testProperty' type=kotlin.Int? origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit @@ -109,7 +112,8 @@ FILE fqName:test fileName:/safeCallWithIncrementDecrement.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun (): kotlin.Int declared in test' type=kotlin.Int origin=GET_PROPERTY - $receiver: GET_VAR 'val tmp_5: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null + $receiver: TYPE_OP type=test.C origin=IMPLICIT_CAST typeOperand=test.C + GET_VAR 'val tmp_5: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] CONST Int type=kotlin.Int value=0 VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int [val] diff --git a/compiler/testData/ir/irText/expressions/safeCalls.fir.kt.txt b/compiler/testData/ir/irText/expressions/safeCalls.fir.kt.txt index 9805859fa15..8cd5ff12e05 100644 --- a/compiler/testData/ir/irText/expressions/safeCalls.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/safeCalls.fir.kt.txt @@ -24,7 +24,7 @@ fun test1(x: String?): Int? { val tmp0_safe_receiver: String? = x when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.() + else -> tmp0_safe_receiver /*as String */.() } } } @@ -34,7 +34,7 @@ fun test2(x: String?): Int? { val tmp1_safe_receiver: String? = x when { EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null - else -> tmp1_safe_receiver.hashCode() + else -> tmp1_safe_receiver /*as String */.hashCode() } } } @@ -44,7 +44,7 @@ fun test3(x: String?, y: Any?): Boolean? { val tmp2_safe_receiver: String? = x when { EQEQ(arg0 = tmp2_safe_receiver, arg1 = null) -> null - else -> tmp2_safe_receiver.equals(other = y) + else -> tmp2_safe_receiver /*as String */.equals(other = y) } } } @@ -54,7 +54,7 @@ fun test4(x: Ref?) { val tmp3_safe_receiver: Ref? = x when { EQEQ(arg0 = tmp3_safe_receiver, arg1 = null) -> null - else -> tmp3_safe_receiver.( = 0) + else -> tmp3_safe_receiver /*as Ref */.( = 0) } } /*~> Unit */ } @@ -64,7 +64,7 @@ fun IHost.test5(s: String?): Int? { val tmp4_safe_receiver: String? = s when { EQEQ(arg0 = tmp4_safe_receiver, arg1 = null) -> null - else -> (, tmp4_safe_receiver).extLength() + else -> (, tmp4_safe_receiver /*as String */).extLength() } } } diff --git a/compiler/testData/ir/irText/expressions/safeCalls.fir.txt b/compiler/testData/ir/irText/expressions/safeCalls.fir.txt index 89b6504723b..8bdfebd4780 100644 --- a/compiler/testData/ir/irText/expressions/safeCalls.fir.txt +++ b/compiler/testData/ir/irText/expressions/safeCalls.fir.txt @@ -76,7 +76,8 @@ FILE fqName: fileName:/safeCalls.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun (): kotlin.Int declared in kotlin.String' type=kotlin.Int origin=GET_PROPERTY - $this: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .test1' type=kotlin.String? origin=null + $this: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String + GET_VAR 'val tmp_0: kotlin.String? [val] declared in .test1' type=kotlin.String? origin=null FUN name:test2 visibility:public modality:FINAL <> (x:kotlin.String?) returnType:kotlin.Int? VALUE_PARAMETER name:x index:0 type:kotlin.String? BLOCK_BODY @@ -93,7 +94,8 @@ FILE fqName: fileName:/safeCalls.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.String' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .test2' type=kotlin.String? origin=null + $this: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String + GET_VAR 'val tmp_1: kotlin.String? [val] declared in .test2' type=kotlin.String? origin=null FUN name:test3 visibility:public modality:FINAL <> (x:kotlin.String?, y:kotlin.Any?) returnType:kotlin.Boolean? VALUE_PARAMETER name:x index:0 type:kotlin.String? VALUE_PARAMETER name:y index:1 type:kotlin.Any? @@ -111,7 +113,8 @@ FILE fqName: fileName:/safeCalls.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in kotlin.String' type=kotlin.Boolean origin=null - $this: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .test3' type=kotlin.String? origin=null + $this: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String + GET_VAR 'val tmp_2: kotlin.String? [val] declared in .test3' type=kotlin.String? origin=null other: GET_VAR 'y: kotlin.Any? declared in .test3' type=kotlin.Any? origin=null FUN name:test4 visibility:public modality:FINAL <> (x:.Ref?) returnType:kotlin.Unit VALUE_PARAMETER name:x index:0 type:.Ref? @@ -129,7 +132,8 @@ FILE fqName: fileName:/safeCalls.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .Ref' type=kotlin.Unit origin=EQ - $this: GET_VAR 'val tmp_3: .Ref? [val] declared in .test4' type=.Ref? origin=null + $this: TYPE_OP type=.Ref origin=IMPLICIT_CAST typeOperand=.Ref + GET_VAR 'val tmp_3: .Ref? [val] declared in .test4' type=.Ref? origin=null : CONST Int type=kotlin.Int value=0 FUN name:test5 visibility:public modality:FINAL <> ($receiver:.IHost, s:kotlin.String?) returnType:kotlin.Int? $receiver: VALUE_PARAMETER name: type:.IHost @@ -149,7 +153,8 @@ FILE fqName: fileName:/safeCalls.kt if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun extLength (): kotlin.Int declared in .IHost' type=kotlin.Int origin=null $this: GET_VAR ': .IHost declared in .test5' type=.IHost origin=null - $receiver: GET_VAR 'val tmp_4: kotlin.String? [val] declared in .test5' type=kotlin.String? origin=null + $receiver: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String + GET_VAR 'val tmp_4: kotlin.String? [val] declared in .test5' type=kotlin.String? origin=null FUN name:foo visibility:public modality:FINAL <> ($receiver:kotlin.Int) returnType:kotlin.Int $receiver: VALUE_PARAMETER name: type:kotlin.Int BLOCK_BODY diff --git a/compiler/testData/ir/irText/expressions/temporaryInEnumEntryInitializer.fir.kt.txt b/compiler/testData/ir/irText/expressions/temporaryInEnumEntryInitializer.fir.kt.txt index 8019c9ab30b..32933809ff1 100644 --- a/compiler/testData/ir/irText/expressions/temporaryInEnumEntryInitializer.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/temporaryInEnumEntryInitializer.fir.kt.txt @@ -17,7 +17,7 @@ open enum class En : Enum { val tmp0_safe_receiver: Any? = () when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.toString() + else -> tmp0_safe_receiver /*as Any */.toString() } }) diff --git a/compiler/testData/ir/irText/expressions/temporaryInEnumEntryInitializer.fir.txt b/compiler/testData/ir/irText/expressions/temporaryInEnumEntryInitializer.fir.txt index 033ae4b5121..bc50c00adb8 100644 --- a/compiler/testData/ir/irText/expressions/temporaryInEnumEntryInitializer.fir.txt +++ b/compiler/testData/ir/irText/expressions/temporaryInEnumEntryInitializer.fir.txt @@ -42,7 +42,8 @@ FILE fqName: fileName:/temporaryInEnumEntryInitializer.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun toString (): kotlin.String declared in kotlin.Any' type=kotlin.String origin=null - $this: GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .En' type=kotlin.Any? origin=null + $this: TYPE_OP type=kotlin.Any origin=IMPLICIT_CAST typeOperand=kotlin.Any + GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .En' type=kotlin.Any? origin=null FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<.En> SYNTHETIC_BODY kind=ENUM_VALUES FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf visibility:public modality:FINAL <> (value:kotlin.String) returnType:.En diff --git a/compiler/testData/ir/irText/expressions/temporaryInInitBlock.kt.txt b/compiler/testData/ir/irText/expressions/temporaryInInitBlock.kt.txt index 47ad087b450..9d183ecd8b8 100644 --- a/compiler/testData/ir/irText/expressions/temporaryInInitBlock.kt.txt +++ b/compiler/testData/ir/irText/expressions/temporaryInInitBlock.kt.txt @@ -13,10 +13,9 @@ class C { val tmp0_safe_receiver: Any? = x when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.toString() + else -> tmp0_safe_receiver /*as Any */.toString() } } } } - diff --git a/compiler/testData/ir/irText/expressions/temporaryInInitBlock.txt b/compiler/testData/ir/irText/expressions/temporaryInInitBlock.txt index 842752aa6d2..10826774f71 100644 --- a/compiler/testData/ir/irText/expressions/temporaryInInitBlock.txt +++ b/compiler/testData/ir/irText/expressions/temporaryInInitBlock.txt @@ -31,7 +31,8 @@ FILE fqName: fileName:/temporaryInInitBlock.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun toString (): kotlin.String declared in kotlin.Any' type=kotlin.String origin=null - $this: GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .C' type=kotlin.Any? origin=null + $this: TYPE_OP type=kotlin.Any origin=IMPLICIT_CAST typeOperand=kotlin.Any + GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .C' type=kotlin.Any? origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/expressions/variableAsFunctionCall.fir.kt.txt b/compiler/testData/ir/irText/expressions/variableAsFunctionCall.fir.kt.txt index d26d3800122..6986fd4fc10 100644 --- a/compiler/testData/ir/irText/expressions/variableAsFunctionCall.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/variableAsFunctionCall.fir.kt.txt @@ -23,12 +23,12 @@ fun test4(ns: String?): String? { val tmp0_safe_receiver: String? = ns when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.k() + else -> tmp0_safe_receiver /*as String */.k() } } when { EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null - else -> tmp1_safe_receiver.invoke() + else -> tmp1_safe_receiver /*as Function0 */.invoke() } } } diff --git a/compiler/testData/ir/irText/expressions/variableAsFunctionCall.fir.txt b/compiler/testData/ir/irText/expressions/variableAsFunctionCall.fir.txt index 7ba641b6e3a..2fda803593a 100644 --- a/compiler/testData/ir/irText/expressions/variableAsFunctionCall.fir.txt +++ b/compiler/testData/ir/irText/expressions/variableAsFunctionCall.fir.txt @@ -45,7 +45,8 @@ FILE fqName: fileName:/variableAsFunctionCall.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun k (): kotlin.Function0 declared in ' type=kotlin.Function0 origin=null - $receiver: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .test4' type=kotlin.String? origin=null + $receiver: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String + GET_VAR 'val tmp_1: kotlin.String? [val] declared in .test4' type=kotlin.String? origin=null WHEN type=kotlin.String? 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 @@ -55,4 +56,5 @@ FILE fqName: fileName:/variableAsFunctionCall.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.String origin=INVOKE - $this: GET_VAR 'val tmp_0: kotlin.Function0? [val] declared in .test4' type=kotlin.Function0? origin=null + $this: TYPE_OP type=kotlin.Function0 origin=IMPLICIT_CAST typeOperand=kotlin.Function0 + GET_VAR 'val tmp_0: kotlin.Function0? [val] declared in .test4' type=kotlin.Function0? origin=null diff --git a/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.kt.txt b/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.kt.txt index 31d5a81df78..a6275eb4f88 100644 --- a/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.kt.txt +++ b/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.kt.txt @@ -79,7 +79,7 @@ fun box(): String { val tmp0_safe_receiver: ImplicitReceiverValue<*>? = stack.get(name = null) when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.() + else -> tmp0_safe_receiver /*as ImplicitReceiverValue<*> */.() } }) } diff --git a/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.txt b/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.txt index 06ec0dfc0fe..6dd76dc95a5 100644 --- a/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.txt +++ b/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.txt @@ -249,4 +249,5 @@ FILE fqName: fileName:/ImplicitReceiverStack.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun (): kotlin.String declared in .ImplicitReceiverValue' type=kotlin.String origin=GET_PROPERTY - $this: GET_VAR 'val tmp_0: .ImplicitReceiverValue<*>? [val] declared in .box' type=.ImplicitReceiverValue<*>? origin=null + $this: TYPE_OP type=.ImplicitReceiverValue<*> origin=IMPLICIT_CAST typeOperand=.ImplicitReceiverValue<*> + GET_VAR 'val tmp_0: .ImplicitReceiverValue<*>? [val] declared in .box' type=.ImplicitReceiverValue<*>? origin=null diff --git a/compiler/testData/ir/irText/firProblems/JCTree.fir.kt.txt b/compiler/testData/ir/irText/firProblems/JCTree.fir.kt.txt index 4d37bdfb27f..f62bcb560c9 100644 --- a/compiler/testData/ir/irText/firProblems/JCTree.fir.kt.txt +++ b/compiler/testData/ir/irText/firProblems/JCTree.fir.kt.txt @@ -13,7 +13,7 @@ class Owner { get(): String { var tree: JCTree = .() when { - tree /*as T */ is JCTypeApply -> return tree /*as JCTypeApply */.#clazz /*!! String */ + tree /*as T */ is JCTypeApply -> return tree /*as T */ /*as JCTypeApply */.#clazz /*!! String */ } return "" } diff --git a/compiler/testData/ir/irText/firProblems/JCTree.fir.txt b/compiler/testData/ir/irText/firProblems/JCTree.fir.txt index be83543c676..1c25e130956 100644 --- a/compiler/testData/ir/irText/firProblems/JCTree.fir.txt +++ b/compiler/testData/ir/irText/firProblems/JCTree.fir.txt @@ -35,7 +35,8 @@ FILE fqName: fileName:/JCTreeUser.kt TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:clazz type:kotlin.String? visibility:public' type=kotlin.String? origin=GET_PROPERTY receiver: TYPE_OP type=.JCTree.JCTypeApply origin=IMPLICIT_CAST typeOperand=.JCTree.JCTypeApply - GET_VAR 'var tree: .JCTree [var] declared in .Owner.' type=.JCTree origin=null + TYPE_OP type=T of .Owner origin=IMPLICIT_CAST typeOperand=T of .Owner + GET_VAR 'var tree: .JCTree [var] declared in .Owner.' type=.JCTree origin=null RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .Owner' CONST String type=kotlin.String value="" FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] diff --git a/compiler/testData/ir/irText/firProblems/coercionToUnitForNestedWhen.fir.kt.txt b/compiler/testData/ir/irText/firProblems/coercionToUnitForNestedWhen.fir.kt.txt index 4cf9c1fb9dc..c5165983793 100644 --- a/compiler/testData/ir/irText/firProblems/coercionToUnitForNestedWhen.fir.kt.txt +++ b/compiler/testData/ir/irText/firProblems/coercionToUnitForNestedWhen.fir.kt.txt @@ -10,7 +10,7 @@ private fun Reader.nextChar(): Char? { ) when { EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver.toChar() + else -> tmp0_safe_receiver /*as Int */.toChar() } } } @@ -26,7 +26,7 @@ fun Reader.consumeRestOfQuotedSequence(sb: StringBuilder, quote: Char) { val tmp1_safe_receiver: Char? = .nextChar() when { EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null - else -> tmp1_safe_receiver.let(block = local fun (it: Char): StringBuilder? { + else -> tmp1_safe_receiver /*as Char */.let(block = local fun (it: Char): StringBuilder? { return sb.append(p0 = it) } ) diff --git a/compiler/testData/ir/irText/firProblems/coercionToUnitForNestedWhen.fir.txt b/compiler/testData/ir/irText/firProblems/coercionToUnitForNestedWhen.fir.txt index 24624e3721b..197ac7adb75 100644 --- a/compiler/testData/ir/irText/firProblems/coercionToUnitForNestedWhen.fir.txt +++ b/compiler/testData/ir/irText/firProblems/coercionToUnitForNestedWhen.fir.txt @@ -35,7 +35,8 @@ FILE fqName: fileName:/coercionToUnitForNestedWhen.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public open fun toChar (): kotlin.Char declared in kotlin.Int' type=kotlin.Char origin=null - $this: GET_VAR 'val tmp_0: kotlin.Int? [val] declared in .nextChar' type=kotlin.Int? origin=null + $this: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int + GET_VAR 'val tmp_0: kotlin.Int? [val] declared in .nextChar' type=kotlin.Int? origin=null FUN name:consumeRestOfQuotedSequence visibility:public modality:FINAL <> ($receiver:java.io.Reader, sb:java.lang.StringBuilder, quote:kotlin.Char) returnType:kotlin.Unit $receiver: VALUE_PARAMETER name: type:java.io.Reader VALUE_PARAMETER name:sb index:0 type:java.lang.StringBuilder @@ -82,7 +83,8 @@ FILE fqName: fileName:/coercionToUnitForNestedWhen.kt then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=java.lang.StringBuilder? origin=null : kotlin.Char : java.lang.StringBuilder? - $receiver: GET_VAR 'val tmp_1: kotlin.Char? [val] declared in .consumeRestOfQuotedSequence' type=kotlin.Char? origin=null + $receiver: TYPE_OP type=kotlin.Char origin=IMPLICIT_CAST typeOperand=kotlin.Char + GET_VAR 'val tmp_1: kotlin.Char? [val] declared in .consumeRestOfQuotedSequence' type=kotlin.Char? origin=null block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Char) returnType:java.lang.StringBuilder? VALUE_PARAMETER name:it index:0 type:kotlin.Char diff --git a/compiler/testData/ir/irText/types/genericDelegatedDeepProperty.fir.kt.txt b/compiler/testData/ir/irText/types/genericDelegatedDeepProperty.fir.kt.txt index f7ebf840dfd..44b470be1c1 100644 --- a/compiler/testData/ir/irText/types/genericDelegatedDeepProperty.fir.kt.txt +++ b/compiler/testData/ir/irText/types/genericDelegatedDeepProperty.fir.kt.txt @@ -108,7 +108,7 @@ val Value>.additionalText: P /* by */ () } get(): T { - return .#deepO$delegate.getValue(t = , p = ::deepO) + return /*as */.#deepO$delegate.getValue(t = , p = ::deepO) } private val Value>.deepK: T /* by */ @@ -129,7 +129,7 @@ val Value>.additionalText: P /* by */ () } get(): T { - return .#deepK$delegate.getValue(t = , p = ::deepK) + return /*as */.#deepK$delegate.getValue(t = , p = ::deepK) } override operator fun getValue(t: Value>, p: KProperty<*>): P { diff --git a/compiler/testData/ir/irText/types/genericDelegatedDeepProperty.fir.txt b/compiler/testData/ir/irText/types/genericDelegatedDeepProperty.fir.txt index 3afe437a671..3e3d08e97bc 100644 --- a/compiler/testData/ir/irText/types/genericDelegatedDeepProperty.fir.txt +++ b/compiler/testData/ir/irText/types/genericDelegatedDeepProperty.fir.txt @@ -279,7 +279,8 @@ FILE fqName: fileName:/genericDelegatedDeepProperty.kt RETURN type=kotlin.Nothing from='public final fun (): T of . declared in .additionalText$delegate.' CALL 'public final fun getValue (t: .Value., .CR.>>, p: kotlin.reflect.KProperty<*>): T of . [operator] declared in .additionalText$delegate..deepO$delegate.' type=T of . origin=null $this: GET_FIELD 'FIELD PROPERTY_DELEGATE name:deepO$delegate type:.additionalText$delegate..deepO$delegate..> visibility:private [final]' type=.additionalText$delegate..deepO$delegate..> origin=null - receiver: GET_VAR ': .additionalText$delegate..> declared in .additionalText$delegate..' type=.additionalText$delegate..> origin=null + receiver: TYPE_OP type=.additionalText$delegate. origin=IMPLICIT_CAST typeOperand=.additionalText$delegate. + GET_VAR ': .additionalText$delegate..> declared in .additionalText$delegate..' type=.additionalText$delegate..> origin=null t: GET_VAR ': .additionalText$delegate..> declared in .additionalText$delegate..' type=.additionalText$delegate..> origin=null p: PROPERTY_REFERENCE 'private final deepO: T of . [delegated,val]' field=null getter='public final fun (): T of . declared in .additionalText$delegate.' setter=null type=kotlin.reflect.KProperty2<.Value., .CR.>>, *, T of .> origin=PROPERTY_REFERENCE_FOR_DELEGATE PROPERTY name:deepK visibility:private modality:FINAL [delegated,val] @@ -325,7 +326,8 @@ FILE fqName: fileName:/genericDelegatedDeepProperty.kt RETURN type=kotlin.Nothing from='public final fun (): T of . declared in .additionalText$delegate.' CALL 'public final fun getValue (t: .Value., .CR.>>, p: kotlin.reflect.KProperty<*>): T of . [operator] declared in .additionalText$delegate..deepK$delegate.' type=T of . origin=null $this: GET_FIELD 'FIELD PROPERTY_DELEGATE name:deepK$delegate type:.additionalText$delegate..deepK$delegate..> visibility:private [final]' type=.additionalText$delegate..deepK$delegate..> origin=null - receiver: GET_VAR ': .additionalText$delegate..> declared in .additionalText$delegate..' type=.additionalText$delegate..> origin=null + receiver: TYPE_OP type=.additionalText$delegate. origin=IMPLICIT_CAST typeOperand=.additionalText$delegate. + GET_VAR ': .additionalText$delegate..> declared in .additionalText$delegate..' type=.additionalText$delegate..> origin=null t: GET_VAR ': .additionalText$delegate..> declared in .additionalText$delegate..' type=.additionalText$delegate..> origin=null p: PROPERTY_REFERENCE 'private final deepK: T of . [delegated,val]' field=null getter='public final fun (): T of . declared in .additionalText$delegate.' setter=null type=kotlin.reflect.KProperty2<.Value., .CR.>>, *, T of .> origin=PROPERTY_REFERENCE_FOR_DELEGATE FUN name:getValue visibility:public modality:FINAL <> ($this:.additionalText$delegate..>, t:.Value., .CR.>>, p:kotlin.reflect.KProperty<*>) returnType:.P., T of .> [operator] diff --git a/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.kt.txt b/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.kt.txt index 4a847278e99..22e24614d4c 100644 --- a/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.kt.txt +++ b/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.kt.txt @@ -17,7 +17,7 @@ var C.y: T return .() } set(v: T) { - .( = v) + /*as C */.( = v) } fun use(p: KMutableProperty) { diff --git a/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.txt b/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.txt index 7471e9924c6..1fbcb8c17b5 100644 --- a/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.txt +++ b/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.txt @@ -55,7 +55,8 @@ FILE fqName: fileName:/genericPropertyReferenceType.kt VALUE_PARAMETER name:v index:0 type:T of . BLOCK_BODY CALL 'public final fun (: T of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=EQ - $this: GET_VAR ': .C.> declared in .' type=.C.> origin=null + $this: TYPE_OP type=.C.> origin=IMPLICIT_CAST typeOperand=.C.> + GET_VAR ': .C.> declared in .' type=.C.> origin=null : GET_VAR 'v: T of . declared in .' type=T of . origin=null FUN name:use visibility:public modality:FINAL <> (p:kotlin.reflect.KMutableProperty) returnType:kotlin.Unit VALUE_PARAMETER name:p index:0 type:kotlin.reflect.KMutableProperty diff --git a/compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.fir.kt.txt b/compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.fir.kt.txt index b1cd9cd8e15..5adf3761bd6 100644 --- a/compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.fir.kt.txt +++ b/compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.fir.kt.txt @@ -25,8 +25,8 @@ interface IB { fun test(a: In, b: In, z: Z) { z.create(x = a, y = b).().foo() - z.create(x = a, y = b).().bar() + z.create(x = a, y = b).() /*as IB */.bar() val t: IA = z.create(x = a, y = b).() t.foo() - t.bar() + t /*as IB */.bar() } diff --git a/compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.fir.txt b/compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.fir.txt index c46e69a5cbb..b49be83326c 100644 --- a/compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.fir.txt +++ b/compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.fir.txt @@ -102,12 +102,13 @@ FILE fqName: fileName:/localVariableOfIntersectionType_NI.kt x: GET_VAR 'a: .In<.IA> declared in .test' type=.In<.IA> origin=null y: GET_VAR 'b: .In<.IB> declared in .test' type=.In<.IB> origin=null CALL 'public abstract fun bar (): kotlin.Unit declared in .IB' type=kotlin.Unit origin=null - $this: CALL 'public abstract fun (): T of .Inv declared in .Inv' type=.IA origin=GET_PROPERTY - $this: CALL 'public abstract fun create (x: .In.Z.create>, y: .In.Z.create>): .Inv.Z.create> declared in .Z' type=.Inv<.IA> origin=null - : .IA - $this: GET_VAR 'z: .Z declared in .test' type=.Z origin=null - x: GET_VAR 'a: .In<.IA> declared in .test' type=.In<.IA> origin=null - y: GET_VAR 'b: .In<.IB> declared in .test' type=.In<.IB> origin=null + $this: TYPE_OP type=.IB origin=IMPLICIT_CAST typeOperand=.IB + CALL 'public abstract fun (): T of .Inv declared in .Inv' type=.IA origin=GET_PROPERTY + $this: CALL 'public abstract fun create (x: .In.Z.create>, y: .In.Z.create>): .Inv.Z.create> declared in .Z' type=.Inv<.IA> origin=null + : .IA + $this: GET_VAR 'z: .Z declared in .test' type=.Z origin=null + x: GET_VAR 'a: .In<.IA> declared in .test' type=.In<.IA> origin=null + y: GET_VAR 'b: .In<.IB> declared in .test' type=.In<.IB> origin=null VAR name:t type:.IA [val] CALL 'public abstract fun (): T of .Inv declared in .Inv' type=.IA origin=GET_PROPERTY $this: CALL 'public abstract fun create (x: .In.Z.create>, y: .In.Z.create>): .Inv.Z.create> declared in .Z' type=.Inv<.IA> origin=null @@ -118,4 +119,5 @@ FILE fqName: fileName:/localVariableOfIntersectionType_NI.kt CALL 'public abstract fun foo (): kotlin.Unit declared in .IA' type=kotlin.Unit origin=null $this: GET_VAR 'val t: .IA [val] declared in .test' type=.IA origin=null CALL 'public abstract fun bar (): kotlin.Unit declared in .IB' type=kotlin.Unit origin=null - $this: GET_VAR 'val t: .IA [val] declared in .test' type=.IA origin=null + $this: TYPE_OP type=.IB origin=IMPLICIT_CAST typeOperand=.IB + GET_VAR 'val t: .IA [val] declared in .test' type=.IA origin=null diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 50d4043833c..ffb1a202405 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -35094,6 +35094,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @Test + @TestMetadata("complexExplicitReceiver.kt") + public void testComplexExplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt"); + } + @Test @TestMetadata("complexImplicitReceiver.kt") public void testComplexImplicitReceiver() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index b49c31ba0e2..b3d0bb8aa11 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -34894,6 +34894,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("complexExplicitReceiver.kt") + public void testComplexExplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt"); + } + @Test @TestMetadata("complexImplicitReceiver.kt") public void testComplexImplicitReceiver() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 471512c6f8d..25047ce0e46 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -28666,6 +28666,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @TestMetadata("complexExplicitReceiver.kt") + public void testComplexExplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt"); + } + @TestMetadata("complexImplicitReceiver.kt") public void testComplexImplicitReceiver() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 142c74c6815..ae6239cde17 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -24792,6 +24792,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } + @TestMetadata("complexExplicitReceiver.kt") + public void testComplexExplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt"); + } + @TestMetadata("complexImplicitReceiver.kt") public void testComplexImplicitReceiver() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 71a0780d19b..b398829a8ee 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -24792,6 +24792,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + @TestMetadata("complexExplicitReceiver.kt") + public void testComplexExplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt"); + } + @TestMetadata("complexImplicitReceiver.kt") public void testComplexImplicitReceiver() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index b804a2cbcc4..3c9ac4b9149 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -24757,6 +24757,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } + @TestMetadata("complexExplicitReceiver.kt") + public void testComplexExplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt"); + } + @TestMetadata("complexImplicitReceiver.kt") public void testComplexImplicitReceiver() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index e991db16c9f..8862d4fd405 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -13261,6 +13261,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); } + @TestMetadata("complexExplicitReceiver.kt") + public void testComplexExplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexExplicitReceiver.kt"); + } + @TestMetadata("complexImplicitReceiver.kt") public void testComplexImplicitReceiver() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt");