Kotlin Number class mystery

Well, if it was in standard library then it would not be the problem, because annotations from kotlin.internal could be used to enforce specific behavior of type inference, e.g.

package kotlin.internal

@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.BINARY)
internal annotation class Exact

@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.BINARY)
internal annotation class NoInfer

// Hack above - you can copy Kotlin's internal annotations to your module
// to use them in your module. Not recommended for production ;)

fun <T: Number> plus(a: @Exact T, b: @Exact T): Int {

    return a.toInt() + b.toInt()
}

fun <T: Number> @Exact T.plus2(b: @Exact T): Int {

    return this.toInt() + b.toInt()
}

fun <T: Number> plus3(a: T, b: @NoInfer T): Int {

    return a.toInt() + b.toInt()
}

fun <T: Number> T.plus4(b: @NoInfer T): Int {

    return this.toInt() + b.toInt()
}

fun main() {
    val int: Int = 5
    val double: Double = 3.7

    plus(int, int)
    plus(double, double)
    plus(int, double) // errors for both arguments - because parameters must have equal types
    
    int.plus2(int)
    double.plus2(double)
    int.plus2(double) // errors for both arguments - because parameters must have equal types

    plus3(int, int)
    plus3(double, double)
    plus3(int, double) // error for second argument only - because inference takes into account only first parameter
    
    int.plus4(int)
    double.plus4(double)
    int.plus4(double) // error for second argument only - because inference takes into account only first parameter
}

However, as these annotations are internal, I believe they cannot really be used on an operator fun in Number, because then it cannot be subclassed outside of the standard library.

As a bit on a side note, it would be nice for these annotations to be made public or promoted to some language construct, because they could be really helpful for designing APIs using generics. I guess it could be especially useful for library writers.

3 Likes