diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index d874cbca46c..2953928ced8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -11,11 +11,13 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods import org.jetbrains.kotlin.backend.jvm.intrinsics.JavaClassProperty +import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry import org.jetbrains.kotlin.backend.jvm.lower.constantValue import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass import org.jetbrains.kotlin.backend.jvm.lower.isMultifileBridge import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal +import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.AsmUtil.* import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getNameForReceiverParameter @@ -628,9 +630,27 @@ class ExpressionCodegen( expression.markLineNumber(startOffset = true) val type = frameMap.typeOf(expression.symbol) mv.load(findLocalIndex(expression.symbol), type) + unboxResultIfNeeded(expression) return MaterialValue(this, type, expression.type) } + // We do not mangle functions if Result is the only parameter of the function, + // thus, if the function overrides generic parameter, its argument is boxed and there is no + // bridge to unbox it. Instead, we unbox it in the non-mangled function manually. + private fun unboxResultIfNeeded(arg: IrGetValue) { + if (arg.type.erasedUpperBound.fqNameWhenAvailable != StandardNames.RESULT_FQ_NAME) return + if (irFunction !is IrSimpleFunction) return + + val index = (arg.symbol as? IrValueParameterSymbol)?.owner?.index ?: return + val genericOrAnyOverride = irFunction.overriddenSymbols.any { + val overriddenParam = if (index < 0) it.owner.dispatchReceiverParameter!! else it.owner.valueParameters[index] + overriddenParam.type.erasedUpperBound.fqNameWhenAvailable != StandardNames.RESULT_FQ_NAME + } || irFunction.parentAsClass.origin == JvmLoweredDeclarationOrigin.LAMBDA_IMPL + if (!genericOrAnyOverride) return + + StackValue.unboxInlineClass(OBJECT_TYPE, arg.type.toIrBasedKotlinType(), mv) + } + override fun visitFieldAccess(expression: IrFieldAccessExpression, data: BlockInfo): PromisedValue { val callee = expression.symbol.owner if (context.state.shouldInlineConstVals) { diff --git a/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/funInterface/result.kt b/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/funInterface/result.kt index aace7ed01cc..4537fa84cf7 100644 --- a/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/funInterface/result.kt +++ b/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/funInterface/result.kt @@ -1,7 +1,5 @@ // !LANGUAGE: +InlineClasses // WITH_RUNTIME -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_FIR: JVM_IR fun foo(a: Result): T = bar(a) { it.getOrThrow() diff --git a/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/lambda/result.kt b/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/lambda/result.kt index ea0c0dff3fd..38e8b625326 100644 --- a/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/lambda/result.kt +++ b/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/lambda/result.kt @@ -1,7 +1,5 @@ // !LANGUAGE: +InlineClasses // WITH_RUNTIME -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_FIR: JVM_IR fun foo(a: Result): T = bar(a) { it.getOrThrow() diff --git a/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/objectLiteral/result.kt b/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/objectLiteral/result.kt index 9a0d8e7d0f9..23d285cae90 100644 --- a/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/objectLiteral/result.kt +++ b/compiler/testData/codegen/box/inlineClasses/unboxGenericParameter/objectLiteral/result.kt @@ -1,7 +1,5 @@ // !LANGUAGE: +InlineClasses // WITH_RUNTIME -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_FIR: JVM_IR fun foo(a: Result): T = bar(a, object : IFace, T> { override fun call(ic: Result): T = ic.getOrThrow()