You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
Given a serializable data class containing 2 value class fields (one having a primitive type like int, the other with a structure), both fields are serialized using encodeSerializableElement instead of encodeInlineElement, forcing primitive values to be boxed, and also doesn't follow the expected as said in the docs:
/** * [...] * * Namely, for the `@Serializable @JvmInline value class MyInt(val my: Int)`, * and `@Serializable class MyData(val myInt: MyInt)` the following sequence is used: * ``` * thisEncoder.encodeInlineElement(MyData.serializer.descriptor, 0).encodeInt(my) * ``` * * This method provides an opportunity for the optimization to avoid boxing of a carried value * and its invocation should be equivalent to the following: * ``` * thisEncoder.encodeSerializableElement(MyData.serializer.descriptor, 0, MyInt.serializer(), myInt) * ``` * * [...] * * Note that this function returns [Encoder] instead of the [CompositeEncoder] * because value classes always have the single property. * * [...]*/publicfunencodeInlineElement(
descriptor:SerialDescriptor,
index:Int
): Encoder
To Reproduce
classReproduceBug {
@Test
funstructureContainingValueClassFieldsShouldCall_encodeInlineElement() {
val value =Structure(
BooleanValue(true),
BooleanValue(false),
SubStructureValue(SubStructure(42)),
)
val encoder =MyEncoder()
encoder.encodeSerializableValue(Structure.serializer(), value)
assertEquals(actual = encoder.encodeInlineElementCalled, expected =true)
}
@Serializable
data classStructure(
valprimitiveField:BooleanValue,
valprimitiveNullableField:BooleanValue?,
valfield:SubStructureValue,
)
@Serializable
@JvmInline
value classBooleanValue(valvalue:Boolean)
@Serializable
@JvmInline
value classSubStructureValue(valvalue:SubStructure)
@Serializable
data classSubStructure(
valsubField:Int,
)
classMyEncoder: AbstractEncoder() {
var encodeInlineElementCalled =falseoverrideval serializersModule:SerializersModule
get() =EmptySerializersModule()
// I removed the `final` modifier in the `AbstractEncoder` to allow overriding it for reproducing the bug and avoid the useless noise of all the other overridesoverridefunencodeInlineElement(descriptor:SerialDescriptor, index:Int): Encoder {
encodeInlineElementCalled =truereturnsuper.encodeInlineElement(descriptor, index)
}
overridefunencodeValue(value:Any) {
}
}
}
And here is the generated serializer (only the interesting part) retrieved using Kotlin bytecode IDEA tooling:
Describe the bug
Given a serializable data class containing 2 value class fields (one having a primitive type like
int
, the other with a structure), both fields are serialized usingencodeSerializableElement
instead ofencodeInlineElement
, forcing primitive values to be boxed, and also doesn't follow the expected as said in the docs:To Reproduce
And here is the generated serializer (only the interesting part) retrieved using
Kotlin bytecode
IDEA tooling:Expected behavior
Should call
encodeInlineElement
and generate the following (not sure for the nullable value class' field):Environment
6886e345e06a48c4b0f9014bf85047a1e2f96a29
)The text was updated successfully, but these errors were encountered: