Kotlin type-safe queries and updates are not type-safe at all #4798
Labels
in: kotlin
Kotlin support
status: blocked
An issue that's blocked on an external project change
status: waiting-for-triage
An issue we've not yet triaged
Hi,
spring-data-mongodb supports in Kotlin typed queries and recently introduced with my help typed updates too (#3028). While this API is handy because there's no need to keep field names in constants, it has one hidden drawback or bug - it's not type-safe at any manner. Even though docs (that one I wrote too) and its construction suggest it undeniably should be.
Problem explanation
I will show it by an example:
isEqualTo
infix fun is defined in a way that as I said undeniably suggests that it should be type-safe:Why the type of value is not checked properly by a compiler? The culprit is declaration-site variance Kotlin mechanism. And especially the fact that
KProperty
interface has its generic type marked without
variance annotation:Possible solutions
While the problem seems to be complicated and rather lies on the Kotlin language side, there is a simple (but tricky) solution. JetBrains team has internal annotation (in kotlin.internal package)
@OnlyInputTypes
designed for cases like this. The solution would be as simple as just using it on a generic type:However, this solution has one drawback - while this annotation is in
kotlin.internal package
it can't be used directly outside the Kotlin project. There are two workarounds to use it, but both are tricky.First:
@OnlyInputTypes
annotation which is identical to an original one, ie. the same package, the same name-Xallow-kotlin-package
compiler arg to bypassOnly the Kotlin standard library is allowed to use the 'kotlin' package
errorSecond:
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
before each usage or on the whole file:@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
Both of them are rather workarounds with some drawbacks. Another drawback of fixing this bug is the fact that it breaks the backward compatibility of this API - some code will stop compiling (but let's say very error-prone code that uses this API in the wrong way)
I have prepared code with these solutions and can post PRs later on.
Moreover, I did some research and saw that ex. KMongo uses
@OnlyInputTypes
too: Litote/kmongo@413539eWhat are your thoughts about that? Do you think that introducing a fix with
@OnlyInputTypes
would be OK?Resources
https://youtrack.jetbrains.com/issue/KT-13198
https://discuss.kotlinlang.org/t/restrict-type-by-receiver/5492
https://kotlinlang.org/docs/generics.html
https://stackoverflow.com/questions/54779553/kotlin-generic-constraints-require-param-to-be-of-same-type-as-other <-- there is workaround with wrapping KProperty into own type, but I can't see a way to use it in a clean and seamless way
The text was updated successfully, but these errors were encountered: