| // WITH_STDLIB |
| // WORKS_WHEN_VALUE_CLASS |
| // CHECK_BYTECODE_LISTING |
| // ISSUE: KT-87327 |
| |
| OPTIONAL_JVM_INLINE_ANNOTATION |
| value class IntValue(val value: Int) |
| |
| OPTIONAL_JVM_INLINE_ANNOTATION |
| value class Wrapper<out T>(val value: T) |
| |
| // KT-87327: generic-unwrapped value class vs direct value-class instance |
| fun boom(w1: Wrapper<IntValue>): Boolean = w1.value == IntValue(1) |
| |
| // Flipped order |
| fun flipped(w1: Wrapper<IntValue>): Boolean = IntValue(1) == w1.value |
| |
| // Both sides are generic-extracted |
| fun bothGeneric(w1: Wrapper<IntValue>, w2: Wrapper<IntValue>): Boolean = w1.value == w2.value |
| |
| // Extracted to local variable |
| fun viaLocal(w1: Wrapper<IntValue>): Boolean { |
| val v = w1.value |
| return v == IntValue(1) |
| } |
| |
| // Wrapper-level equality |
| fun wrapperEquals(w1: Wrapper<IntValue>, w2: Wrapper<IntValue>): Boolean = w1 == w2 |
| |
| // Explicit .equals() call |
| fun explicitEquals(w1: Wrapper<IntValue>): Boolean = w1.value.equals(IntValue(1)) |
| |
| fun box(): String { |
| if (!boom(Wrapper(IntValue(1)))) return "Fail 1" |
| if (boom(Wrapper(IntValue(2)))) return "Fail 2" |
| if (!flipped(Wrapper(IntValue(1)))) return "Fail 3" |
| if (flipped(Wrapper(IntValue(2)))) return "Fail 4" |
| if (!bothGeneric(Wrapper(IntValue(1)), Wrapper(IntValue(1)))) return "Fail 5" |
| if (bothGeneric(Wrapper(IntValue(1)), Wrapper(IntValue(2)))) return "Fail 6" |
| if (!viaLocal(Wrapper(IntValue(1)))) return "Fail 7" |
| if (viaLocal(Wrapper(IntValue(2)))) return "Fail 8" |
| if (!wrapperEquals(Wrapper(IntValue(1)), Wrapper(IntValue(1)))) return "Fail 9" |
| if (wrapperEquals(Wrapper(IntValue(1)), Wrapper(IntValue(2)))) return "Fail 10" |
| if (!explicitEquals(Wrapper(IntValue(1)))) return "Fail 11" |
| if (explicitEquals(Wrapper(IntValue(2)))) return "Fail 12" |
| return "OK" |
| } |