# Multiple invariant parameters leads to type compilation failure?

**URL:** <https://discuss.kotlinlang.org/t/multiple-invariant-parameters-leads-to-type-compilation-failure/20632>\
**Category:** Language Design\
**Created:** [January 22, 2021, 7:38pm UTC](https://discuss.kotlinlang.org/t/multiple-invariant-parameters-leads-to-type-compilation-failure/20632 "2021-01-22T19:38:16Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![peter](https://avatars.discourse-cdn.com/v4/letter/p/278dde/32.png) [@peter](https://discuss.kotlinlang.org/u/peter)\
**Post date:** [January 22, 2021, 7:38pm UTC](https://discuss.kotlinlang.org/t/multiple-invariant-parameters-leads-to-type-compilation-failure/20632/1 "2021-01-22T19:38:16Z")

</div>

```
interface Animal
class Cat: Animal
class Dog: Animal

data class BoundedInvariant<T: Animal>(val thing: T)
data class SecondBoundedInvariant<T: Animal>(val thing: T)

fun <T: Animal>pet(invariant: BoundedInvariant<T>) {
    println(invariant.thing::class)
}
fun <T: Animal>petBoth(secondBoundedInvariant: SecondBoundedInvariant<T>, invariant: BoundedInvariant<T>) {
    println(invariant.thing::class)
    println(secondBoundedInvariant.thing::class)
}

val animalSet = mapOf(
    BoundedInvariant(Dog()) to SecondBoundedInvariant(Dog()),
    BoundedInvariant(Cat()) to SecondBoundedInvariant(Cat()),
)

fun main() {
    animalSet
        .forEach {
            pet(it.key)
            //petBoth(it.value, it.key)
        }
}

```

Why does `pet()` compile but `petBoth()` does not? It fails with `Type mismatch: inferred type is Animal but CapturedType(out Animal) was expected`

I understand that `petBoth()` parameters are not declared with T as covariant but why does it work in the case of `pet()`?  
Does it fail in the case of `petBoth()` because the compiler cannot prove they are the same T for each iteration of `forEach`?  
Ok let’s explore that theory a bit further:

```
data class Container<T: Animal>(val a: BoundedInvariant<T>, val b: SecondBoundedInvariant<T>)
val a = Container(BoundedInvariant(Dog()), SecondBoundedInvariant(Cat()))

```

This compiles just fine?? This is very unexpected and does not compile in Scala as expected: [Scastie - An interactive playground for Scala.](https://scastie.scala-lang.org/eTxYlFFJSBylpotohogbrA)

How can the invocation of `petBoth()` be fixed without changing those parameters to covariant (undesirable)?

---

<div class="post-metadata">

**Author:** ![luhtonen](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/luhtonen/32/6825_2.png) [@luhtonen](https://discuss.kotlinlang.org/u/luhtonen)\
**Post date:** [January 24, 2021, 10:59am UTC](https://discuss.kotlinlang.org/t/multiple-invariant-parameters-leads-to-type-compilation-failure/20632/2 "2021-01-24T10:59:17Z")

</div>

In this case `it.value` and `it.key` are of type `out Animal` but your function expects `Animal` type. Just change your function parameter declaration like this:

```kotlin
fun <T: Animal>petBoth(secondBoundedInvariant: SecondBoundedInvariant<out T>, invariant: BoundedInvariant<out T>) {
    println(invariant.thing::class)
    println(secondBoundedInvariant.thing::class)
}

```

Or you can change the declaration of invariant data classes:

```kotlin
data class BoundedInvariant<out T: Animal>(val thing: T)
data class SecondBoundedInvariant<out T: Animal>(val thing: T)

```

---

<div class="post-metadata">

**Author:** ![christophels](https://avatars.discourse-cdn.com/v4/letter/c/7feea3/32.png) [@christophels](https://discuss.kotlinlang.org/u/christophels)\
**Post date:** [January 25, 2021, 8:15am UTC](https://discuss.kotlinlang.org/t/multiple-invariant-parameters-leads-to-type-compilation-failure/20632/3 "2021-01-25T08:15:02Z")

</div>

I think Peter is right,  
With its definition of BoundedInvariant & SecondBoundedInvariant classes (without covariant ‘out’ word)

The code

> [@peter](#):
>
> ```auto
> data class Container<T: Animal>(val a: BoundedInvariant<T>, val b: SecondBoundedInvariant<T>)
> val a = Container(BoundedInvariant(Dog()), SecondBoundedInvariant(Cat()))
> 
> ```

Should not compile

---

<div class="post-metadata">

**Author:** ![Varia](https://avatars.discourse-cdn.com/v4/letter/v/b9e5f3/32.png) [@Varia](https://discuss.kotlinlang.org/u/Varia)\
**Post date:** [January 25, 2021, 5:46pm UTC](https://discuss.kotlinlang.org/t/multiple-invariant-parameters-leads-to-type-compilation-failure/20632/4 "2021-01-25T17:46:35Z")

</div>

I would guess that the reason it compiles is because the compiler infers the following type arguments:  
`Container<Animal>(BoundedInvariant<Animal>(Dog()), SecondBoundedInvariant<Animal>(Cat()))`
