Support default parameters of inline type with generic underlying value

#KT-32162
This commit is contained in:
Ilmir Usmanov
2021-12-24 07:44:32 +01:00
parent 4f95171472
commit c8817893d4
22 changed files with 781 additions and 4 deletions
@@ -0,0 +1,17 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class Z<T: Int>(val z: T)
class Test(val z: Z<Int> = Z(42)) {
fun test() = z.z
}
fun box(): String {
if (Test().test() != 42) throw AssertionError()
if (Test(Z(123)).test() != 123) throw AssertionError()
return "OK"
}
@@ -0,0 +1,26 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class Z<T: Int>(val z: T)
interface ITest {
fun testDefault(z: Z<Int> = Z(42)) = z.z
fun testOverridden(z: Z<Int> = Z(42)): Int
}
class Test : ITest {
override fun testOverridden(z: Z<Int>) = z.z
}
fun box(): String {
if (Test().testDefault() != 42) throw AssertionError()
if (Test().testDefault(Z(123)) != 123) throw AssertionError()
if (Test().testOverridden() != 42) throw AssertionError()
if (Test().testOverridden(Z(123)) != 123) throw AssertionError()
return "OK"
}
@@ -0,0 +1,31 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
interface IFoo {
fun foo(): String
}
OPTIONAL_JVM_INLINE_ANNOTATION
value class Z<T: Int>(val z: T) : IFoo {
override fun foo() = z.toString()
}
fun testNullable(z: Z<Int>? = Z(42)) = z!!.z
fun testAny(z: Any = Z(42)) = (z as Z<*>).z
fun testInterface(z: IFoo = Z(42)) = z.foo()
fun box(): String {
if (testNullable() != 42) throw AssertionError()
if (testNullable(Z(123)) != 123) throw AssertionError()
if (testAny() != 42) throw AssertionError()
if (testAny(Z(123)) != 123) throw AssertionError()
if (testInterface() != "42") throw AssertionError()
if (testInterface(Z(123)) != "123") throw AssertionError()
return "OK"
}
@@ -0,0 +1,15 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class Z<T: Int>(val z: T)
fun test(z: Z<Int> = Z(42)) = z.z
fun box(): String {
if (test() != 42) throw AssertionError()
if (test(Z(123)) != 123) throw AssertionError()
return "OK"
}
@@ -0,0 +1,40 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class Z<T: Int>(val int: T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class L<T: Long>(val long: T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class Str<T: String>(val string: T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class Obj<T: Any>(val obj: T)
inline fun <R> withDefaultZ(fn: (Z<Int>) -> R, x: Z<Int> = Z(42)) = fn(x)
inline fun <R> withDefaultL(fn: (L<Long>) -> R, x: L<Long> = L(42L)) = fn(x)
inline fun <R> withDefaultL2(x: L<Long> = L(42L), fn: (L<Long>) -> R) = fn(x)
inline fun <R> withDefaultStr(fn: (Str<String>) -> R, x: Str<String> = Str("abc")) = fn(x)
inline fun <R> withDefaultObj(fn: (Obj<Any>) -> R, x: Obj<Any> = Obj("abc")) = fn(x)
inline fun <R> withDefaultObj2(x: Obj<Any> = Obj("abc"), fn: (Obj<Any>) -> R) = fn(x)
fun testWithDefaultZ() = withDefaultZ({ Z(it.int + 1) })
fun testWithDefaultL() = withDefaultL({ L(it.long + 1L) })
fun testWithDefaultL2() = withDefaultL2(fn = { L(it.long + 1L) })
fun testWithDefaultStr() = withDefaultStr({ Str(it.string + "1") })
fun testWithDefaultObj() = withDefaultObj({ Obj(it.obj.toString() + "1") })
fun testWithDefaultObj2() = withDefaultObj2(fn = { Obj(it.obj.toString() + "1") })
fun box(): String {
if (testWithDefaultZ().int != 43) throw AssertionError()
if (testWithDefaultL().long != 43L) throw AssertionError()
if (testWithDefaultL2().long != 43L) throw AssertionError()
if (testWithDefaultStr().string != "abc1") throw AssertionError()
if (testWithDefaultObj().obj != "abc1") throw AssertionError()
if (testWithDefaultObj2().obj != "abc1") throw AssertionError()
return "OK"
}
@@ -0,0 +1,44 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class Z<T: Int>(val int: T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class L<T: Long>(val long: T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class Str<T: String>(val string: T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class Obj<T: Any>(val obj: T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class Host<T: Int>(val xx: T) {
inline fun <R> withDefaultZ(fn: (Z<Int>) -> R, x: Z<Int> = Z(xx)) = fn(x)
inline fun <R> withDefaultL(fn: (L<Long>) -> R, x: L<Long> = L(xx.toLong())) = fn(x)
inline fun <R> withDefaultL2(x: L<Long> = L(xx.toLong()), fn: (L<Long>) -> R) = fn(x)
inline fun <R> withDefaultStr(fn: (Str<String>) -> R, x: Str<String> = Str(xx.toString())) = fn(x)
inline fun <R> withDefaultObj(fn: (Obj<Any>) -> R, x: Obj<Any> = Obj(xx.toString())) = fn(x)
inline fun <R> withDefaultObj2(x: Obj<Any> = Obj(xx.toString()), fn: (Obj<Any>) -> R) = fn(x)
fun testWithDefaultZ() = withDefaultZ({ Z(it.int + 1) })
fun testWithDefaultL() = withDefaultL({ L(it.long + 1L) })
fun testWithDefaultL2() = withDefaultL2(fn = { L(it.long + 1L) })
fun testWithDefaultStr() = withDefaultStr({ Str(it.string + "1") })
fun testWithDefaultObj() = withDefaultObj({ Obj(it.obj.toString() + "1") })
fun testWithDefaultObj2() = withDefaultObj2(fn = { Obj(it.obj.toString() + "1") })
}
fun box(): String {
val h = Host(42)
if (h.testWithDefaultZ().int != 43) throw AssertionError()
if (h.testWithDefaultL().long != 43L) throw AssertionError()
if (h.testWithDefaultL2().long != 43L) throw AssertionError()
if (h.testWithDefaultStr().string != "421") throw AssertionError()
if (h.testWithDefaultObj().obj != "421") throw AssertionError()
if (h.testWithDefaultObj2().obj != "421") throw AssertionError()
return "OK"
}
@@ -0,0 +1,15 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class Z<T: Int>(val x: T) {
fun test(y: Int = 42) = x + y
}
fun box(): String {
if (Z(800).test() != 842) throw AssertionError()
if (Z(400).test(32) != 432) throw AssertionError()
return "OK"
}
@@ -0,0 +1,20 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class Z<T: Int>(val x: T = 1234 as T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class L<T: Long>(val x: T = 1234L as T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class S<T: String>(val x: T = "foobar" as T)
fun box(): String {
if (Z<Int>().x != 1234) throw AssertionError()
if (L<Long>().x != 1234L) throw AssertionError()
if (S<String>().x != "foobar") throw AssertionError()
return "OK"
}
@@ -0,0 +1,13 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class Inner<T: String>(val result: T)
OPTIONAL_JVM_INLINE_ANNOTATION
value class A<T: Inner<String>>(val inner: T = Inner("OK") as T)
fun box(): String {
return A<Inner<String>>().inner.result
}
@@ -0,0 +1,14 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class Z<T: Int>(val x: T) {
constructor(x: Long = 42L) : this(x.toInt() as T)
}
fun box(): String {
if (Z<Int>().x != 42) throw AssertionError()
return "OK"
}
@@ -0,0 +1,10 @@
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses, +GenericInlineClassParameter
OPTIONAL_JVM_INLINE_ANNOTATION
value class A<T: Int>(val i: T) {
fun foo(s: String = "OK") = s
}
fun box() = A(42).foo()