diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index fb94f001664..b8accddf4cf 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.FirSamResolverImpl import org.jetbrains.kotlin.fir.resolve.calls.getExpectedTypeForSAMConversion import org.jetbrains.kotlin.fir.resolve.calls.isFunctional import org.jetbrains.kotlin.fir.resolve.fullyExpandedType +import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType import org.jetbrains.kotlin.fir.resolve.inference.isKMutableProperty import org.jetbrains.kotlin.fir.resolve.toSymbol @@ -38,6 +39,7 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects import org.jetbrains.kotlin.types.AbstractTypeApproximator +import org.jetbrains.kotlin.types.AbstractTypeChecker class CallAndReferenceGenerator( private val components: Fir2IrComponents, @@ -615,6 +617,17 @@ class CallAndReferenceGenerator( } private fun needSamConversion(argument: FirExpression, parameter: FirValueParameter): Boolean { + // If the type of the argument is already an explicitly subtype of the type of the parameter, we don't need SAM conversion. + if (argument.typeRef !is FirResolvedTypeRef || + AbstractTypeChecker.isSubtypeOf( + session.inferenceComponents.ctx, + argument.typeRef.coneType, + parameter.returnTypeRef.coneType, + isFromNullabilityConstraint = true + ) + ) { + return false + } // If the expected type is a built-in functional type, we don't need SAM conversion. val expectedType = argument.getExpectedTypeForSAMConversion(parameter) if (expectedType is ConeTypeParameterType || expectedType.isBuiltinFunctionalType(session)) { diff --git a/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.fir.kt.txt b/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.fir.kt.txt index 2598c69ea47..16b3427c296 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.fir.kt.txt @@ -64,7 +64,7 @@ fun test4(fn: Function1) { fn is IFoo -> { // BLOCK val <>: A = A val <>: IFoo = fn /*as IFoo */ - <>.set(i = <> /*-> IFoo */, newValue = <>.get(i = <> /*-> IFoo */).plus(other = 1)) + <>.set(i = <>, newValue = <>.get(i = <>).plus(other = 1)) } } } @@ -84,7 +84,7 @@ fun test6(a: Any) { { // BLOCK val <>: A = A val <>: Function1 = a /*as Function1 */ - <>.set(i = <> /*-> IFoo */, newValue = <>.get(i = <> /*-> IFoo */).plus(other = 1)) + <>.set(i = <>, newValue = <>.get(i = <>).plus(other = 1)) } } diff --git a/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.fir.txt index b74efa16760..d1943517037 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.fir.txt @@ -141,13 +141,11 @@ FILE fqName: fileName:/caoWithAdaptationForSam.kt GET_VAR 'fn: kotlin.Function1 declared in .test4' type=kotlin.Function1 origin=null CALL 'public final fun set (i: .IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null $receiver: GET_VAR 'val tmp_2: .A [val] declared in .test4' type=.A origin=null - i: TYPE_OP type=.IFoo origin=SAM_CONVERSION typeOperand=.IFoo - GET_VAR 'val tmp_3: .IFoo [val] declared in .test4' type=.IFoo origin=null + i: GET_VAR 'val tmp_3: .IFoo [val] declared in .test4' type=.IFoo origin=null newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: CALL 'public final fun get (i: .IFoo): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null $receiver: GET_VAR 'val tmp_2: .A [val] declared in .test4' type=.A origin=null - i: TYPE_OP type=.IFoo origin=SAM_CONVERSION typeOperand=.IFoo - GET_VAR 'val tmp_3: .IFoo [val] declared in .test4' type=.IFoo origin=null + i: GET_VAR 'val tmp_3: .IFoo [val] declared in .test4' type=.IFoo origin=null other: CONST Int type=kotlin.Int value=1 FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Any @@ -189,11 +187,9 @@ FILE fqName: fileName:/caoWithAdaptationForSam.kt GET_VAR 'a: kotlin.Any declared in .test6' type=kotlin.Any origin=null CALL 'public final fun set (i: .IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null $receiver: GET_VAR 'val tmp_6: .A [val] declared in .test6' type=.A origin=null - i: TYPE_OP type=.IFoo origin=SAM_CONVERSION typeOperand=.IFoo - GET_VAR 'val tmp_7: kotlin.Function1 [val] declared in .test6' type=kotlin.Function1 origin=null + i: GET_VAR 'val tmp_7: kotlin.Function1 [val] declared in .test6' type=kotlin.Function1 origin=null newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: CALL 'public final fun get (i: .IFoo): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null $receiver: GET_VAR 'val tmp_6: .A [val] declared in .test6' type=.A origin=null - i: TYPE_OP type=.IFoo origin=SAM_CONVERSION typeOperand=.IFoo - GET_VAR 'val tmp_7: kotlin.Function1 [val] declared in .test6' type=kotlin.Function1 origin=null + i: GET_VAR 'val tmp_7: kotlin.Function1 [val] declared in .test6' type=kotlin.Function1 origin=null other: CONST Int type=kotlin.Int value=1 diff --git a/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.kt.txt b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.kt.txt index 91c55e89d1e..b769f5e4a61 100644 --- a/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.kt.txt @@ -14,29 +14,29 @@ fun run2(r1: KRunnable, r2: KRunnable) { } fun test0(a: T) where T : KRunnable, T : Function0 { - run1(r = a /*-> KRunnable */) + run1(r = a) } fun test1(a: Function0) { when { - a is KRunnable -> run1(r = a /*as KRunnable */ /*-> KRunnable */) + a is KRunnable -> run1(r = a /*as KRunnable */) } } fun test2(a: KRunnable) { a as Function0 /*~> Unit */ - run1(r = a /*as Function0 */ /*-> KRunnable */) + run1(r = a /*as Function0 */) } fun test3(a: Function0) { when { - a is KRunnable -> run2(r1 = a /*as KRunnable */ /*-> KRunnable */, r2 = a /*as KRunnable */ /*-> KRunnable */) + a is KRunnable -> run2(r1 = a /*as KRunnable */, r2 = a /*as KRunnable */) } } fun test4(a: Function0, b: Function0) { when { - a is KRunnable -> run2(r1 = a /*as KRunnable */ /*-> KRunnable */, r2 = b /*-> KRunnable */) + a is KRunnable -> run2(r1 = a /*as KRunnable */, r2 = b /*-> KRunnable */) } } @@ -50,7 +50,7 @@ fun test5x(a: Any) { when { a is KRunnable -> { // BLOCK a /*as KRunnable */ as Function0 /*~> Unit */ - run1(r = a /*as KRunnable */ /*-> KRunnable */) + run1(r = a /*as KRunnable */) } } } diff --git a/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.txt b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.txt index d89270747af..86e5d5b4cdb 100644 --- a/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.txt +++ b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.txt @@ -34,8 +34,7 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt VALUE_PARAMETER name:a index:0 type:T of .test0 BLOCK_BODY CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null - r: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable - GET_VAR 'a: T of .test0 declared in .test0' type=T of .test0 origin=null + r: GET_VAR 'a: T of .test0 declared in .test0' type=T of .test0 origin=null FUN name:test1 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Function0 BLOCK_BODY @@ -44,9 +43,8 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable GET_VAR 'a: kotlin.Function0 declared in .test1' type=kotlin.Function0 origin=null then: CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null - r: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable - TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable - GET_VAR 'a: kotlin.Function0 declared in .test1' type=kotlin.Function0 origin=null + r: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test1' type=kotlin.Function0 origin=null FUN name:test2 visibility:public modality:FINAL <> (a:.KRunnable) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:.KRunnable BLOCK_BODY @@ -54,9 +52,8 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 GET_VAR 'a: .KRunnable declared in .test2' type=.KRunnable origin=null CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null - r: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable - TYPE_OP type=kotlin.Function0 origin=IMPLICIT_CAST typeOperand=kotlin.Function0 - GET_VAR 'a: .KRunnable declared in .test2' type=.KRunnable origin=null + r: TYPE_OP type=kotlin.Function0 origin=IMPLICIT_CAST typeOperand=kotlin.Function0 + GET_VAR 'a: .KRunnable declared in .test2' type=.KRunnable origin=null FUN name:test3 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Function0 BLOCK_BODY @@ -65,12 +62,10 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null then: CALL 'public final fun run2 (r1: .KRunnable, r2: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null - r1: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable - TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable - GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null - r2: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable - TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable - GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null + r1: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null + r2: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null FUN name:test4 visibility:public modality:FINAL <> (a:kotlin.Function0, b:kotlin.Function0) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Function0 VALUE_PARAMETER name:b index:1 type:kotlin.Function0 @@ -80,9 +75,8 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable GET_VAR 'a: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null then: CALL 'public final fun run2 (r1: .KRunnable, r2: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null - r1: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable - TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable - GET_VAR 'a: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null + r1: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null r2: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable GET_VAR 'b: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit @@ -108,9 +102,8 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null - r: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable - TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable - GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null + r: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null FUN name:test6 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Any BLOCK_BODY diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.kt.txt b/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.kt.txt index 85ebe18232e..8a6af5e2cfa 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.kt.txt @@ -1,24 +1,24 @@ fun test1(a: Function0) { when { - a is Runnable -> runStatic(r = a /*as Runnable */ /*-> Runnable? */) + a is Runnable -> runStatic(r = a /*as Runnable */) } } fun test2(a: Function0) { when { - a is Runnable -> J().run1(r = a /*as Runnable */ /*-> Runnable? */) + a is Runnable -> J().run1(r = a /*as Runnable */) } } fun test3(a: Function0) { when { - a is Runnable -> J().run2(r1 = a /*as Runnable */ /*-> Runnable? */, r2 = a /*as Runnable */ /*-> Runnable? */) + a is Runnable -> J().run2(r1 = a /*as Runnable */, r2 = a /*as Runnable */) } } fun test4(a: Function0, b: Function0) { when { - a is Runnable -> J().run2(r1 = a /*as Runnable */ /*-> Runnable? */, r2 = b /*-> Runnable? */) + a is Runnable -> J().run2(r1 = a /*as Runnable */, r2 = b /*-> Runnable? */) } } @@ -32,7 +32,7 @@ fun test5x(a: Any) { when { a is Runnable -> { // BLOCK a /*as Runnable */ as Function0 /*~> Unit */ - J().run1(r = a /*as Runnable */ /*-> Runnable? */) + J().run1(r = a /*as Runnable */) } } } diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.txt b/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.txt index 5a22093c4e2..720cf65c0da 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.txt @@ -7,9 +7,8 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=java.lang.Runnable GET_VAR 'a: kotlin.Function0 declared in .test1' type=kotlin.Function0 origin=null then: CALL 'public open fun runStatic (r: java.lang.Runnable?): kotlin.Unit declared in .J' type=kotlin.Unit origin=null - r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable? - TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable - GET_VAR 'a: kotlin.Function0 declared in .test1' type=kotlin.Function0 origin=null + r: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable + GET_VAR 'a: kotlin.Function0 declared in .test1' type=kotlin.Function0 origin=null FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Function0 BLOCK_BODY @@ -19,9 +18,8 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt GET_VAR 'a: kotlin.Function0 declared in .test2' type=kotlin.Function0 origin=null then: CALL 'public open fun run1 (r: java.lang.Runnable?): kotlin.Unit declared in .J' type=kotlin.Unit origin=null $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .J' type=.J origin=null - r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable? - TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable - GET_VAR 'a: kotlin.Function0 declared in .test2' type=kotlin.Function0 origin=null + r: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable + GET_VAR 'a: kotlin.Function0 declared in .test2' type=kotlin.Function0 origin=null FUN name:test3 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Function0 BLOCK_BODY @@ -31,12 +29,10 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null then: CALL 'public open fun run2 (r1: java.lang.Runnable?, r2: java.lang.Runnable?): kotlin.Unit declared in .J' type=kotlin.Unit origin=null $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .J' type=.J origin=null - r1: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable? - TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable - GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null - r2: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable? - TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable - GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null + r1: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable + GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null + r2: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable + GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null FUN name:test4 visibility:public modality:FINAL <> (a:kotlin.Function0, b:kotlin.Function0) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Function0 VALUE_PARAMETER name:b index:1 type:kotlin.Function0 @@ -47,9 +43,8 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt GET_VAR 'a: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null then: CALL 'public open fun run2 (r1: java.lang.Runnable?, r2: java.lang.Runnable?): kotlin.Unit declared in .J' type=kotlin.Unit origin=null $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .J' type=.J origin=null - r1: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable? - TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable - GET_VAR 'a: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null + r1: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable + GET_VAR 'a: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null r2: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable? GET_VAR 'b: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit @@ -77,9 +72,8 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null CALL 'public open fun run1 (r: java.lang.Runnable?): kotlin.Unit declared in .J' type=kotlin.Unit origin=null $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .J' type=.J origin=null - r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable? - TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable - GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null + r: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable + GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null FUN name:test6 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Any BLOCK_BODY