The following is a question on generic serializati...
# serialization
u
The following is a question on generic serialization that I raised on SO with a singe reply suggesting it might be a bug. I'm not so sure, but maybe someone here can give me a hint to understand the inner workings that I'm currently struggling to understand. I am trying to serialize a type hierarchy (
BaseContainer
, see example) with a restricted generic type parameter. The generic type itself is a sealed hierarchy (
Element
). To my understanding, serializers should be automatically generated for this sealed
Element
hierarchy. However, I am not able to use these auto-generated serializers for the parameterized
BaseContainer
hierarchy.
Copy code
// This is the sealed hierarchy, for which serializers should be auto-generated:
@Serializable
sealed interface Element

@Serializable
data class CountElement(val elementCount: Int) : Element

@Serializable
data class FlagElement(val flag: Boolean) : Element


// This is a class hierarchy with generic type parameter E restricted to Element:
@Serializable
sealed interface BaseContainer<out E : Element>

@Serializable
data class ElementContainer<out E : Element>(
    val element: E
) : BaseContainer<E>


// This is the serializers module to enable polymorphic serialization of the generic container classes
val containerSerializerModule = SerializersModule {
    polymorphic(BaseContainer::class) {
        subclass(ElementContainer.serializer(Element.serializer())) // alt: serializer<Element>()
    }
// Commented out, so the auto-generated serializers of the sealed Element hierarchy are used.
//    polymorphic(Element::class) {
//        subclass(FlagElement::class)
//        subclass(CountElement::class)
//    }
}


// And here is a test to illustrate the problem
internal class GenericSerializerTest {
    val json = Json { serializersModule = containerSerializerModule }

    @Test
    fun `polymorphically serialize and deserialize an element container`() {
        val container = ElementContainer(FlagElement(false))
        val containerJson = json.encodeToString(serializer<BaseContainer<Element>>(), container)
        val containerDeserialized = json.decodeFromString(serializer<BaseContainer<Element>>(), containerJson)
        assertEquals(container, containerDeserialized)
    }
}
When I run the above test, I get the following error message:
kotlinx.serialization.SerializationException: Serializer for subclass 'FlagElement' is not found in the polymorphic scope of 'Element'.
However, when I manually define the polymorphic serializer for the
Element
hierarchy (uncomment the lines above), the test passes. Why is that? It seems that the auto-generated serializer is not used when I define the polymorphic serialization for the container. Is this expected? Why?