K1: Deprecate incorrect callable references resolution behavior

^KT-54316 Related
^KT-54832 Fixed
This commit is contained in:
Denis.Zharkov
2022-11-04 19:28:21 +01:00
committed by Space Team
parent a3fd63fb1d
commit 2953e600ff
21 changed files with 485 additions and 20 deletions
@@ -37,5 +37,5 @@ fun test() {
val r7 = c::foo
checkSubtype<() -> String>(r7)
C::bar
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>C::bar<!>
}
@@ -0,0 +1,13 @@
// FIR_DUMP
class Foo {
companion object {
fun bar() {}
val baz = 42
}
}
val x1 = Foo::bar
val x2 = Foo.Companion::bar
val x3 = Foo::baz
val x4 = Foo.Companion::baz
@@ -0,0 +1,28 @@
FILE: callableReferencesToCompanionMembers.fir.kt
public final class Foo : R|kotlin/Any| {
public constructor(): R|Foo| {
super<R|kotlin/Any|>()
}
public final companion object Companion : R|kotlin/Any| {
private constructor(): R|Foo.Companion| {
super<R|kotlin/Any|>()
}
public final fun bar(): R|kotlin/Unit| {
}
public final val baz: R|kotlin/Int| = Int(42)
public get(): R|kotlin/Int|
}
}
public final val x1: R|kotlin/reflect/KFunction0<kotlin/Unit>| = Q|Foo|::R|/Foo.Companion.bar|
public get(): R|kotlin/reflect/KFunction0<kotlin/Unit>|
public final val x2: R|kotlin/reflect/KFunction0<kotlin/Unit>| = Q|Foo.Companion|::R|/Foo.Companion.bar|
public get(): R|kotlin/reflect/KFunction0<kotlin/Unit>|
public final val x3: R|kotlin/reflect/KProperty0<kotlin/Int>| = Q|Foo|::R|/Foo.Companion.baz|
public get(): R|kotlin/reflect/KProperty0<kotlin/Int>|
public final val x4: R|kotlin/reflect/KProperty0<kotlin/Int>| = Q|Foo.Companion|::R|/Foo.Companion.baz|
public get(): R|kotlin/reflect/KProperty0<kotlin/Int>|
@@ -0,0 +1,13 @@
// FIR_DUMP
class Foo {
companion object {
fun bar() {}
val baz = 42
}
}
val x1 = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>Foo::bar<!>
val x2 = Foo.Companion::bar
val x3 = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>Foo::baz<!>
val x4 = Foo.Companion::baz
@@ -0,0 +1,22 @@
package
public val x1: kotlin.reflect.KFunction1<Foo, kotlin.Unit>
public val x2: kotlin.reflect.KFunction0<kotlin.Unit>
public val x3: kotlin.reflect.KProperty1<Foo, kotlin.Int>
public val x4: kotlin.reflect.KProperty0<kotlin.Int>
public final class Foo {
public constructor Foo()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public companion object Companion {
private constructor Companion()
public final val baz: kotlin.Int = 42
public final fun bar(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,79 @@
// SKIP_TXT
class A {
companion object {
fun foo(): Int = 43
val companionProp: Int = 44
}
fun baz(): Int = 1
val memberProp: Int = 2
}
object Obj {
fun foo(): Int = 43
val objProp: Int = 44
}
fun main() {
A::foo.invoke(<!TOO_MANY_ARGUMENTS!>A()<!>)
A::foo.invoke()
val x = A::foo
x.invoke(<!TOO_MANY_ARGUMENTS!>A()<!>)
x.invoke()
A.Companion::foo.invoke()
val x0 = A.Companion::foo
x0.invoke()
bar(A::foo)
val y = id(A::foo)
y.invoke()
A::baz.invoke(A())
val z = A::baz
z.invoke(A())
bam(A::baz)
Obj::foo.invoke()
val zObj = Obj::foo
zObj.invoke()
bar(Obj::foo)
}
fun mainProp() {
A::companionProp.invoke(<!TOO_MANY_ARGUMENTS!>A()<!>)
A::companionProp.invoke()
val x = A::companionProp
x.invoke(<!TOO_MANY_ARGUMENTS!>A()<!>)
x.invoke()
A.Companion::companionProp.invoke()
val x0 = A.Companion::companionProp
x0.invoke()
bar(A::companionProp)
val y = id(A::companionProp)
y.invoke()
A::memberProp.invoke(A())
val z = A::memberProp
z.invoke(A())
bam(A::memberProp)
Obj::objProp.invoke()
val zObj = Obj::objProp
zObj.invoke()
bar(Obj::objProp)
}
fun <E> id(e: E): E = e
fun bar(x: () -> Int) {}
fun bam(x: A.() -> Int) {}
@@ -0,0 +1,79 @@
// SKIP_TXT
class A {
companion object {
fun foo(): Int = 43
val companionProp: Int = 44
}
fun baz(): Int = 1
val memberProp: Int = 2
}
object Obj {
fun foo(): Int = 43
val objProp: Int = 44
}
fun main() {
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::foo<!>.invoke(A())
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::foo<!>.invoke<!NO_VALUE_FOR_PARAMETER!>()<!>
val x = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::foo<!>
x.invoke(A())
x.invoke<!NO_VALUE_FOR_PARAMETER!>()<!>
A.Companion::foo.invoke()
val x0 = A.Companion::foo
x0.invoke()
bar(A::foo)
val y = id(A::foo)
y.invoke()
A::baz.invoke(A())
val z = A::baz
z.invoke(A())
bam(A::baz)
Obj::foo.invoke()
val zObj = Obj::foo
zObj.invoke()
bar(Obj::foo)
}
fun mainProp() {
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::companionProp<!>.invoke(A())
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::companionProp<!>.invoke<!NO_VALUE_FOR_PARAMETER!>()<!>
val x = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::companionProp<!>
x.invoke(A())
x.invoke<!NO_VALUE_FOR_PARAMETER!>()<!>
A.Companion::companionProp.invoke()
val x0 = A.Companion::companionProp
x0.invoke()
bar(A::companionProp)
val y = id(A::companionProp)
y.invoke()
A::memberProp.invoke(A())
val z = A::memberProp
z.invoke(A())
bam(A::memberProp)
Obj::objProp.invoke()
val zObj = Obj::objProp
zObj.invoke()
bar(Obj::objProp)
}
fun <E> id(e: E): E = e
fun bar(x: () -> Int) {}
fun bam(x: A.() -> Int) {}
@@ -26,6 +26,6 @@ fun main() {
// It must be OK
val x18 = String?::hashCode <!USELESS_ELVIS!>?: ::foo<!>
val x19 = String::hashCode <!USELESS_ELVIS!>?: ::foo<!>
val x20 = String?::hashCode::hashCode
val x21 = kotlin.String?::hashCode::hashCode
val x20 = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>String?::hashCode<!>::hashCode
val x21 = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>kotlin.String?::hashCode<!>::hashCode
}
@@ -0,0 +1,74 @@
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
import A.Base.Companion.FromABaseCompanion
import B.Base.Companion.FromBBaseCompanion
import C.Base.Companion.FromCBaseCompanion
import D.Base.Companion.FromDBaseCompanion
// ===== Case 1: LHS is a class
//
object A {
open class Base {
companion object {
class FromABaseCompanion {
fun foo() = 42
}
}
}
class Derived : Base() {
val a = FromABaseCompanion::foo
}
}
// ===== Case 2: LHS is a class with companion object, function comes from class
object B {
open class Base {
companion object {
class FromBBaseCompanion {
fun foo() = 42
companion object {}
}
}
}
class Derived : Base() {
val a = FromBBaseCompanion::foo
}
}
// ==== Case 3: LHS is a class with companion object, function comes from companion
object C {
open class Base {
companion object {
class FromCBaseCompanion {
companion object {
fun foo() = 42
}
}
}
}
class Derived : Base() {
val a = FromCBaseCompanion::foo
}
}
// ==== Case 4: LHS is an object
object D {
open class Base {
companion object {
object FromDBaseCompanion {
fun foo() = 42
}
}
}
class Derived : Base() {
val a = FromDBaseCompanion::foo
}
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
import A.Base.Companion.FromABaseCompanion
@@ -54,7 +53,7 @@ object C {
}
class Derived : Base() {
val a = FromCBaseCompanion::foo
val a = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>FromCBaseCompanion::foo<!>
}
}
@@ -72,4 +71,4 @@ object D {
class Derived : Base() {
val a = FromDBaseCompanion::foo
}
}
}
@@ -0,0 +1,69 @@
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
// ===== Case 1: LHS is a class
//
object A {
open class Base {
companion object {
class FromBaseCompanion {
fun foo() = 42
}
}
}
class Derived : Base() {
val a = A.Base.Companion.FromBaseCompanion::foo
}
}
// ===== Case 2: LHS is a class with companion object, function comes from class
object B {
open class Base {
companion object {
class FromBaseCompanion {
fun foo() = 42
companion object {}
}
}
}
class Derived : Base() {
val a = B.Base.Companion.FromBaseCompanion::foo
}
}
// ==== Case 3: LHS is a class with companion object, function comes from companion
object C {
open class Base {
companion object {
class FromBaseCompanion {
companion object {
fun foo() = 42
}
}
}
}
class Derived : Base() {
val a = C.Base.Companion.FromBaseCompanion::foo
}
}
// ==== Case 4: LHS is an object
object D {
open class Base {
companion object {
object FromBaseCompanion {
fun foo() = 42
}
}
}
class Derived : Base() {
val a = D.Base.Companion.FromBaseCompanion::foo
}
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
// ===== Case 1: LHS is a class
@@ -49,7 +48,7 @@ object C {
}
class Derived : Base() {
val a = C.Base.Companion.FromBaseCompanion::foo
val a = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>C.Base.Companion.FromBaseCompanion::foo<!>
}
}
@@ -67,4 +66,4 @@ object D {
class Derived : Base() {
val a = D.Base.Companion.FromBaseCompanion::foo
}
}
}
@@ -48,7 +48,7 @@ object C {
}
class Derived : Base() {
val a = <!DEPRECATED_ACCESS_BY_SHORT_NAME!>FromBaseCompanion<!>::foo
val a = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!><!DEPRECATED_ACCESS_BY_SHORT_NAME!>FromBaseCompanion<!>::foo<!>
}
}