Unbox inline class parameter of lambda if underlying type is Any or Any?

The inline class is boxed when we pass it as lambda argument, now we
unbox it. If the underlying type is not Any or Any?, bridge method does
the unboxing.

 #KT-32450 Fixed
 #KT-39923 Fixed
 #KT-32228 Fixed
 #KT-40282 Fixed
This commit is contained in:
Ilmir Usmanov
2020-10-20 19:38:06 +02:00
parent 752f6d8f72
commit a775fa195b
59 changed files with 4371 additions and 0 deletions
@@ -0,0 +1,49 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
it.value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
fun interface FunIFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: FunIFace<T, R>): R {
return f.call(value)
}
inline class IC(val value: Any) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<Int>(IC(40)) + 2
if (res != 42) return "FAIL 1: $res"
res = extension<Int>(IC(40)) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(40)) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(40)) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,49 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
it.value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun interface FunIFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: FunIFace<T, R>): R {
return f.call(value)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
inline class IC(val value: Any?) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<Int>(IC(40)) + 2
if (res != 42) "FAIL 1 $res"
res = extension<Int>(IC(40)) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(40)) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(40)) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,53 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
(it.value as FooHolder).value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun <T> IC.extensionValue(): T = (value as FooHolder).value as T
fun <T> normalValue(ic: IC): T = (ic.value as FooHolder).value as T
fun interface FunIFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: FunIFace<T, R>): R {
return f.call(value)
}
interface Foo
class FooHolder(val value: Any): Foo
inline class IC(val value: Foo): Foo {
fun <T> dispatchValue(): T = (value as FooHolder).value as T
}
fun box(): String {
var res = underlying<Int>(IC(FooHolder(40))) + 2
if (res != 42) return "FAIL 1: $res"
res = extension<Int>(IC(FooHolder(40))) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(FooHolder(40))) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(FooHolder(40))) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,53 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
(it.value as FooHolder).value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun <T> IC.extensionValue(): T = (value as FooHolder).value as T
fun <T> normalValue(ic: IC): T = (ic.value as FooHolder).value as T
fun interface FunIFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: FunIFace<T, R>): R {
return f.call(value)
}
interface Foo
class FooHolder(val value: Any): Foo
inline class IC(val value: FooHolder): Foo {
fun <T> dispatchValue(): T = (value as FooHolder).value as T
}
fun box(): String {
var res = underlying<Int>(IC(FooHolder(40))) + 2
if (res != 42) return "FAIL 1: $res"
res = extension<Int>(IC(FooHolder(40))) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(FooHolder(40))) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(FooHolder(40))) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,49 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
it.value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun interface FunIFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: FunIFace<T, R>): R {
return f.call(value)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
inline class IC(val value: Int) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<Int>(IC(40)) + 2
if (res != 42) "FAIL 1: $res"
res = extension<Int>(IC(40)) + 3
if (res != 43) "FAIL 2: $res"
res = dispatch<Int>(IC(40)) + 4
if (res != 44) "FAIL 3: $res"
res = normal<Int>(IC(40)) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,21 @@
// !LANGUAGE: +InlineClasses
// WITH_RUNTIME
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
fun <T> foo(a: Result<T>): T = bar(a) {
it.getOrThrow()
}
fun interface FunIFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: FunIFace<T, R>): R {
return f.call(value)
}
fun box(): String {
val res = foo<Int>(Result.success(40)) + 2
return if (res != 42) "FAIL $res" else "OK"
}
@@ -0,0 +1,51 @@
// !LANGUAGE: +InlineClasses
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
fun <T> underlying(a: IC): T = bar(a) {
it.value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun interface FunIFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: FunIFace<T, R>): R {
return f.call(value)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
inline class IC(val value: String) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 1: $res"
res = extension<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 2: $res"
res = dispatch<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 3: $res"
res = normal<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 3: $res"
return "OK"
}
@@ -0,0 +1,45 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
it.value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
fun <T, R> bar(value: T, f: (T) -> R): R {
return f(value)
}
inline class IC(val value: Any) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<Int>(IC(40)) + 2
if (res != 42) return "FAIL 1: $res"
res = extension<Int>(IC(40)) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(40)) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(40)) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,45 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
it.value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun <T, R> bar(value: T, f: (T) -> R): R {
return f(value)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
inline class IC(val value: Any?) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<Int>(IC(40)) + 2
if (res != 42) "FAIL 1 $res"
res = extension<Int>(IC(40)) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(40)) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(40)) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,49 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
(it.value as FooHolder).value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun <T> IC.extensionValue(): T = (value as FooHolder).value as T
fun <T> normalValue(ic: IC): T = (ic.value as FooHolder).value as T
fun <T, R> bar(value: T, f: (T) -> R): R {
return f(value)
}
interface Foo
class FooHolder(val value: Any): Foo
inline class IC(val value: Foo): Foo {
fun <T> dispatchValue(): T = (value as FooHolder).value as T
}
fun box(): String {
var res = underlying<Int>(IC(FooHolder(40))) + 2
if (res != 42) return "FAIL 1: $res"
res = extension<Int>(IC(FooHolder(40))) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(FooHolder(40))) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(FooHolder(40))) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,49 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
(it.value as FooHolder).value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun <T> IC.extensionValue(): T = (value as FooHolder).value as T
fun <T> normalValue(ic: IC): T = (ic.value as FooHolder).value as T
fun <T, R> bar(value: T, f: (T) -> R): R {
return f(value)
}
interface Foo
class FooHolder(val value: Any): Foo
inline class IC(val value: FooHolder): Foo {
fun <T> dispatchValue(): T = (value as FooHolder).value as T
}
fun box(): String {
var res = underlying<Int>(IC(FooHolder(40))) + 2
if (res != 42) return "FAIL 1: $res"
res = extension<Int>(IC(FooHolder(40))) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(FooHolder(40))) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(FooHolder(40))) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,45 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a) {
it.value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun <T, R> bar(value: T, f: (T) -> R): R {
return f(value)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
inline class IC(val value: Int) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<Int>(IC(40)) + 2
if (res != 42) "FAIL 1: $res"
res = extension<Int>(IC(40)) + 3
if (res != 43) "FAIL 2: $res"
res = dispatch<Int>(IC(40)) + 4
if (res != 44) "FAIL 3: $res"
res = normal<Int>(IC(40)) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,17 @@
// !LANGUAGE: +InlineClasses
// WITH_RUNTIME
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
fun <T> foo(a: Result<T>): T = bar(a) {
it.getOrThrow()
}
fun <T, R> bar(value: T, f: (T) -> R): R {
return f(value)
}
fun box(): String {
val res = foo<Int>(Result.success(40)) + 2
return if (res != 42) "FAIL $res" else "OK"
}
@@ -0,0 +1,47 @@
// !LANGUAGE: +InlineClasses
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
fun <T> underlying(a: IC): T = bar(a) {
it.value as T
}
fun <T> extension(a: IC): T = bar(a) {
it.extensionValue()
}
fun <T> dispatch(a: IC): T = bar(a) {
it.dispatchValue()
}
fun <T> normal(a: IC): T = bar(a) {
normalValue(it)
}
fun <T, R> bar(value: T, f: (T) -> R): R {
return f(value)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
inline class IC(val value: String) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 1: $res"
res = extension<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 2: $res"
res = dispatch<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 3: $res"
res = normal<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 3: $res"
return "OK"
}
@@ -0,0 +1,49 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.value as T
})
fun <T> extension(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.extensionValue()
})
fun <T> dispatch(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.dispatchValue()
})
fun <T> normal(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = normalValue(ic)
})
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
interface IFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: IFace<T, R>): R {
return f.call(value)
}
inline class IC(val value: Any) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<Int>(IC(40)) + 2
if (res != 42) return "FAIL 1: $res"
res = extension<Int>(IC(40)) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(40)) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(40)) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,49 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.value as T
})
fun <T> extension(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.extensionValue()
})
fun <T> dispatch(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.dispatchValue()
})
fun <T> normal(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = normalValue(ic)
})
interface IFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: IFace<T, R>): R {
return f.call(value)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
inline class IC(val value: Any?) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<Int>(IC(40)) + 2
if (res != 42) "FAIL 1 $res"
res = extension<Int>(IC(40)) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(40)) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(40)) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,53 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = (ic.value as FooHolder).value as T
})
//fun <T> extension(a: IC): T = bar(a, object : IFace<IC, T> {
// override fun call(ic: IC): T = ic.extensionValue()
//})
//
//fun <T> dispatch(a: IC): T = bar(a, object : IFace<IC, T> {
// override fun call(ic: IC): T = ic.dispatchValue()
//})
//
//fun <T> normal(a: IC): T = bar(a, object : IFace<IC, T> {
// override fun call(ic: IC): T = normalValue(ic)
//})
//
//fun <T> IC.extensionValue(): T = (value as FooHolder).value as T
//
//fun <T> normalValue(ic: IC): T = (ic.value as FooHolder).value as T
interface IFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: IFace<T, R>): R {
return f.call(value)
}
interface Foo
class FooHolder(val value: Any): Foo
inline class IC(val value: Foo): Foo {
// fun <T> dispatchValue(): T = (value as FooHolder).value as T
}
fun box(): String {
var res = underlying<Int>(IC(FooHolder(40))) + 2
if (res != 42) return "FAIL 1: $res"
// res = extension<Int>(IC(FooHolder(40))) + 3
// if (res != 43) return "FAIL 2: $res"
//
// res = dispatch<Int>(IC(FooHolder(40))) + 4
// if (res != 44) return "FAIL 3: $res"
//
// res = normal<Int>(IC(FooHolder(40))) + 5
// if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,53 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = (ic.value as FooHolder).value as T
})
fun <T> extension(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.extensionValue()
})
fun <T> dispatch(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.dispatchValue()
})
fun <T> normal(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = normalValue(ic)
})
fun <T> IC.extensionValue(): T = (value as FooHolder).value as T
fun <T> normalValue(ic: IC): T = (ic.value as FooHolder).value as T
interface IFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: IFace<T, R>): R {
return f.call(value)
}
interface Foo
class FooHolder(val value: Any): Foo
inline class IC(val value: FooHolder): Foo {
fun <T> dispatchValue(): T = (value as FooHolder).value as T
}
fun box(): String {
var res = underlying<Int>(IC(FooHolder(40))) + 2
if (res != 42) return "FAIL 1: $res"
res = extension<Int>(IC(FooHolder(40))) + 3
if (res != 43) return "FAIL 2: $res"
res = dispatch<Int>(IC(FooHolder(40))) + 4
if (res != 44) return "FAIL 3: $res"
res = normal<Int>(IC(FooHolder(40))) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,49 @@
// !LANGUAGE: +InlineClasses
fun <T> underlying(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.value as T
})
fun <T> extension(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.extensionValue()
})
fun <T> dispatch(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.dispatchValue()
})
fun <T> normal(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = normalValue(ic)
})
interface IFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: IFace<T, R>): R {
return f.call(value)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
inline class IC(val value: Int) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<Int>(IC(40)) + 2
if (res != 42) "FAIL 1: $res"
res = extension<Int>(IC(40)) + 3
if (res != 43) "FAIL 2: $res"
res = dispatch<Int>(IC(40)) + 4
if (res != 44) "FAIL 3: $res"
res = normal<Int>(IC(40)) + 5
if (res != 45) return "FAIL 4: $res"
return "OK"
}
@@ -0,0 +1,21 @@
// !LANGUAGE: +InlineClasses
// WITH_RUNTIME
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
fun <T> foo(a: Result<T>): T = bar(a, object : IFace<Result<T>, T> {
override fun call(ic: Result<T>): T = ic.getOrThrow()
})
interface IFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: IFace<T, R>): R {
return f.call(value)
}
fun box(): String {
val res = foo<Int>(Result.success(40)) + 2
return if (res != 42) "FAIL $res" else "OK"
}
@@ -0,0 +1,51 @@
// !LANGUAGE: +InlineClasses
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
fun <T> underlying(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.value as T
})
fun <T> extension(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.extensionValue()
})
fun <T> dispatch(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = ic.dispatchValue()
})
fun <T> normal(a: IC): T = bar(a, object : IFace<IC, T> {
override fun call(ic: IC): T = normalValue(ic)
})
interface IFace<T, R> {
fun call(ic: T): R
}
fun <T, R> bar(value: T, f: IFace<T, R>): R {
return f.call(value)
}
fun <T> IC.extensionValue(): T = value as T
fun <T> normalValue(ic: IC): T = ic.value as T
inline class IC(val value: String) {
fun <T> dispatchValue(): T = value as T
}
fun box(): String {
var res = underlying<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 1: $res"
res = extension<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 2: $res"
res = dispatch<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 3: $res"
res = normal<String>(IC("O")) + "K"
if (res != "OK") return "FAIL 3: $res"
return "OK"
}