Fix building fake overrides for sam and function references

This commit is contained in:
Pavel Kunyavskiy
2022-09-27 12:04:33 +02:00
committed by Space Team
parent 95eaf3d234
commit ea3713f051
5 changed files with 48 additions and 31 deletions
@@ -219,7 +219,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
isSuspend = originalSuperMethod.isSuspend
setSourceRange(createFor)
}.apply {
overriddenSymbols = listOf(transformedSuperMethod.symbol)
overriddenSymbols = listOf(originalSuperMethod.symbol)
dispatchReceiverParameter = subclass.thisReceiver!!.copyTo(this)
extensionReceiverParameter = originalSuperMethod.extensionReceiverParameter?.copyTo(this)
valueParameters = originalSuperMethod.valueParameters.map { it.copyTo(this) }
@@ -239,7 +239,13 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
if (superType.needEqualsHashCodeMethods)
generateEqualsHashCode(subclass, superType, field)
subclass.addFakeOverrides(context.typeSystem)
subclass.addFakeOverrides(
context.typeSystem,
// Built function overrides originalSuperMethod, while, if parent class is already lowered, it would
// transformedSuperMethod in its declaration list. We need not fake override in that case.
// Later lowerings will fix it and replace function with one overriding transformedSuperMethod.
ignoredParentSymbols = listOf(transformedSuperMethod.symbol)
)
return subclass
}
@@ -171,7 +171,8 @@ class IrOverridingUtil(
fun buildFakeOverridesForClassUsingOverriddenSymbols(
clazz: IrClass,
implementedMembers: List<IrOverridableMember> = emptyList(),
compatibilityMode: Boolean
compatibilityMode: Boolean,
ignoredParentSymbols: List<IrSymbol> = emptyList()
): List<IrOverridableMember> {
val overriddenMembers = (clazz.declarations.filterIsInstance<IrOverridableMember>() + implementedMembers)
.flatMap { member -> member.overriddenSymbols.map { it.owner } }
@@ -182,7 +183,7 @@ class IrOverridingUtil(
superClass.declarations
.filterIsInstance<IrOverridableMember>()
.filterNot {
it in overriddenMembers || it.isStaticMember || DescriptorVisibilities.isPrivate(it.visibility)
it in overriddenMembers || it.symbol in ignoredParentSymbols || it.isStaticMember || DescriptorVisibilities.isPrivate(it.visibility)
}
.map { overriddenMember ->
val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, overriddenMember, clazz)
@@ -1125,9 +1125,16 @@ private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy(empt
}
}
fun IrClass.addFakeOverrides(typeSystem: IrTypeSystemContext, implementedMembers: List<IrOverridableMember> = emptyList()) {
fun IrClass.addFakeOverrides(
typeSystem: IrTypeSystemContext,
implementedMembers: List<IrOverridableMember> = emptyList(),
ignoredParentSymbols: List<IrSymbol> = emptyList()
) {
IrOverridingUtil(typeSystem, FakeOverrideBuilderForLowerings())
.buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers, compatibilityMode = false)
.buildFakeOverridesForClassUsingOverriddenSymbols(this,
implementedMembers = implementedMembers,
compatibilityMode = false,
ignoredParentSymbols = ignoredParentSymbols)
.forEach { addChild(it) }
}
@@ -11,11 +11,20 @@ import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
import helpers.EmptyContinuation
suspend fun run(block: suspend () -> Unit) = A(block).run()
suspend fun runA(block: suspend () -> Unit) = A(block).run()
suspend fun runC(block: suspend () -> Unit) = C(block).run()
fun box(): String {
suspend {
run {}
runA {}
runC {}
A { }.run()
C { }.run()
}.startCoroutine(EmptyContinuation)
return "OK"
}
// FILE: c.kt
fun interface C {
suspend fun run()
}