summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Gorbunov <ilya.gorbunov@jetbrains.com>2020-07-07 04:50:42 +0300
committerIlya Gorbunov <ilya.gorbunov@jetbrains.com>2020-07-10 15:47:21 +0300
commit0a8b4c6996f4b8a4c66c696ec97a3b855754b7cf (patch)
treee6c7f211950927d97e11b8718af45465e1a9f452
parent17e210e19cb0d46b71c0969629ceed8e34ff3d95 (diff)
downloadkotlin-0a8b4c6996f4b8a4c66c696ec97a3b855754b7cf.tar.gz
Add EXACTLY_ONCE contract to suspendCoroutine* functions
Update line numbers in the affected test. (cherry picked from commit 2f3e1dcbc6d97b38cdca2dbbb954ef4adf728668)
-rw-r--r--js/js.translator/testData/lineNumbers/coroutine.kt2
-rw-r--r--libraries/stdlib/jvm/test/coroutines/CoroutinesTest.kt16
-rw-r--r--libraries/stdlib/src/kotlin/coroutines/Continuation.kt9
-rw-r--r--libraries/stdlib/src/kotlin/coroutines/intrinsics/Intrinsics.kt7
4 files changed, 23 insertions, 11 deletions
diff --git a/js/js.translator/testData/lineNumbers/coroutine.kt b/js/js.translator/testData/lineNumbers/coroutine.kt
index 41b8a593698..c4562c1c16d 100644
--- a/js/js.translator/testData/lineNumbers/coroutine.kt
+++ b/js/js.translator/testData/lineNumbers/coroutine.kt
@@ -14,4 +14,4 @@ suspend fun bar(): Unit {
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 \ No newline at end of file
+// 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 \ No newline at end of file
diff --git a/libraries/stdlib/jvm/test/coroutines/CoroutinesTest.kt b/libraries/stdlib/jvm/test/coroutines/CoroutinesTest.kt
index 99b79a4b77f..a4b6b48da42 100644
--- a/libraries/stdlib/jvm/test/coroutines/CoroutinesTest.kt
+++ b/libraries/stdlib/jvm/test/coroutines/CoroutinesTest.kt
@@ -39,11 +39,17 @@ class DispatcherSwitcher(
private val contextDispatcher: TestDispatcher,
private val resumeDispatcher: TestDispatcher
) {
- suspend fun run(): Int = suspendCoroutine { cont ->
- contextDispatcher.assertThread()
- resumeDispatcher.executor.execute {
- resumeDispatcher.assertThread()
- cont.resume(42)
+ suspend fun run(): Int {
+ val sideEffect: Int
+ val runResult = suspendCoroutine<Int> { cont ->
+ contextDispatcher.assertThread()
+ resumeDispatcher.executor.execute {
+ resumeDispatcher.assertThread()
+ cont.resume(42)
+ }
+ sideEffect = 21
}
+ assertEquals(21, sideEffect)
+ return runResult
}
}
diff --git a/libraries/stdlib/src/kotlin/coroutines/Continuation.kt b/libraries/stdlib/src/kotlin/coroutines/Continuation.kt
index a4f06cf2c6d..375cec539a5 100644
--- a/libraries/stdlib/src/kotlin/coroutines/Continuation.kt
+++ b/libraries/stdlib/src/kotlin/coroutines/Continuation.kt
@@ -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.
*/
package kotlin.coroutines
+import kotlin.contracts.*
import kotlin.coroutines.intrinsics.*
import kotlin.internal.InlineOnly
@@ -138,12 +139,14 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
*/
@SinceKotlin("1.3")
@InlineOnly
-public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T =
- suspendCoroutineUninterceptedOrReturn { c: Continuation<T> ->
+public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T {
+ contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
+ return suspendCoroutineUninterceptedOrReturn { c: Continuation<T> ->
val safe = SafeContinuation(c.intercepted())
block(safe)
safe.getOrThrow()
}
+}
/**
* Returns the context of the current coroutine.
diff --git a/libraries/stdlib/src/kotlin/coroutines/intrinsics/Intrinsics.kt b/libraries/stdlib/src/kotlin/coroutines/intrinsics/Intrinsics.kt
index ba08334d69a..3b3dd23e4dd 100644
--- a/libraries/stdlib/src/kotlin/coroutines/intrinsics/Intrinsics.kt
+++ b/libraries/stdlib/src/kotlin/coroutines/intrinsics/Intrinsics.kt
@@ -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.
*/
@@ -8,6 +8,7 @@
package kotlin.coroutines.intrinsics
+import kotlin.contracts.*
import kotlin.coroutines.*
import kotlin.internal.InlineOnly
@@ -37,8 +38,10 @@ import kotlin.internal.InlineOnly
@SinceKotlin("1.3")
@InlineOnly
@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")
+}
/**
* This value is used as a return value of [suspendCoroutineUninterceptedOrReturn] `block` argument to state that