# How prevent type inference?

**URL:** <https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140>\
**Category:** Language Design\
**Created:** [June 13, 2018, 12:56pm UTC](https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140 "2018-06-13T12:56:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![zcb7kbgxtgjt](https://avatars.discourse-cdn.com/v4/letter/z/e47774/32.png) [@zcb7kbgxtgjt](https://discuss.kotlinlang.org/u/zcb7kbgxtgjt)\
**Post date:** [June 13, 2018, 12:56pm UTC](https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140/1 "2018-06-13T12:56:58Z")

</div>

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:

```auto
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?

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [June 13, 2018, 1:59pm UTC](https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140/2 "2018-06-13T13:59:06Z")

</div>

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

> [@Inference with unexpected outcome](https://discuss.kotlinlang.org/t/inference-with-unexpected-outcome/7997/6):
>
> In Java Iterable interface is invariant, and in Kotlin it’s covariant. Usually Java methods taking Iterable are declared as: private static \<T\> void fun(Iterable\<? extends T\> it, T value) { } And that allows calling it the same way as in Kotlin: fun(it, 5); where it is a List\<String\>. Casting Iterable\<Int\> to Iterable\<Any\> is an upcast in Kotlin, same as casting Int to Any. Do you feel that the latter should be prohibited? As to why Any is inferred for T there — it’s the same reason why we…

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.

---

<div class="post-metadata">

**Author:** ![zcb7kbgxtgjt](https://avatars.discourse-cdn.com/v4/letter/z/e47774/32.png) [@zcb7kbgxtgjt](https://discuss.kotlinlang.org/u/zcb7kbgxtgjt)\
**Post date:** [June 13, 2018, 2:23pm UTC](https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140/3 "2018-06-13T14:23:37Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![zcb7kbgxtgjt](https://avatars.discourse-cdn.com/v4/letter/z/e47774/32.png) [@zcb7kbgxtgjt](https://discuss.kotlinlang.org/u/zcb7kbgxtgjt)\
**Post date:** [June 13, 2018, 3:03pm UTC](https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140/4 "2018-06-13T15:03:49Z")

</div>

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:

```auto
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:

```auto
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)
    */
}

```

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [June 13, 2018, 3:05pm UTC](https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140/5 "2018-06-13T15:05:19Z")

</div>

That is amazing 😄 love it

---

<div class="post-metadata">

**Author:** ![stangl0r](https://avatars.discourse-cdn.com/v4/letter/s/58f4c7/32.png) [@stangl0r](https://discuss.kotlinlang.org/u/stangl0r)\
**Post date:** [June 21, 2018, 9:38pm UTC](https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140/6 "2018-06-21T21:38:17Z")

</div>

Maybe I’m wrong, but that looks like a dirty hack to me.

Is this supposed to be done? And why would one even need `@Exact`? I want my compilers to be always exact!

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [June 21, 2018, 10:14pm UTC](https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140/7 "2018-06-21T22:14:32Z")

</div>

> [@stangl0r](#):
>
> Maybe I’m wrong, but that looks like a dirty hack to me.

I guess it is, so I would not rely on this in production code.

> [@stangl0r](#):
>
> And why would one even need `@Exact` ? I want my compilers to be always exact!

The `@Exact` annotation means, that the compiler will only accept arguments with the exact type.

```kotlin
fun <A, B: List<A>>foo(a: A, list: B) {}

foo(1, listOf(1, 2, 3)) // this should always work
foo(1, lisOf(true, false)) // this also works: B is now List<Any> and A is Any

fun <A> bar(a: A, list: List<A>) {} // has the same results

```

With the `@Exact` annotation the kotlin standard library forces this to work in a way where when a is an integer the list also needs to be a list of integers.  
That way you can create functions like contains.

> <https://github.com/JetBrains/kotlin/blob/9838ed8e14513a0b0d4e786e67d9f2ea85020f78/libraries/stdlib/common/src/generated/_Collections.kt#L63-L67>

Ok it uses another internal annotation but the idea is the same. This is also the reason I guess why they are still internal. They are not that obvious to use and the design for them is not yet settled enough to make them public.

---

<div class="post-metadata">

**Author:** ![stangl0r](https://avatars.discourse-cdn.com/v4/letter/s/58f4c7/32.png) [@stangl0r](https://discuss.kotlinlang.org/u/stangl0r)\
**Post date:** [July 6, 2018, 3:42pm UTC](https://discuss.kotlinlang.org/t/how-prevent-type-inference/8140/8 "2018-07-06T15:42:45Z")

</div>

Interesting.  
Thanks for the explanation!
