From 36484abb50296eaa0af1d99e8a0df9e0b236701f Mon Sep 17 00:00:00 2001 From: "Sergey.Shanshin" Date: Wed, 1 Sep 2021 23:04:11 +0300 Subject: [PATCH] Fix call of `serializer` for parametrized sealed and abstract classes Fixes Kotlin/kotlinx.serialization#1646 --- .../compiler/backend/ir/GeneratorHelpers.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt index 4f478239f7bd6..1a8c88a0f0dcb 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt @@ -1126,13 +1126,23 @@ interface IrBuilderExtension { val serializerProviderFunction = companionClass.declarations.singleOrNull { it is IrFunction && it.name == SerialEntityNames.SERIALIZER_PROVIDER_NAME && it.valueParameters.size == baseClass.typeParameters.size } ?: return null + + val adjustedArgs: List = + if (baseClass.descriptor.isSealed() || baseClass.descriptor.modality == Modality.ABSTRACT) { + val serializer = findStandardKotlinTypeSerializer(baseClass.module, context.irBuiltIns.unitType.toKotlinType())!! + // workaround for sealed and classes - the `serializer` function expects non-null serializers, but does not use them, so serializers of any type can be passed + List(baseClass.typeParameters.size) { irGetObject(serializer) } + } else { + args + } + with(serializerProviderFunction as IrFunction) { - // Note that [args] and [typeArgs] may be unused if we short-cut to e.g. SealedClassSerializer + // Note that [typeArgs] may be unused if we short-cut to e.g. SealedClassSerializer return irInvoke( irGetObject(companionClass), symbol, typeArgs.takeIf { it.size == typeParameters.size }.orEmpty(), - args.takeIf { it.size == valueParameters.size }.orEmpty() + adjustedArgs.takeIf { it.size == valueParameters.size }.orEmpty() ) } }