From 58af8d68a13302801627fa554d72cafacf5e4e43 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 6 Jul 2020 16:48:15 +0300 Subject: [PATCH] [FIR] Check for isFun flag in SAM resolution --- .../resolve/samConstructors/kotlinSam.kt | 3 +- .../resolve/samConversions/kotlinSam.kt | 11 +- .../callableReferences/sam.kt | 2 +- .../inference/plusAssignWithLambdaInRhs.dot | 195 +++++++++++------- .../inference/plusAssignWithLambdaInRhs.kt | 6 +- .../inference/plusAssignWithLambdaInRhs.txt | 27 ++- .../kotlin/fir/resolve/SamResolution.kt | 1 + .../testData/codegen/box/coroutines/await.kt | 1 - .../funIsNotInheritedFromBaseInterface.fir.kt | 2 +- .../samAdapters/Simple.fir.kt | 2 +- .../castsInsideCoroutineInference.fir.txt | 94 ++++----- 11 files changed, 203 insertions(+), 141 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/resolve/samConstructors/kotlinSam.kt b/compiler/fir/analysis-tests/testData/resolve/samConstructors/kotlinSam.kt index 19adf795633..015c66bfa1b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/samConstructors/kotlinSam.kt +++ b/compiler/fir/analysis-tests/testData/resolve/samConstructors/kotlinSam.kt @@ -1,5 +1,4 @@ -// TODO: This interface must be marked as "fun" ones that modifier is supported -interface MyRunnable { +fun interface MyRunnable { fun foo(x: Int): Boolean } diff --git a/compiler/fir/analysis-tests/testData/resolve/samConversions/kotlinSam.kt b/compiler/fir/analysis-tests/testData/resolve/samConversions/kotlinSam.kt index 9a970c71325..5fb027ccb83 100644 --- a/compiler/fir/analysis-tests/testData/resolve/samConversions/kotlinSam.kt +++ b/compiler/fir/analysis-tests/testData/resolve/samConversions/kotlinSam.kt @@ -1,21 +1,20 @@ -// TODO: These interfaces must be marked as "fun" ones that modifier is supported -interface MyRunnable { +fun interface MyRunnable { fun foo(x: Int): Boolean } -interface WithProperty { +fun interface WithProperty { val x: Int } -interface TwoAbstract : MyRunnable { +fun interface TwoAbstract : MyRunnable { fun bar() } -interface Super { +fun interface Super { fun foo(x: Int): Any } -interface Derived : Super { +fun interface Derived : Super { override fun foo(x: Int): Boolean } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/callableReferences/sam.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/callableReferences/sam.kt index 64ee64950f2..cd8dd27cdb1 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/callableReferences/sam.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/callableReferences/sam.kt @@ -1,4 +1,4 @@ -interface MySam { +fun interface MySam { fun run(x: String): Int } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot index 5ba45d4c9d6..8a4bbd79dbb 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot @@ -5,103 +5,156 @@ digraph plusAssignWithLambdaInRhs_kt { subgraph cluster_0 { color=red - 0 [label="Enter function plusAssign" style="filled" fillcolor=red]; + 0 [label="Enter function test" style="filled" fillcolor=red]; subgraph cluster_1 { color=blue 1 [label="Enter block"]; - 2 [label="Exit block"]; + 2 [label="Const: Null(null)"]; + 3 [label="Check not null: Null(null)!!"]; + 4 [label="Variable declaration: lval list: R|kotlin/collections/MutableList>|"]; + 5 [label="Access variable R|/list|"]; + 6 [label="Postponed enter to lambda"]; + subgraph cluster_2 { + color=blue + 11 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_3 { + color=blue + 12 [label="Enter block"]; + 13 [label="Access variable R|/it|"]; + 14 [label="Exit block"]; + } + 15 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 7 [label="Postponed exit from lambda"]; + 8 [label="Function call: R|/list|.R|kotlin/collections/plusAssign| kotlin/String|>(...)"]; + 9 [label="Exit block"]; } - 3 [label="Exit function plusAssign" style="filled" fillcolor=red]; + 10 [label="Exit function test" style="filled" fillcolor=red]; } 0 -> {1}; 1 -> {2}; 2 -> {3}; - - subgraph cluster_2 { - color=red - 4 [label="Enter function plus" style="filled" fillcolor=red]; - subgraph cluster_3 { - color=blue - 5 [label="Enter block"]; - 6 [label="Access variable this@R|/plus|"]; - 7 [label="Jump: ^plus this@R|/plus|"]; - 8 [label="Stub" style="filled" fillcolor=gray]; - 9 [label="Exit block" style="filled" fillcolor=gray]; - } - 10 [label="Exit function plus" style="filled" fillcolor=red]; - } + 3 -> {4}; 4 -> {5}; 5 -> {6}; - 6 -> {7}; - 7 -> {10}; - 7 -> {8} [style=dotted]; - 8 -> {9} [style=dotted]; - 9 -> {10} [style=dotted]; - - subgraph cluster_4 { - color=red - 11 [label="Enter function test" style="filled" fillcolor=red]; - subgraph cluster_5 { - color=blue - 12 [label="Enter block"]; - 13 [label="Const: Null(null)"]; - 14 [label="Check not null: Null(null)!!"]; - 15 [label="Variable declaration: lval list: R|kotlin/collections/MutableList>|"]; - 16 [label="Access variable R|/list|"]; - 17 [label="Postponed enter to lambda"]; - subgraph cluster_6 { - color=blue - 22 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; - subgraph cluster_7 { - color=blue - 23 [label="Enter block"]; - 24 [label="Access variable R|/it|"]; - 25 [label="Exit block"]; - } - 26 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; - } - 18 [label="Postponed exit from lambda"]; - 19 [label="Function call: R|/list|.R|/plusAssign| kotlin/String|>(...)"]; - 20 [label="Exit block"]; - } - 21 [label="Exit function test" style="filled" fillcolor=red]; - } - 11 -> {12}; + 6 -> {11}; + 6 -> {7} [color=red]; + 7 -> {8}; + 8 -> {9}; + 9 -> {10}; + 11 -> {15 12}; 12 -> {13}; 13 -> {14}; 14 -> {15}; - 15 -> {16}; - 16 -> {17}; - 17 -> {18 22}; + 15 -> {7} [color=green]; + 15 -> {11} [color=green style=dashed]; + + subgraph cluster_4 { + color=red + 16 [label="Enter class A" style="filled" fillcolor=red]; + subgraph cluster_5 { + color=blue + 18 [label="Enter property" style="filled" fillcolor=red]; + 19 [label="Access variable R|/executor|"]; + 20 [label="Exit property" style="filled" fillcolor=red]; + } + 17 [label="Exit class A" style="filled" fillcolor=red]; + } + 16 -> {18} [color=green]; 18 -> {19}; 19 -> {20}; - 20 -> {21}; + 20 -> {17} [color=green]; + + subgraph cluster_6 { + color=red + 21 [label="Enter function " style="filled" fillcolor=red]; + 22 [label="Delegated constructor call: super()"]; + 23 [label="Exit function " style="filled" fillcolor=red]; + } + 21 -> {22}; 22 -> {23}; - 23 -> {24}; + + subgraph cluster_7 { + color=red + 24 [label="Enter function getter" style="filled" fillcolor=red]; + 25 [label="Exit function getter" style="filled" fillcolor=red]; + } 24 -> {25}; - 25 -> {26}; subgraph cluster_8 { color=red - 27 [label="Enter function listOf" style="filled" fillcolor=red]; + 26 [label="Enter function postpone" style="filled" fillcolor=red]; subgraph cluster_9 { color=blue - 28 [label="Enter block"]; - 29 [label="Const: Null(null)"]; - 30 [label="Check not null: Null(null)!!"]; - 31 [label="Jump: ^listOf Null(null)!!"]; - 32 [label="Stub" style="filled" fillcolor=gray]; - 33 [label="Exit block" style="filled" fillcolor=gray]; - } - 34 [label="Exit function listOf" style="filled" fillcolor=red]; + 27 [label="Enter block"]; + 28 [label="Function call: R|kotlin/collections/mutableListOf| kotlin/Unit|>()"]; + 29 [label="Variable declaration: lval queue: R|kotlin/collections/MutableList>|"]; + 30 [label="Postponed enter to lambda"]; + subgraph cluster_10 { + color=blue + 37 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_11 { + color=blue + 38 [label="Enter block"]; + 39 [label="Access variable R|/queue|"]; + 40 [label="Postponed enter to lambda"]; + subgraph cluster_12 { + color=blue + 45 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_13 { + color=blue + 46 [label="Enter block"]; + 47 [label="Function call: R|/computation|.R|FakeOverride|()"]; + 48 [label="Function call: R|/resolve|.R|FakeOverride|(...)"]; + 49 [label="Exit block"]; + } + 50 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 41 [label="Postponed exit from lambda"]; + 42 [label="Function call: R|/queue|.R|kotlin/collections/plusAssign| kotlin/Unit|>(...)"]; + 43 [label="Exit block"]; + } + 44 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 31 [label="Postponed exit from lambda"]; + 32 [label="Function call: R|/A.A|(...)"]; + 33 [label="Jump: ^postpone R|/A.A|( = A@fun (resolve: R|(T) -> kotlin/Unit|): R|kotlin/Unit| { + R|/queue|.R|kotlin/collections/plusAssign| kotlin/Unit|>(A@fun (): R|kotlin/Unit| { + R|/resolve|.R|FakeOverride|(R|/computation|.R|FakeOverride|()) } + ) +} +)"]; + 34 [label="Stub" style="filled" fillcolor=gray]; + 35 [label="Exit block" style="filled" fillcolor=gray]; + } + 36 [label="Exit function postpone" style="filled" fillcolor=red]; + } + 26 -> {27}; 27 -> {28}; 28 -> {29}; 29 -> {30}; - 30 -> {31}; - 31 -> {34}; - 31 -> {32} [style=dotted]; - 32 -> {33} [style=dotted]; + 30 -> {31 37}; + 31 -> {32}; + 32 -> {33}; + 33 -> {36}; 33 -> {34} [style=dotted]; + 34 -> {35} [style=dotted]; + 35 -> {36} [style=dotted]; + 37 -> {38}; + 38 -> {39}; + 39 -> {40}; + 40 -> {45}; + 40 -> {41} [color=red]; + 41 -> {42}; + 42 -> {43}; + 43 -> {44}; + 45 -> {50 46}; + 46 -> {47}; + 47 -> {48}; + 48 -> {49}; + 49 -> {50}; + 50 -> {41} [color=green]; + 50 -> {45} [color=green style=dashed]; } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.kt index 0b6f7f5f632..a2248ca2899 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.kt @@ -3,7 +3,7 @@ fun test() { val list: MutableList<(String) -> String> = null!! - list += { it } + list += { it } } class A(private val executor: ((T) -> Unit) -> Unit) @@ -12,8 +12,8 @@ fun postpone(computation: () -> T): A { val queue = mutableListOf<() -> Unit>() return A { resolve -> - queue += { + queue += { resolve(computation()) - } + } } } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.txt index 0b91590e24f..16863a33082 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.txt @@ -1,16 +1,27 @@ FILE: plusAssignWithLambdaInRhs.kt - public final operator fun R|kotlin/collections/MutableList|.plusAssign(x: R|T|): R|kotlin/Unit| { - } - public final operator fun R|kotlin/collections/List|.plus(x: R|T|): R|kotlin/collections/List| { - ^plus this@R|/plus| - } public final fun test(): R|kotlin/Unit| { lval list: R|kotlin/collections/MutableList>| = Null(null)!! - R|/list|.R|/plusAssign| kotlin/String|>(fun (it: R|kotlin/String|): R|kotlin/String| { + R|/list|.R|kotlin/collections/plusAssign| kotlin/String|>(fun (it: R|kotlin/String|): R|kotlin/String| { ^ R|/it| } ) } - public final fun listOf(x: R|T|): R|kotlin/collections/List| { - ^listOf Null(null)!! + public final class A : R|kotlin/Any| { + public constructor(executor: R|(kotlin/Function1) -> kotlin/Unit|): R|A| { + super() + } + + private final val executor: R|(kotlin/Function1) -> kotlin/Unit| = R|/executor| + private get(): R|(kotlin/Function1) -> kotlin/Unit| + + } + public final fun postpone(computation: R|() -> T|): R|A| { + lval queue: R|kotlin/collections/MutableList>| = R|kotlin/collections/mutableListOf| kotlin/Unit|>() + ^postpone R|/A.A|( = A@fun (resolve: R|(T) -> kotlin/Unit|): R|kotlin/Unit| { + R|/queue|.R|kotlin/collections/plusAssign| kotlin/Unit|>(A@fun (): R|kotlin/Unit| { + R|/resolve|.R|FakeOverride|(R|/computation|.R|FakeOverride|()) + } + ) + } + ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt index 76ae0b16904..9e755784f8a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt @@ -202,6 +202,7 @@ class FirSamResolverImpl( private fun resolveFunctionTypeIfSamInterface(firRegularClass: FirRegularClass): ConeKotlinType? { return resolvedFunctionType.getOrPut(firRegularClass) { + if (!firRegularClass.status.isFun) return@getOrPut NULL_STUB val abstractMethod = firRegularClass.getSingleAbstractMethodOrNull(firSession, scopeSession) ?: return@getOrPut NULL_STUB // TODO: val shouldConvertFirstParameterToDescriptor = samWithReceiverResolvers.any { it.shouldConvertFirstSamParameterToReceiver(abstractMethod) } diff --git a/compiler/testData/codegen/box/coroutines/await.kt b/compiler/testData/codegen/box/coroutines/await.kt index de38a4c1ce5..a47acf9136e 100644 --- a/compiler/testData/codegen/box/coroutines/await.kt +++ b/compiler/testData/codegen/box/coroutines/await.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // KJS_WITH_FULL_RUNTIME // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/diagnostics/tests/funInterface/funIsNotInheritedFromBaseInterface.fir.kt b/compiler/testData/diagnostics/tests/funInterface/funIsNotInheritedFromBaseInterface.fir.kt index aceec92281d..6d0e0dbefa7 100644 --- a/compiler/testData/diagnostics/tests/funInterface/funIsNotInheritedFromBaseInterface.fir.kt +++ b/compiler/testData/diagnostics/tests/funInterface/funIsNotInheritedFromBaseInterface.fir.kt @@ -14,6 +14,6 @@ fun takeWithFun(a: WithFun) {} fun test() { takeBase {} - takeWithoutFun({}) + takeWithoutFun({}) takeWithFun {} } diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Simple.fir.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Simple.fir.kt index 33efc0e7495..aa494b9e7e5 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Simple.fir.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Simple.fir.kt @@ -16,7 +16,7 @@ fun foo(javaClass: JavaClass, kotlinClass: KotlinClass) { bar() } - javaClass.doSomething2 { + javaClass.doSomething2 { bar() } } diff --git a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt index 2208d3bcad9..a335dfd3bb5 100644 --- a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt +++ b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt @@ -92,29 +92,29 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt TYPE_OP type=.ChannelCoroutine origin=CAST typeOperand=.ChannelCoroutine CALL 'public abstract fun (): .SendChannel.ProducerScope> declared in .ProducerScope' type=.SendChannel origin=GET_PROPERTY $this: GET_VAR ': .ProducerScope declared in .asFairChannel.' type=.ProducerScope origin=null - CALL 'public abstract fun collect (collector: .FlowCollector.Flow>): kotlin.Unit [suspend] declared in .Flow' type=kotlin.Unit origin=null - $this: GET_VAR 'flow: .Flow<*> declared in .asFairChannel' type=.Flow<*> origin=null - collector: TYPE_OP type=.FlowCollector origin=SAM_CONVERSION typeOperand=.FlowCollector - FUN_EXPR type=kotlin.Function1 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (value:kotlin.Any?) returnType:kotlin.Unit - VALUE_PARAMETER name:value index:0 type:kotlin.Any? - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (value: kotlin.Any?): kotlin.Unit declared in .asFairChannel.' - CALL 'public final fun sendFair (element: E of .ChannelCoroutine): kotlin.Unit [suspend] declared in .ChannelCoroutine' type=kotlin.Unit origin=null - $this: GET_VAR 'val channel: .ChannelCoroutine [val] declared in .asFairChannel.' type=.ChannelCoroutine origin=null - element: BLOCK type=kotlin.Any origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Any? [val] - GET_VAR 'value: kotlin.Any? declared in .asFairChannel..' 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_0: kotlin.Any? [val] declared in .asFairChannel..' type=kotlin.Any? origin=null - arg1: CONST Null type=kotlin.Nothing? value=null - then: CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' type=kotlin.Any origin=null - BRANCH - if: CONST Boolean type=kotlin.Boolean value=true - then: TYPE_OP type=kotlin.Any origin=IMPLICIT_CAST typeOperand=kotlin.Any - GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .asFairChannel..' type=kotlin.Any? origin=null + CALL 'public final fun collect (action: kotlin.coroutines.SuspendFunction1.collect, kotlin.Unit>): kotlin.Unit [inline,suspend] declared in ' type=kotlin.Unit origin=null + : kotlin.Any? + $receiver: GET_VAR 'flow: .Flow<*> declared in .asFairChannel' type=.Flow<*> origin=null + action: FUN_EXPR type=kotlin.coroutines.SuspendFunction1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (value:kotlin.Any?) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER name:value index:0 type:kotlin.Any? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (value: kotlin.Any?): kotlin.Unit [suspend] declared in .asFairChannel.' + CALL 'public final fun sendFair (element: E of .ChannelCoroutine): kotlin.Unit [suspend] declared in .ChannelCoroutine' type=kotlin.Unit origin=null + $this: GET_VAR 'val channel: .ChannelCoroutine [val] declared in .asFairChannel.' type=.ChannelCoroutine origin=null + element: BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Any? [val] + GET_VAR 'value: kotlin.Any? declared in .asFairChannel..' 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_0: kotlin.Any? [val] declared in .asFairChannel..' type=kotlin.Any? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' type=kotlin.Any origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: TYPE_OP type=kotlin.Any origin=IMPLICIT_CAST typeOperand=kotlin.Any + GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .asFairChannel..' type=kotlin.Any? origin=null FUN name:asChannel visibility:private modality:FINAL <> ($receiver:.CoroutineScope, flow:.Flow<*>) returnType:.ReceiveChannel $receiver: VALUE_PARAMETER name: type:.CoroutineScope VALUE_PARAMETER name:flow index:0 type:.Flow<*> @@ -127,30 +127,30 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> ($receiver:.ProducerScope) returnType:kotlin.Unit [suspend] $receiver: VALUE_PARAMETER name: type:.ProducerScope BLOCK_BODY - CALL 'public abstract fun collect (collector: .FlowCollector.Flow>): kotlin.Unit [suspend] declared in .Flow' type=kotlin.Unit origin=null - $this: GET_VAR 'flow: .Flow<*> declared in .asChannel' type=.Flow<*> origin=null - collector: TYPE_OP type=.FlowCollector origin=SAM_CONVERSION typeOperand=.FlowCollector - FUN_EXPR type=kotlin.Function1 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (value:kotlin.Any?) returnType:kotlin.Unit - VALUE_PARAMETER name:value index:0 type:kotlin.Any? - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (value: kotlin.Any?): kotlin.Unit declared in .asChannel.' - CALL 'public abstract fun send (e: E of .SendChannel): kotlin.Unit [suspend] declared in .SendChannel' type=kotlin.Unit origin=null - $this: CALL 'public abstract fun (): .SendChannel.ProducerScope> declared in .ProducerScope' type=.SendChannel origin=GET_PROPERTY - $this: GET_VAR ': .ProducerScope declared in .asChannel.' type=.ProducerScope origin=null - e: BLOCK type=kotlin.Any origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Any? [val] - GET_VAR 'value: kotlin.Any? declared in .asChannel..' 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_1: kotlin.Any? [val] declared in .asChannel..' type=kotlin.Any? origin=null - arg1: CONST Null type=kotlin.Nothing? value=null - then: CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' type=kotlin.Any origin=null - BRANCH - if: CONST Boolean type=kotlin.Boolean value=true - then: TYPE_OP type=kotlin.Any origin=IMPLICIT_CAST typeOperand=kotlin.Any - GET_VAR 'val tmp_1: kotlin.Any? [val] declared in .asChannel..' type=kotlin.Any? origin=null + CALL 'public final fun collect (action: kotlin.coroutines.SuspendFunction1.collect, kotlin.Unit>): kotlin.Unit [inline,suspend] declared in ' type=kotlin.Unit origin=null + : kotlin.Any? + $receiver: GET_VAR 'flow: .Flow<*> declared in .asChannel' type=.Flow<*> origin=null + action: FUN_EXPR type=kotlin.coroutines.SuspendFunction1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (value:kotlin.Any?) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER name:value index:0 type:kotlin.Any? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (value: kotlin.Any?): kotlin.Unit [suspend] declared in .asChannel.' + CALL 'public abstract fun send (e: E of .SendChannel): kotlin.Unit [suspend] declared in .SendChannel' type=kotlin.Unit origin=null + $this: CALL 'public abstract fun (): .SendChannel.ProducerScope> declared in .ProducerScope' type=.SendChannel origin=GET_PROPERTY + $this: GET_VAR ': .ProducerScope declared in .asChannel.' type=.ProducerScope origin=null + e: BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Any? [val] + GET_VAR 'value: kotlin.Any? declared in .asChannel..' 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_1: kotlin.Any? [val] declared in .asChannel..' type=kotlin.Any? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' type=kotlin.Any origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: TYPE_OP type=kotlin.Any origin=IMPLICIT_CAST typeOperand=kotlin.Any + GET_VAR 'val tmp_1: kotlin.Any? [val] declared in .asChannel..' type=kotlin.Any? origin=null CLASS CLASS name:SafeCollector modality:FINAL visibility:public superTypes:[.FlowCollector.SafeCollector>] $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.SafeCollector.SafeCollector> TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]