serializer(KType) doesn't find types with custom serializers
Describe the bug
serializer(KType) and serializerOrNull(KType) find types annotated with @Serializable but not types annotated with @Serializable(with = …)
To Reproduce Playground link: https://pl.kotl.in/GPVEn019Z
Expected behavior
The behavior of serializer(KType) should be identical for any class annotated with @Serializable, whether or not it uses with =.
Environment
- Kotlin version: 2.2.21
- Library version: 1.9.0
- Kotlin platforms:
- All non-JVM platforms
- In my own project, this bug doesn't display itself on the JVM. However, the minimal reproducer I linked above on the Kotlin Playground does exhibit the bug, so I'm not sure what's going on.
- Gradle version: 9.2, but I don't think it matters
I've had a bit of a look at it. I'm not sure why the playground version doesn't work. The actual implementation of the runtime lookup works as follows:
Details
### JVM Find (using reflection) the function `serializer` (with a correct number of `KSerializer` arguments) in the (potentially named) companion object. (note that this would mean doing this by hand would work, but the plugin fails if the annotation is present and the function too).
JS
Dynamically invoke the serializer function on the Companion member of the type object.
Native and WASM
Uses associated objects (part of the standard library) to store either the serializer or a factory for instantiating it.
Actually running the test (SerializersLookupNamedCompanionTest) in the library test suite (copying in your C implementation) works as expected. This looks more like an issue either with the playground or the use of an inconsistent or older version of the library.
This looks like a weird Kotlin Playground bug. If you use this code elsewhere, it works as expected on JVM. Did you say it doesn't on Native?
On my own project, I do see it work correctly on the JVM. However, I see the same behavior as the playground on JS, WasmJS, Wasm WASI and LinuxX64.
It may well be related to https://github.com/Kotlin/kotlinx.serialization/issues/2382: non-generic serializers on JS can't be classes and must be objects.
This bug just caught me out again for possibly the third time. Would be great if a meaningful error message could be triggered in such cases.
@SimonCJacobs In this case the serializer is an object so that cannot be the issue. Also, the code works when put into the library test suite, so there is something more to the issue.
Oh wow. It is #2382. I just replaced the serializer in the real-world project by an object and it fixes the issue. Thankfully, in my case, it's fine to make the serializer an object.
I guess this leaves this issue as tracking for the Playground behavior itself, but at least I have a solution for the real world. Thanks!