How prevent type inference?


#1

Sorry for my English. I would like to use function test with parameter value exactly type of some property. But it declared as out R, and compiler inference type to Any if types is distinct.
For example:

open class Foo(var barInt: Int)

// public interface KProperty1<T, out R> : KProperty<R>, (T) -> R

fun <E : Foo, T> test(field: kotlin.reflect.KProperty1<E, T>, value: T) {}

fun main(args: Array<String>) {
    test(Foo::barInt, 12345) // ok
    test(Foo::barInt, "NotInt") // ok! Type T is Any, but I would like compile error
}

What can be done?


#2

As far as I know it is not possible yet. There are a few internal annotations used for this in the standard library but they are not publicly usable. There is another discussion with the same problem here where Ilya explains this


TL;DR of it: they know that this is useful but have not made it public yet because they are not sure of the design of those annotations.


#3

I will wait. Thank you very much for your answer.


#4

I found temporary workaround for those who are ready to possible future refactoring.
It may be kotlin compiler or ide bug:

  1. Create file kotlin/internal/Annotations.kt in source root of your project:
package kotlin.internal

@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.BINARY)
annotation class Exact
  1. Add compiler command line parameter: -Xallow-kotlin-package
  2. Using this annotation:
import kotlin.internal.Exact

open class Foo(val barInt: Int)

// public interface KProperty1<T, out R> : KProperty<R>, (T) -> R

fun <E : Foo, T> test(field: kotlin.reflect.KProperty1<E, @Exact T>, value: T): T = TODO()


fun main(args: Array<String>) {
    test(Foo::barInt, 123) // ok
    test(Foo::barInt, "NotInt") // expected compile error:
    /*
        Error:(13, 5) Kotlin: Type inference failed: Cannot infer type parameter T in fun <E : Foo, T> test(field: KProperty1<E, T>, value: T): T
        None of the following substitutions
        (KProperty1<Foo, Int>,Int)
        (KProperty1<Foo, String>,String)
        can be applied to
        (KProperty1<Foo, Int>,String)
    */
}

Inference with unexpected outcome
#5

That is amazing :smile: love it