Add EXACTLY_ONCE contract to suspendCoroutine* functions

Update line numbers in the affected test.
This commit is contained in:
Ilya Gorbunov
2020-07-07 04:50:42 +03:00
parent 1a32fdf6d7
commit 2f3e1dcbc6
4 changed files with 23 additions and 11 deletions
+1 -1
View File
@@ -14,4 +14,4 @@ suspend fun bar(): Unit {
println(a + b) println(a + b)
} }
// LINES: 38 4 4 4 7 5 5 44 44 5 92 44 5 5 6 4 4 4 9 15 9 9 9 * 9 15 10 10 11 11 11 11 11 * 11 12 12 13 13 13 13 13 13 13 14 14 * 9 15 9 9 9 9 // LINES: 39 4 4 4 7 5 5 45 45 5 92 45 5 5 6 4 4 4 9 15 9 9 9 * 9 15 10 10 11 11 11 11 11 * 11 12 12 13 13 13 13 13 13 13 14 14 * 9 15 9 9 9 9
@@ -39,11 +39,17 @@ class DispatcherSwitcher(
private val contextDispatcher: TestDispatcher, private val contextDispatcher: TestDispatcher,
private val resumeDispatcher: TestDispatcher private val resumeDispatcher: TestDispatcher
) { ) {
suspend fun run(): Int = suspendCoroutine { cont -> suspend fun run(): Int {
contextDispatcher.assertThread() val sideEffect: Int
resumeDispatcher.executor.execute { val runResult = suspendCoroutine<Int> { cont ->
resumeDispatcher.assertThread() contextDispatcher.assertThread()
cont.resume(42) resumeDispatcher.executor.execute {
resumeDispatcher.assertThread()
cont.resume(42)
}
sideEffect = 21
} }
assertEquals(21, sideEffect)
return runResult
} }
} }
@@ -1,10 +1,11 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package kotlin.coroutines package kotlin.coroutines
import kotlin.contracts.*
import kotlin.coroutines.intrinsics.* import kotlin.coroutines.intrinsics.*
import kotlin.internal.InlineOnly import kotlin.internal.InlineOnly
@@ -138,12 +139,14 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
*/ */
@SinceKotlin("1.3") @SinceKotlin("1.3")
@InlineOnly @InlineOnly
public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T = public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T {
suspendCoroutineUninterceptedOrReturn { c: Continuation<T> -> contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
return suspendCoroutineUninterceptedOrReturn { c: Continuation<T> ->
val safe = SafeContinuation(c.intercepted()) val safe = SafeContinuation(c.intercepted())
block(safe) block(safe)
safe.getOrThrow() safe.getOrThrow()
} }
}
/** /**
* Returns the context of the current coroutine. * Returns the context of the current coroutine.
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -8,6 +8,7 @@
package kotlin.coroutines.intrinsics package kotlin.coroutines.intrinsics
import kotlin.contracts.*
import kotlin.coroutines.* import kotlin.coroutines.*
import kotlin.internal.InlineOnly import kotlin.internal.InlineOnly
@@ -37,8 +38,10 @@ import kotlin.internal.InlineOnly
@SinceKotlin("1.3") @SinceKotlin("1.3")
@InlineOnly @InlineOnly
@Suppress("UNUSED_PARAMETER", "RedundantSuspendModifier") @Suppress("UNUSED_PARAMETER", "RedundantSuspendModifier")
public suspend inline fun <T> suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation<T>) -> Any?): T = public suspend inline fun <T> suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation<T>) -> Any?): T {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
throw NotImplementedError("Implementation of suspendCoroutineUninterceptedOrReturn is intrinsic") throw NotImplementedError("Implementation of suspendCoroutineUninterceptedOrReturn is intrinsic")
}
/** /**
* This value is used as a return value of [suspendCoroutineUninterceptedOrReturn] `block` argument to state that * This value is used as a return value of [suspendCoroutineUninterceptedOrReturn] `block` argument to state that