# Generic type bound on extension method silently coerced to Any

**URL:** https://discuss.kotlinlang.org/t/generic-type-bound-on-extension-method-silently-coerced-to-any/1453
**Category:** Language Design
**Created:** [February 7, 2016, 4:19pm UTC](https://discuss.kotlinlang.org/t/generic-type-bound-on-extension-method-silently-coerced-to-any/1453 "2016-02-07T16:19:38Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![norswap](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/norswap/32/1737_2.png) [@norswap](https://discuss.kotlinlang.org/u/norswap)
#### Post date: [February 7, 2016, 4:19pm UTC](https://discuss.kotlinlang.org/t/generic-type-bound-on-extension-method-silently-coerced-to-any/1453/1 "2016-02-07T16:19:38Z")

</div>

To my surprise I found out I could write this in Kotlin:

```
class P<out T>
fun <T> P<T>.ext(e: T) {}
val x = P<String>() 
x.ext(3)

```

Normally, you can’t write methods parameterized by an `out` type, lest you end up treating a subtype of a type `T` as another of its subtypes:

```
open class A
open class B: A()
open class C: A()
class P<out T> {
    private var x: T? = null
    fun take(e: T) { x = e } // rejected by compiler
}
// if it were accepted:
val p: P<A> = P<B>()
p.take(C()) // oops I've written a C into a B var!

```

Kotlin apparently enforces the same restriction on extension methods, but instead of rejecting method `ext` above, it silently transforms the `T` bound into an `Any`, which is why it won’t complain when you pass an `Int` to a function you thought would take `String`s. You can’t do anything harmful with the `Int` inside the body of `ext`: it is treated a type `Any`.

So at the very least, the user should be forced to write `Any` instead of having its bound silently coerced to `Any`.

**But** , extension methods are not regular methods, they are not dynamically dispatched. This means that you can actually never fuck up by having your `ext` parameter being treated as type `T` inside the method: the compiler already prevents these problems by forbidding _real_ methods of `out T` classes to take parameters of type `T`.

Is there more to it than meets the eye, or should this limitation be lifted?

---

<div class="post-metadata">

### Author: ![abreslav](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/abreslav/32/8279_2.png) [@abreslav](https://discuss.kotlinlang.org/u/abreslav)
#### Post date: [February 14, 2016, 12:04pm UTC](https://discuss.kotlinlang.org/t/generic-type-bound-on-extension-method-silently-coerced-to-any/1453/2 "2016-02-14T12:04:41Z")

</div>

I can’t say I can follow this part:

> [@norswap](#):
>
> Kotlin apparently enforces the same restriction on extension methods, but instead of rejecting method ext above, it silently transforms the T bound into an Any, which is why it won’t complain when you pass an Int to a function you thought would take Strings. You can’t do anything harmful with the Int inside the body of ext: it is treated a type Any.

There’s no such limitation on extension functions, because they are not members. From the checker’s point of view,

```auto
fun <T> P<T>.ext(e: T)

```

is the same as

```auto
fun <T> ext(_this: P<T>, e: T)

```

Could you clarify your question?

---

<div class="post-metadata">

### Author: ![norswap](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/norswap/32/1737_2.png) [@norswap](https://discuss.kotlinlang.org/u/norswap)
#### Post date: [February 14, 2016, 1:51pm UTC](https://discuss.kotlinlang.org/t/generic-type-bound-on-extension-method-silently-coerced-to-any/1453/3 "2016-02-14T13:51:01Z")

</div>

Mighty good point. I feel dumb having overlooked that.

Okay, so followup questions.

* * *

1. How can I get the inference mechanic for extension methods, but for member methods.

To take a concrete example, how do I translate what follows to make the extension function into a member function?

```
sealed class Maybe<out T>
{
    class Some<T>(val value: T): Maybe<T>()
    object None : Maybe<Nothing>()
}

inline fun <T> Maybe<T>.getOr(f: () -> T): T = when (this) {
    is Some<T> -> this.value
    is None -> f()
}

```

i.e. what I want is something like this:

```
sealed class Maybe<out T>
{
    ...
    fun <R super T> getOr(e: R): R = when (this) { // imaginary super syntax
        is Some<T> -> this.value
        is None -> e
    }
}

```

So I want the return type of the method to be inferred to the lowest common super-type of `e` and the static type of the parameter `T` at the use site (i.e. just what the extension method does).

* * *

1. How to put a constraint that I want a type parameter to be a subtype of the bound. So if I take back my initial example:

How can I make sure that this fails (because `Int` cannot be a subtype of `String`)?

To be clear, I know that this code is actually safe, I just want to add this extra restriction to catch potential errors. I also know this would be completely circumventable by assigning my `P<String>` to a `P<Any>`. I just want a more “warning” kind of check.
