From be854550f781973b82df98f1381deb28c6e3fc87 Mon Sep 17 00:00:00 2001 From: Vsevolod Tolstopyatov Date: Wed, 29 Apr 2020 11:42:46 +0300 Subject: [PATCH] Fix class cast exception during undispatched resume of cancellable continuation with onCancellation block (#1967) Fixes #1966 --- .../common/src/internal/DispatchedTask.kt | 2 +- .../common/test/CancellableResumeTest.kt | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt b/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt index 9588d22b17..32258ba101 100644 --- a/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt +++ b/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt @@ -117,7 +117,7 @@ internal fun DispatchedTask.resume(delegate: Continuation, useMode: In // slow-path - use delegate val state = takeState() val exception = getExceptionalResult(state)?.let { recoverStackTrace(it, delegate) } - val result = if (exception != null) Result.failure(exception) else Result.success(state as T) + val result = if (exception != null) Result.failure(exception) else Result.success(getSuccessfulResult(state)) when (useMode) { MODE_ATOMIC_DEFAULT -> delegate.resumeWith(result) MODE_CANCELLABLE -> delegate.resumeCancellableWith(result) diff --git a/kotlinx-coroutines-core/common/test/CancellableResumeTest.kt b/kotlinx-coroutines-core/common/test/CancellableResumeTest.kt index 035e2fb55d..39176a9a94 100644 --- a/kotlinx-coroutines-core/common/test/CancellableResumeTest.kt +++ b/kotlinx-coroutines-core/common/test/CancellableResumeTest.kt @@ -138,4 +138,16 @@ class CancellableResumeTest : TestBase() { yield() // to coroutine -- throws cancellation exception finish(9) } + + + @Test + fun testResumeUnconfined() = runTest { + val outerScope = this + withContext(Dispatchers.Unconfined) { + val result = suspendCancellableCoroutine { + outerScope.launch { it.resume("OK", {}) } + } + assertEquals("OK", result) + } + } } \ No newline at end of file