diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index c70bc9cacad..b74feeaab0b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -120,7 +120,7 @@ class JvmBackendContext( override val internalPackageFqn = FqName("kotlin.jvm") val suspendLambdaToOriginalFunctionMap = ConcurrentHashMap() - val suspendFunctionOriginalToView = ConcurrentHashMap() + val suspendFunctionOriginalToView = ConcurrentHashMap() val fakeContinuation: IrExpression = createFakeContinuation(this) val staticDefaultStubs = ConcurrentHashMap() @@ -179,17 +179,15 @@ class JvmBackendContext( } for ((staticReplacement, original) in inlineClassReplacements.originalFunctionForStaticReplacement) { + if (staticReplacement !is IrSimpleFunction) continue val newOriginal = functionSymbolMap[original.symbol]?.owner ?: continue val newStaticReplacement = inlineClassReplacements.getReplacementFunction(newOriginal) ?: continue - staticReplacement as IrSimpleFunction functionSymbolMap[staticReplacement.symbol] = newStaticReplacement.symbol } for ((original, suspendView) in suspendFunctionOriginalToView) { val newOriginal = functionSymbolMap[original.symbol]?.owner ?: continue val newSuspendView = suspendFunctionOriginalToView[newOriginal] ?: continue - suspendView as? IrSimpleFunction ?: continue - newSuspendView as? IrSimpleFunction ?: continue functionSymbolMap[suspendView.symbol] = newSuspendView.symbol } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt index 45f1a89fdeb..c44bc3d8a26 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt @@ -334,20 +334,23 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower // Transform `suspend fun foo(params): RetType` into `fun foo(params, $completion: Continuation): Any?` // the result is called 'view', just to be consistent with old backend. -private fun IrFunction.suspendFunctionViewOrStub(context: JvmBackendContext): IrFunction { +private fun IrSimpleFunction.suspendFunctionViewOrStub(context: JvmBackendContext): IrFunction { if (!isSuspend) return this return context.suspendFunctionOriginalToView.getOrPut(suspendFunctionOriginal()) { createSuspendFunctionStub(context) } } -internal fun IrFunction.suspendFunctionOriginal(): IrFunction = - if (this is IrSimpleFunction && isSuspend && +internal fun IrSimpleFunction.suspendFunctionOriginal(): IrSimpleFunction = + if (isSuspend && !isStaticInlineClassReplacement && !isOrOverridesDefaultParameterStub() && parentAsClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS ) - attributeOwnerId as IrFunction + attributeOwnerId as IrSimpleFunction else this +internal fun IrFunction.suspendFunctionOriginal(): IrFunction = + (this as? IrSimpleFunction)?.suspendFunctionOriginal() ?: this + private fun IrSimpleFunction.isOrOverridesDefaultParameterStub(): Boolean = // Cannot use resolveFakeOverride here because of KT-36188. DFS.ifAny( @@ -356,8 +359,8 @@ private fun IrSimpleFunction.isOrOverridesDefaultParameterStub(): Boolean = { it.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER } ) -private fun IrFunction.createSuspendFunctionStub(context: JvmBackendContext): IrFunction { - require(this.isSuspend && this is IrSimpleFunction) +private fun IrSimpleFunction.createSuspendFunctionStub(context: JvmBackendContext): IrSimpleFunction { + require(this.isSuspend) return factory.buildFun { updateFrom(this@createSuspendFunctionStub) name = this@createSuspendFunctionStub.name @@ -414,12 +417,13 @@ private fun > T.retargetToSuspend copyWithTargetSymbol: T.(IrSimpleFunctionSymbol) -> T ): T { // Calls inside continuation are already generated with continuation parameter as well as calls to suspendImpls - if (!symbol.owner.isSuspend || caller?.isInvokeSuspendOfContinuation() == true - || symbol.owner.origin == JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION - || symbol.owner.continuationParameter() != null + val owner = symbol.owner + if (owner !is IrSimpleFunction || !owner.isSuspend || caller?.isInvokeSuspendOfContinuation() == true + || owner.origin == JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION + || owner.continuationParameter() != null ) return this - val view = symbol.owner.suspendFunctionViewOrStub(context) - if (view == symbol.owner) return this + val view = owner.suspendFunctionViewOrStub(context) + if (view == owner) return this // While the new callee technically returns ` | COROUTINE_SUSPENDED`, the latter case is handled // by a method visitor so at an IR overview we don't need to consider it. @@ -439,7 +443,7 @@ private fun > T.retargetToSuspend else IrGetValueImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, caller.continuationParameter()?.symbol - ?: throw AssertionError("${caller.render()} has no continuation; can't call ${symbol.owner.render()}") + ?: throw AssertionError("${caller.render()} has no continuation; can't call ${owner.render()}") ) it.putValueArgument(continuationIndex, continuation) }