interface In<in T : Any?> {

}

inline fun <reified T : Any?> In<T>.isT(): Boolean {
  return <this> is T
}

inline fun <reified T : Any?> In<T>.asT() {
  <this> as T /*~> Unit */
}

fun <S : Any?> sel(x: S, y: S): S {
  return x
}

interface A {

}

interface B {

}

interface A1 : A {

}

interface A2 : A {

}

interface Z1 : A, B {

}

interface Z2 : A, B {

}

fun testInIs1(x: In<A>, y: In<B>): Boolean {
  return sel<In<Nothing>>(x = x, y = y).isT<Any>()
}

fun testInIs2(x: In<Z1>, y: In<Z2>): Boolean {
  return sel<In<Nothing>>(x = x, y = y).isT<Any>()
}

fun testInIs3(x: In<A1>, y: In<A2>): Boolean {
  return sel<In<Nothing>>(x = x, y = y).isT<A>()
}

fun testInAs1(x: In<A>, y: In<B>) {
  return sel<In<Nothing>>(x = x, y = y).asT<Any>()
}

fun testInAs2(x: In<Z1>, y: In<Z2>) {
  return sel<In<Nothing>>(x = x, y = y).asT<Any>()
}

fun testInAs3(x: In<A1>, y: In<A2>) {
  return sel<In<Nothing>>(x = x, y = y).asT<A>()
}
