Description
Describe the bug
I have a class using a self-recursive generic bound as follows, and elsewhere in my code I would like to serialize a usage of this class where the type parameter is projected. In the actual example in my code-base, the class with the self-recursive generic bound is actually a sealed class
-- essentially an enum, actually, as all instances are object
s, so it should be pretty easy to serialize. However, Kotlin seems to run into a stack overflow on such classes when the generic parameter is star projected.
To Reproduce
Minimal non-working example:
@Serializable
class MinimalNonWorkingExample<X: MinimalNonWorkingExample<X>>
@Serializable
data class MinimalNonWorkingExamplePart2(
val test: MinimalNonWorkingExample<*>
)
Trying to compile this leads the following stack trace:
e: java.lang.StackOverflowError
at org.jetbrains.kotlin.types.TypeSubstitutor.substituteTypeArguments(TypeSubstitutor.java:365)
at org.jetbrains.kotlin.types.TypeSubstitutor.substituteCompoundType(TypeSubstitutor.java:350)
at org.jetbrains.kotlin.types.TypeSubstitutor.unsafeSubstitute(TypeSubstitutor.java:285)
at org.jetbrains.kotlin.types.TypeSubstitutor.substituteTypeArguments(TypeSubstitutor.java:371)
at org.jetbrains.kotlin.types.TypeSubstitutor.substituteCompoundType(TypeSubstitutor.java:350)
at org.jetbrains.kotlin.types.TypeSubstitutor.unsafeSubstitute(TypeSubstitutor.java:285)
at org.jetbrains.kotlin.types.TypeSubstitutor.substituteWithoutApproximation(TypeSubstitutor.java:162)
at org.jetbrains.kotlin.types.TypeSubstitutor.substitute(TypeSubstitutor.java:147)
at org.jetbrains.kotlin.types.TypeSubstitutor.substitute(TypeSubstitutor.java:140)
at org.jetbrains.kotlin.types.TypeUtils.createSubstitutedSupertype(TypeUtils.java:263)
at org.jetbrains.kotlin.types.TypeUtils.getImmediateSupertypes(TypeUtils.java:249)
at org.jetbrains.kotlin.types.TypeUtils.collectAllSupertypes(TypeUtils.java:271)
at org.jetbrains.kotlin.types.TypeUtils.getAllSupertypes(TypeUtils.java:284)
at org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt.supertypes(TypeUtils.kt:54)
at org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker.checkSerializerNullability(SerializationPluginDeclarationChecker.kt:402)
at org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker.checkType(SerializationPluginDeclarationChecker.kt:344)
at org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker.checkTypeArguments(SerializationPluginDeclarationChecker.kt:307)
at org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker.checkType(SerializationPluginDeclarationChecker.kt:345)
at org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker.checkTypeArguments(SerializationPluginDeclarationChecker.kt:307)
at org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker.checkType(SerializationPluginDeclarationChecker.kt:345)
at org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker.checkTypeArguments(SerializationPluginDeclarationChecker.kt:307)
at org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker.checkType(SerializationPluginDeclarationChecker.kt:345)
at org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker.checkTypeArguments(SerializationPluginDeclarationChecker.kt:307)
...
Expected behavior
The plugin should either generate a valid serializer, or at the very least warn me that this use case of generics is not supported -- possibly also directing me to an alternative way of defining a working serializer for the class.
Environment
- Kotlin version: 1.5.31
- Library version: kotlinx-serialization-json:1.3.0 (plugin version is the same as Kotlin version)
- Kotlin platforms: JVM
- Gradle version: 6.8
Note: Possibly related: #1501