Fix attribute clash between STATIC_INLINE_CLASS_REPLACEMENT and original
Attributes are used to name continuation classes and are generated before inline classes processing. During the processing, for override functions in inlined classes, the compiler generates STATIC_INLINE_CLASS_REPLACEMENT function with body of the override. The override's body is replaced with delegating call to STATIC_INLINE_CLASS_REPLACEMENT. However, since we need to keep the name of the continuation class, we copy attributes from the override to STATIC_INLINE_CLASS_REPLACEMENT. This leads to attribute clash during AddContinuationLowering. So, to fix the issue, do not use the attribute of STATIC_INLINE_CLASS_REPLACEMENT in original->suspend map. As an optimization, do not generate continuation for the override function.
This commit is contained in:
Generated
+5
@@ -6994,6 +6994,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideInInlineClass.kt")
|
||||||
|
public void testOverrideInInlineClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/overrideInInlineClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
||||||
public void testSafeCallOnTwoReceiversLong_1_3() throws Exception {
|
public void testSafeCallOnTwoReceiversLong_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines");
|
||||||
|
|||||||
+7
-1
@@ -117,6 +117,11 @@ private fun IrFunction.isBridgeToSuspendImplMethod(): Boolean =
|
|||||||
it.name.asString() == name.asString() + SUSPEND_IMPL_NAME_SUFFIX && it.attributeOwnerId == attributeOwnerId
|
it.name.asString() == name.asString() + SUSPEND_IMPL_NAME_SUFFIX && it.attributeOwnerId == attributeOwnerId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrFunction.isStaticInlineClassReplacementDelegatingCall(): Boolean =
|
||||||
|
this is IrAttributeContainer && origin != JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT &&
|
||||||
|
parentAsClass.declarations.find { it is IrAttributeContainer && it.attributeOwnerId == attributeOwnerId && it !== this }
|
||||||
|
?.origin == JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT
|
||||||
|
|
||||||
internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isInvokeSuspendOfContinuation() &&
|
internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isInvokeSuspendOfContinuation() &&
|
||||||
// These are tail-call bridges and do not require any bytecode modifications.
|
// These are tail-call bridges and do not require any bytecode modifications.
|
||||||
origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER &&
|
origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER &&
|
||||||
@@ -129,7 +134,8 @@ internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isInvokeSuspen
|
|||||||
origin != IrDeclarationOrigin.BRIDGE_SPECIAL &&
|
origin != IrDeclarationOrigin.BRIDGE_SPECIAL &&
|
||||||
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&
|
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&
|
||||||
!isInvokeOfSuspendCallableReference() &&
|
!isInvokeOfSuspendCallableReference() &&
|
||||||
!isBridgeToSuspendImplMethod()
|
!isBridgeToSuspendImplMethod() &&
|
||||||
|
!isStaticInlineClassReplacementDelegatingCall()
|
||||||
|
|
||||||
internal fun IrFunction.hasContinuation(): Boolean = isSuspend && shouldContainSuspendMarkers() &&
|
internal fun IrFunction.hasContinuation(): Boolean = isSuspend && shouldContainSuspendMarkers() &&
|
||||||
// This is inline-only function
|
// This is inline-only function
|
||||||
|
|||||||
+3
-1
@@ -640,7 +640,9 @@ private fun IrFunction.suspendFunctionViewOrStub(context: JvmBackendContext): Ir
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrFunction.suspendFunctionOriginal(): IrFunction =
|
internal fun IrFunction.suspendFunctionOriginal(): IrFunction =
|
||||||
if (this is IrSimpleFunction && isSuspend) attributeOwnerId as IrFunction else this
|
if (this is IrSimpleFunction && isSuspend && origin != JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT)
|
||||||
|
attributeOwnerId as IrFunction
|
||||||
|
else this
|
||||||
|
|
||||||
private fun IrFunction.createSuspendFunctionStub(context: JvmBackendContext): IrFunction {
|
private fun IrFunction.createSuspendFunctionStub(context: JvmBackendContext): IrFunction {
|
||||||
require(this.isSuspend && this is IrSimpleFunction)
|
require(this.isSuspend && this is IrSimpleFunction)
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
import helpers.*
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Delegate {
|
||||||
|
fun build(): String = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Digest {
|
||||||
|
suspend fun build(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
inline class DigestImpl(val delegate: Delegate) : Digest {
|
||||||
|
override suspend fun build(): String = delegate.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
val digest: Digest = DigestImpl(Delegate())
|
||||||
|
builder {
|
||||||
|
res = digest.build()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
+5
@@ -7594,6 +7594,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideInInlineClass.kt")
|
||||||
|
public void testOverrideInInlineClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/overrideInInlineClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
||||||
public void testSafeCallOnTwoReceiversLong_1_2() throws Exception {
|
public void testSafeCallOnTwoReceiversLong_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines.experimental");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines.experimental");
|
||||||
|
|||||||
+5
@@ -7594,6 +7594,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideInInlineClass.kt")
|
||||||
|
public void testOverrideInInlineClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/overrideInInlineClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
||||||
public void testSafeCallOnTwoReceiversLong_1_2() throws Exception {
|
public void testSafeCallOnTwoReceiversLong_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines.experimental");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines.experimental");
|
||||||
|
|||||||
+5
@@ -6994,6 +6994,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideInInlineClass.kt")
|
||||||
|
public void testOverrideInInlineClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/overrideInInlineClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
||||||
public void testSafeCallOnTwoReceiversLong_1_3() throws Exception {
|
public void testSafeCallOnTwoReceiversLong_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines");
|
||||||
|
|||||||
Generated
+5
@@ -5904,6 +5904,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideInInlineClass.kt")
|
||||||
|
public void testOverrideInInlineClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/overrideInInlineClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
||||||
public void testSafeCallOnTwoReceiversLong_1_3() throws Exception {
|
public void testSafeCallOnTwoReceiversLong_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines");
|
||||||
|
|||||||
+5
@@ -5904,6 +5904,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBodyGeneric.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideInInlineClass.kt")
|
||||||
|
public void testOverrideInInlineClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/overrideInInlineClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
@TestMetadata("safeCallOnTwoReceiversLong.kt")
|
||||||
public void testSafeCallOnTwoReceiversLong_1_3() throws Exception {
|
public void testSafeCallOnTwoReceiversLong_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/safeCallOnTwoReceiversLong.kt", "kotlin.coroutines");
|
||||||
|
|||||||
Reference in New Issue
Block a user