[JVM_IR] Fix inline class default method codegen.

Do not coroutine transform static inline class replacements that
forward to a default interface suspend method. No boxing has to
take place on return (as the default interface method always
boxes) so we can simply forward the call.

^KT-49645 Fixed
This commit is contained in:
Mads Ager
2021-11-23 15:15:33 +01:00
committed by Alexander Udalov
parent 50f610cfd8
commit 529944fe9c
7 changed files with 69 additions and 5 deletions
@@ -9828,6 +9828,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/coroutines/kt49168.kt");
}
@Test
@TestMetadata("kt49645.kt")
public void testKt49645() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/kt49645.kt");
}
@Test
@TestMetadata("lastExpressionIsLoop.kt")
public void testLastExpressionIsLoop() throws Exception {
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.file
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.isSuspend
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Type
@@ -147,7 +144,15 @@ private val BRIDGE_ORIGINS = setOf(
// These functions contain a single `suspend` tail call, the value of which should be returned as is
// (i.e. if it's an unboxed inline class value, it should remain unboxed).
internal fun IrFunction.isNonBoxingSuspendDelegation(): Boolean =
origin in BRIDGE_ORIGINS || isMultifileBridge() || isBridgeToSuspendImplMethod()
origin in BRIDGE_ORIGINS ||
isMultifileBridge() ||
isBridgeToSuspendImplMethod() ||
isStaticInlineClassReplacementForDefaultInterfaceMethod()
// Suspend static inline class replacements for fake overrides have to be for interface methods as inline classes cannot have a
// non-Object super type.
fun IrFunction.isStaticInlineClassReplacementForDefaultInterfaceMethod(): Boolean =
isStaticInlineClassReplacement && this is IrSimpleFunction && (attributeOwnerId as IrSimpleFunction).isFakeOverride
fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isNonBoxingSuspendDelegation() &&
// These functions also contain a single `suspend` tail call, but if it returns an unboxed inline class value,
+30
View File
@@ -0,0 +1,30 @@
// WITH_STDLIB
// WITH_COROUTINES
// TARGET_BACKEND: JVM
import helpers.*
import kotlin.coroutines.*
interface Cont1 {
suspend fun flaf() = "O"
suspend fun toResult(): Result<String> {
val x = flaf()
return Result.success(x + "K")
}
}
@JvmInline
private value class ContImpl(val a: String) : Cont1
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
var result = "FAIL"
builder {
result = ContImpl("A").toResult().getOrThrow()
}
return result
}
@@ -9750,6 +9750,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/coroutines/kt49168.kt");
}
@Test
@TestMetadata("kt49645.kt")
public void testKt49645() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/kt49645.kt");
}
@Test
@TestMetadata("lastExpressionIsLoop.kt")
public void testLastExpressionIsLoop() throws Exception {
@@ -9828,6 +9828,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/coroutines/kt49168.kt");
}
@Test
@TestMetadata("kt49645.kt")
public void testKt49645() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/kt49645.kt");
}
@Test
@TestMetadata("lastExpressionIsLoop.kt")
public void testLastExpressionIsLoop() throws Exception {
@@ -7638,6 +7638,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/coroutines/kt46813.kt");
}
@TestMetadata("kt49645.kt")
public void testKt49645() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/kt49645.kt");
}
@TestMetadata("lastExpressionIsLoop.kt")
public void testLastExpressionIsLoop() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt");
@@ -7730,6 +7730,12 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest {
runTest("compiler/testData/codegen/box/coroutines/kt49168.kt");
}
@Test
@TestMetadata("kt49645.kt")
public void testKt49645() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/kt49645.kt");
}
@Test
@TestMetadata("lastExpressionIsLoop.kt")
public void testLastExpressionIsLoop() throws Exception {