diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt index ff020c276b5..828a36fb77a 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt @@ -299,11 +299,22 @@ class SerializableIrGenerator( ignoreIndexTo = bindingContext.serializablePropertiesFor(superClass.descriptor).size // call super.writeSelf - val superWriteSelfF = superClass.findWriteSelfMethod() + var superWriteSelfF = superClass.findWriteSelfMethod() + if (superWriteSelfF != null) { + // Workaround for incorrect DeserializedClassDescriptor on JVM (see MemberDeserializer#getDispatchReceiverParameter): + // Because Kotlin does not have static functions, descriptors from other modules are deserialized with dispatch receiver, + // even if they were created without it + if (superWriteSelfF.dispatchReceiverParameter != null) { + superWriteSelfF = compilerContext.copiedStaticWriteSelf.getOrPut(superWriteSelfF) { + superWriteSelfF!!.deepCopyWithSymbols(initialParent = superClass).also { it.dispatchReceiverParameter = null } + } + } + val args = mutableListOf(irGet(objectToSerialize), irGet(localOutput), irGet(localSerialDesc)) - val typeArgsForParent = serializableDescriptor.typeConstructor.supertypes.single { it.toClassDescriptor?.isInternalSerializable == true }.arguments + val typeArgsForParent = + serializableDescriptor.typeConstructor.supertypes.single { it.toClassDescriptor?.isInternalSerializable == true }.arguments val parentWriteSelfSerializers = typeArgsForParent.map { arg -> val genericIdx = serializableDescriptor.defaultType.arguments.indexOf(arg).let { if (it == -1) null else it } val serial = findTypeSerializerOrContext(serializableDescriptor.module, arg.type) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt index 91e94341a54..ac3aa742cb1 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt @@ -10,9 +10,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.runOnFilePostfix import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid @@ -23,6 +21,7 @@ import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializableCompa import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializableIrGenerator import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver +import java.util.concurrent.ConcurrentHashMap /** * Copy of [runOnFilePostfix], but this implementation first lowers declaration, then its children. @@ -44,6 +43,8 @@ fun ClassLoweringPass.runOnFileInOrder(irFile: IrFile) { class SerializationPluginContext(baseContext: IrPluginContext, val metadataPlugin: SerializationDescriptorSerializerPlugin?) : IrPluginContext by baseContext { lateinit var serialInfoImplJvmIrGenerator: SerialInfoImplJvmIrGenerator + + internal val copiedStaticWriteSelf: MutableMap = ConcurrentHashMap() } private class SerializerClassLowering(