diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CheckerSink.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CheckerSink.kt index 3533181d4ed..910f4a9cf9e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CheckerSink.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CheckerSink.kt @@ -7,33 +7,46 @@ package org.jetbrains.kotlin.fir.resolve.calls import kotlin.coroutines.Continuation -interface CheckerSink { - fun reportApplicability(new: CandidateApplicability) - suspend fun yield() - suspend fun yieldApplicability(new: CandidateApplicability) { - reportApplicability(new) - yield() - } +abstract class CheckerSink { + abstract fun reportApplicability(new: CandidateApplicability) - val components: InferenceComponents + abstract val components: InferenceComponents - suspend fun yieldIfNeed() + abstract val needYielding: Boolean + + @Deprecated( + "This function yields unconditionally, exposed only for yieldIfNeed", + level = DeprecationLevel.WARNING, + replaceWith = ReplaceWith("yieldIfNeed") + ) + abstract suspend fun yield() } -class CheckerSinkImpl(override val components: InferenceComponents, var continuation: Continuation? = null) : CheckerSink { +suspend inline fun CheckerSink.yieldIfNeed() { + if (needYielding) { + @Suppress("DEPRECATION") + yield() + } +} + +suspend inline fun CheckerSink.yieldApplicability(new: CandidateApplicability) { + reportApplicability(new) + yieldIfNeed() +} + +class CheckerSinkImpl(override val components: InferenceComponents, var continuation: Continuation? = null) : CheckerSink() { var current = CandidateApplicability.RESOLVED override fun reportApplicability(new: CandidateApplicability) { if (new < current) current = new } + @Suppress("OverridingDeprecatedMember") override suspend fun yield() = kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn { continuation = it kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED } - override suspend fun yieldIfNeed() { - if (current < CandidateApplicability.SYNTHETIC_RESOLVED) { - yield() - } - } + override val needYielding: Boolean + get() = current < CandidateApplicability.SYNTHETIC_RESOLVED + } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt index 5e06d9650a3..aec2d4719eb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt @@ -112,7 +112,7 @@ internal sealed class CheckReceivers : ResolutionStage() { isSafeCall = callInfo.isSafeCall, typeProvider = callInfo.typeProvider ) - sink.yield() + sink.yieldIfNeed() } else { val argumentExtensionReceiverValue = candidate.implicitExtensionReceiverValue if (argumentExtensionReceiverValue != null && explicitReceiverKind.shouldBeCheckedAgainstImplicit()) { @@ -125,7 +125,7 @@ internal sealed class CheckReceivers : ResolutionStage() { isDispatch = this is Dispatch, isSafeCall = callInfo.isSafeCall ) - sink.yield() + sink.yieldIfNeed() } } } @@ -161,7 +161,7 @@ internal object CheckArguments : CheckerStage() { if (candidate.system.hasContradiction) { sink.yieldApplicability(CandidateApplicability.INAPPLICABLE) } - sink.yield() + sink.yieldIfNeed() } } }