| // TARGET_BACKEND: JVM | |
| // WITH_STDLIB | |
| // WITH_COROUTINES | |
| // FILE: flow.kt | |
| package flow | |
| interface FlowCollector<T> { | |
| suspend fun emit(value: T) | |
| } | |
| interface Flow<T : Any> { | |
| suspend fun collect(collector: FlowCollector<T>) | |
| } | |
| public inline fun <T : Any> flow(crossinline block: suspend FlowCollector<T>.() -> Unit): Flow<T> = object : Flow<T> { | |
| override suspend fun collect(collector: FlowCollector<T>) = collector.block() | |
| } | |
| inline suspend fun <T : Any> Flow<T>.collect(crossinline action: suspend (T) -> Unit): Unit = | |
| collect(object : FlowCollector<T> { | |
| override suspend fun emit(value: T) = action(value) | |
| }) | |
| inline suspend fun inlineMe(crossinline block: suspend () -> Unit) = suspend { | |
| block() | |
| } | |
| // FILE: Test.kt | |
| import flow.* | |
| import helpers.* | |
| import kotlin.coroutines.* | |
| import kotlin.coroutines.intrinsics.* | |
| fun builder(c: suspend () -> Unit) { | |
| c.startCoroutine(EmptyContinuation) | |
| } | |
| fun box(): String { | |
| var str = "FAIL" | |
| builder { | |
| flow<Unit> { | |
| var continuation: Continuation<Unit>? = null | |
| suspendCoroutineUninterceptedOrReturn<Unit> { continuation = it; Unit } | |
| str = "$continuation" | |
| }.collect { | |
| } | |
| } | |
| if ("(Test.kt:" !in str) return str | |
| builder { | |
| inlineMe { | |
| var continuation: Continuation<Unit>? = null | |
| suspendCoroutineUninterceptedOrReturn<Unit> { continuation = it; Unit } | |
| str = "$continuation" | |
| }() | |
| } | |
| if ("(Test.kt:" !in str) return str | |
| return "OK" | |
| } |