Equality comparison for bound callable references takes into account bound receiver.
Fixed KT-14939: use expected receiver type when generating receiver code in get/set methods for bound property references.
Otherwise we have VerifyError for bound receiver 'null' of type 'Nothing?', which is mapped to 'java.lang.Void'.
TODO: proper equality comparison for property accessors ('x::prop.getter', 'x::prop.setter').
This commit is contained in:
+7
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
companion object {
|
||||
fun ok() = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
fun box() = (A.Companion::ok)()
|
||||
@@ -9,8 +9,11 @@ enum class E {
|
||||
|
||||
fun box(): String {
|
||||
val f = E.A::foo
|
||||
val ef = E::foo
|
||||
|
||||
if (f() != "A") return "Fail 1: ${f()}"
|
||||
if (f != E.B::foo) return "Fail 2"
|
||||
if (f == E.B::foo) return "Fail 2"
|
||||
if (ef != E::foo) return "Fail 3"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// TODO: investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
// See https://youtrack.jetbrains.com/issue/KT-14938
|
||||
// WITH_REFLECT
|
||||
|
||||
class A
|
||||
|
||||
val a = A()
|
||||
val aa = A()
|
||||
|
||||
fun A?.foo() {}
|
||||
|
||||
var A?.bar: Int
|
||||
get() = 42
|
||||
set(value) {}
|
||||
|
||||
val aFoo = a::foo
|
||||
val A_foo = A::foo
|
||||
val nullFoo = null::foo
|
||||
|
||||
val aBar = a::bar
|
||||
val A_bar = A::bar
|
||||
val nullBar = null::bar
|
||||
|
||||
fun box(): String =
|
||||
when {
|
||||
nullFoo != null::foo -> "Bound extension refs with same receiver SHOULD be equal"
|
||||
nullFoo == aFoo -> "Bound extension refs with different receivers SHOULD NOT be equal"
|
||||
nullFoo == A_foo -> "Bound extension ref with receiver 'null' SHOULD NOT be equal to free ref"
|
||||
|
||||
nullBar != null::bar -> "Bound extension property refs with same receiver SHOULD be equal"
|
||||
nullBar == aBar -> "Bound extension property refs with different receivers SHOULD NOT be equal"
|
||||
nullBar == A_bar -> "Bound extension property ref with receiver 'null' SHOULD NOT be equal to free property ref"
|
||||
|
||||
else -> "OK"
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// TODO: investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
package test
|
||||
|
||||
class A {
|
||||
fun foo() {}
|
||||
fun bar() {}
|
||||
}
|
||||
|
||||
val a = A()
|
||||
val aa = A()
|
||||
|
||||
val aFoo = a::foo
|
||||
val aBar = a::bar
|
||||
val aaFoo = aa::foo
|
||||
val A_foo = A::foo
|
||||
|
||||
fun box(): String =
|
||||
when {
|
||||
aFoo != a::foo -> "Bound refs with same receiver SHOULD be equal"
|
||||
aFoo == aBar -> "Bound refs to different members SHOULD NOT be equal"
|
||||
aFoo == aaFoo -> "Bound refs with different receiver SHOULD NOT be equal"
|
||||
aFoo == A_foo -> "Bound ref SHOULD NOT be equal to free ref"
|
||||
|
||||
else -> "OK"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// TODO: investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
// See https://youtrack.jetbrains.com/issue/KT-14939
|
||||
|
||||
val String?.ok: String
|
||||
get() = "OK"
|
||||
|
||||
fun box() = (null::ok).get()
|
||||
@@ -0,0 +1,5 @@
|
||||
object Singleton {
|
||||
fun ok() = "OK"
|
||||
}
|
||||
|
||||
fun box() = (Singleton::ok)()
|
||||
@@ -0,0 +1,29 @@
|
||||
// TODO: investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun Boolean.foo() = 1
|
||||
fun Byte.foo() = 2
|
||||
fun Short.foo() = 3
|
||||
fun Int.foo() = 4
|
||||
fun Long.foo() = 5
|
||||
fun Char.foo() = 6
|
||||
fun Float.foo() = 7
|
||||
fun Double.foo() = 8
|
||||
|
||||
fun testRef(name: String, f: () -> Int, expected: Int) {
|
||||
val actual = f()
|
||||
if (actual != expected) throw AssertionError("$name: $actual != $expected")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
testRef("Boolean", true::foo, 1)
|
||||
testRef("Byte", 1.toByte()::foo, 2)
|
||||
testRef("Short", 1.toShort()::foo, 3)
|
||||
testRef("Int", 1::foo, 4)
|
||||
testRef("Long", 1L::foo, 5)
|
||||
testRef("Char", '1'::foo, 6)
|
||||
testRef("Float", 1.0F::foo, 7)
|
||||
testRef("Double", 1.0::foo, 8)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user