Repository: Kotlin/kotlinx.coroutines
File: kotlinx-coroutines-core/common/src/selects/SelectOld.kt (Kotlin)

Code before:
    return suspendCoroutineUninterceptedOrReturn { uCont ->
        val scope = SelectBuilderImpl(uCont)
        try {
            builder(scope)
        } catch (e: Throwable) {
            scope.handleBuilderException(e)
        }
        scope.getResult()
    }
}

// This is the old version of `selectUnbiased`. It should work to guarantee binary compatibility.
@PublishedApi
internal suspend inline fun <R> selectUnbiasedOld(crossinline builder: SelectBuilder<R>.() -> Unit): R =
    suspendCoroutineUninterceptedOrReturn { uCont ->
        val scope = UnbiasedSelectBuilderImpl(uCont)
        try {
            builder(scope)
        } catch (e: Throwable) {
            scope.handleBuilderException(e)
        }
        scope.initSelectResult()
    }

@OptIn(ExperimentalStdlibApi::class)
private fun <T> CancellableContinuation<T>.resumeUndispatched(result: T) {
    val dispatcher = context[CoroutineDispatcher]
    if (dispatcher != null) {
        dispatcher.resumeUndispatched(result)
    } else {
        resume(result)
    }
}

@OptIn(ExperimentalStdlibApi::class)
private fun CancellableContinuation<*>.resumeUndispatchedWithException(exception: Throwable) {
    val dispatcher = context[CoroutineDispatcher]
    if (dispatcher != null) {
        dispatcher.resumeUndispatchedWithException(exception)
    } else {
        resumeWithException(exception)
    }
}


Review comment (suggestion):
Use the explicit `ContinuationInterceptor.Key`, as per the deprecation advice? Or, alternatively, fix the advice to use the implicit `ContinuationInterceptor` and fix all usages to be implicit.

I'd mildly prefer all usages in the codebase to be either all `ContinuationInterceptor` xor all `ContinuationInterceptor.Key`, not just the ones you touch in this PR.

I don't have a strong opinion, just noticing a tiny inconsistency. Feel free to discard if it makes some sense to keep them different.

Code after:
    return suspendCoroutineUninterceptedOrReturn { uCont ->
        val scope = SelectBuilderImpl(uCont)
        try {
            builder(scope)
        } catch (e: Throwable) {
            scope.handleBuilderException(e)
        }
        scope.getResult()
    }
}

// This is the old version of `selectUnbiased`. It should work to guarantee binary compatibility.
@PublishedApi
internal suspend inline fun <R> selectUnbiasedOld(crossinline builder: SelectBuilder<R>.() -> Unit): R =
    suspendCoroutineUninterceptedOrReturn { uCont ->
        val scope = UnbiasedSelectBuilderImpl(uCont)
        try {
            builder(scope)
        } catch (e: Throwable) {
            scope.handleBuilderException(e)
        }
        scope.initSelectResult()
    }

private fun <T> CancellableContinuation<T>.resumeUndispatched(result: T) {
    val dispatcher = context[ContinuationInterceptor] as? CoroutineDispatcher
    if (dispatcher != null) {
        dispatcher.resumeUndispatched(result)
    } else {
        resume(result)
    }
}

private fun CancellableContinuation<*>.resumeUndispatchedWithException(exception: Throwable) {
    val dispatcher = context[ContinuationInterceptor] as? CoroutineDispatcher
    if (dispatcher != null) {
        dispatcher.resumeUndispatchedWithException(exception)
    } else {
        resumeWithException(exception)
    }
}