blob: 5450db3a16542259d6db70273d780e3945750b91 [file]
// WITH_STDLIB
// WORKS_WHEN_VALUE_CLASS
// ISSUE: KT-86123
// Tests that callable reference class deduplication handles generic type parameters correctly
// when they have different upper bounds (nullable vs non-nullable, primitive-wrapping value class, etc.)
OPTIONAL_JVM_INLINE_ANNOTATION
value class W(val x: Long)
// T has implicit bound Any? (nullable) => erases to anyNType
fun <T> captureNullableBound(t: T): () -> String = { t.toString() }
// T : Any (non-nullable) => erases to anyNType (Any is a reference type)
fun <T : Any> captureNonNullBound(t: T): () -> String = { t.toString() }
// T : W (value class bound wrapping primitive) => erases to W (unboxed)
fun <T : W> captureValueClassBound(t: T): () -> String = { t.toString() }
// Two different type parameter names with same bound should merge
fun <A> captureA(a: A): () -> String = { a.toString() }
fun <B> captureB(b: B): () -> String = { b.toString() }
fun box(): String {
// Nullable bound captures
val n1 = captureNullableBound("hello")
val n2 = captureNullableBound(42)
val n3 = captureNullableBound<String?>(null)
if (n1() != "hello") return "FAIL n1: ${n1()}"
if (n2() != "42") return "FAIL n2: ${n2()}"
if (n3() != "null") return "FAIL n3: ${n3()}"
// Non-null bound captures
val nn1 = captureNonNullBound("world")
val nn2 = captureNonNullBound(99)
if (nn1() != "world") return "FAIL nn1: ${nn1()}"
if (nn2() != "99") return "FAIL nn2: ${nn2()}"
// Value class bound captures
val v1 = captureValueClassBound(W(77))
if (v1() != "W(x=77)") return "FAIL v1: ${v1()}"
// Different type parameter names, same bound => should merge correctly
val a = captureA("from A")
val b = captureB("from B")
if (a() != "from A") return "FAIL a: ${a()}"
if (b() != "from B") return "FAIL b: ${b()}"
return "OK"
}