K2: Do not use KFunctionN as representation type for adapted references

Beside some corner cases, it's already prohibited in K1 because
adaptation have a bit strange nature
(they don't represent any existing real function exactly)

^KT-55137 Fixed
This commit is contained in:
Denis.Zharkov
2022-11-25 18:19:10 +01:00
committed by Space Team
parent dcdc48a233
commit a38040680c
17 changed files with 102 additions and 18 deletions
@@ -0,0 +1,9 @@
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND_K1: JVM_IR
fun foo(x: String = "OK"): String = x
fun box(): String {
val f: () -> String = ::foo
return f()
}
@@ -0,0 +1,16 @@
// SKIP_TXT
fun foo(x: String = "O"): String = x
fun bar(x: String = "K"): String = x
fun dump(dumpStrategy: String) {
val k0: kotlin.reflect.KFunction0<String> = <!INAPPLICABLE_CANDIDATE!>returnAdapter<!>(::<!UNRESOLVED_REFERENCE!>foo<!>) // Error: ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE
val k1: kotlin.reflect.KFunction0<String> = ::<!UNRESOLVED_REFERENCE!>foo<!>
// Should be error here, too
val k2: kotlin.reflect.KFunction0<String> = if (dumpStrategy == "KotlinLike") ::<!UNRESOLVED_REFERENCE!>foo<!> else ::<!UNRESOLVED_REFERENCE!>bar<!>
val f0: Function0<String> = <!INAPPLICABLE_CANDIDATE!>returnAdapter<!>(::<!UNRESOLVED_REFERENCE!>foo<!>)
val f1: Function0<String> = ::foo
val f2: Function0<String> = if (dumpStrategy == "KotlinLike") ::<!UNRESOLVED_REFERENCE!>foo<!> else ::<!UNRESOLVED_REFERENCE!>bar<!>
}
fun returnAdapter(a: kotlin.reflect.KFunction0<String>) = a
@@ -0,0 +1,16 @@
// SKIP_TXT
fun foo(x: String = "O"): String = x
fun bar(x: String = "K"): String = x
fun dump(dumpStrategy: String) {
val k0: kotlin.reflect.KFunction0<String> = returnAdapter(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::foo<!>) // Error: ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE
val k1: kotlin.reflect.KFunction0<String> = <!TYPE_MISMATCH!>::<!TYPE_MISMATCH!>foo<!><!>
// Should be error here, too
val k2: kotlin.reflect.KFunction0<String> = if (dumpStrategy == "KotlinLike") ::foo else ::bar
val f0: Function0<String> = returnAdapter(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::foo<!>)
val f1: Function0<String> = <!TYPE_MISMATCH!>::<!TYPE_MISMATCH!>foo<!><!>
val f2: Function0<String> = if (dumpStrategy == "KotlinLike") ::foo else ::bar
}
fun returnAdapter(a: kotlin.reflect.KFunction0<String>) = a
@@ -22,6 +22,6 @@ object Local {
fun baz(x: Int, y: Int = 0): Int = 0
fun test() {
bar(::baz)
<!INAPPLICABLE_CANDIDATE!>bar<!>(::<!UNRESOLVED_REFERENCE!>baz<!>)
}
}
@@ -22,6 +22,6 @@ object Local {
fun baz(x: Int, y: Int = 0): Int = 0
fun test() {
bar(::baz)
<!INAPPLICABLE_CANDIDATE!>bar<!>(::<!UNRESOLVED_REFERENCE!>baz<!>)
}
}
@@ -107,7 +107,7 @@ FILE fqName:<root> fileName:/caoWithAdaptationForSam.kt
BLOCK type=kotlin.Unit origin=null
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.A [val]
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> [val]
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=ADAPTED_FUNCTION_REFERENCE
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int
@@ -118,19 +118,19 @@ FILE fqName:<root> fileName:/caoWithAdaptationForSam.kt
CALL 'public final fun set (i: <root>.IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=null
$receiver: GET_VAR 'val tmp_0: <root>.A [val] declared in <root>.test1' type=<root>.A origin=null
i: TYPE_OP type=<root>.IFoo origin=SAM_CONVERSION typeOperand=<root>.IFoo
GET_VAR 'val tmp_1: kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test1' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
GET_VAR 'val tmp_1: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test1' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
$receiver: GET_VAR 'val tmp_0: <root>.A [val] declared in <root>.test1' type=<root>.A origin=null
i: TYPE_OP type=<root>.IFoo origin=SAM_CONVERSION typeOperand=<root>.IFoo
GET_VAR 'val tmp_1: kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test1' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
GET_VAR 'val tmp_1: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test1' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
other: CONST Int type=kotlin.Int value=1
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
BLOCK type=kotlin.Unit origin=null
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.B [val]
GET_OBJECT 'CLASS OBJECT name:B modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.B
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> [val]
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=ADAPTED_FUNCTION_REFERENCE
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:withVararg visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int
@@ -141,12 +141,12 @@ FILE fqName:<root> fileName:/caoWithAdaptationForSam.kt
CALL 'public final fun set (i: <root>.IFoo2, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=null
$receiver: GET_VAR 'val tmp_2: <root>.B [val] declared in <root>.test2' type=<root>.B origin=null
i: TYPE_OP type=<root>.IFoo2 origin=SAM_CONVERSION typeOperand=<root>.IFoo2
GET_VAR 'val tmp_3: kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test2' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
GET_VAR 'val tmp_3: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test2' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
$receiver: GET_VAR 'val tmp_2: <root>.B [val] declared in <root>.test2' type=<root>.B origin=null
i: TYPE_OP type=<root>.IFoo origin=SAM_CONVERSION typeOperand=<root>.IFoo
GET_VAR 'val tmp_3: kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test2' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null
GET_VAR 'val tmp_3: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test2' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
other: CONST Int type=kotlin.Int value=1
FUN name:test3 visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Unit>
@@ -46,7 +46,7 @@ fun withVararg(vararg xs: Int): Int {
fun test1() {
{ // BLOCK
val <array>: A = A
val <index_0>: KFunction1<Int, Unit> = local fun withVararg(p0: Int) {
val <index_0>: Function1<Int, Unit> = local fun withVararg(p0: Int) {
withVararg(xs = [p0])
}
@@ -57,7 +57,7 @@ fun test1() {
fun test2() {
{ // BLOCK
val <array>: B = B
val <index_0>: KFunction1<Int, Unit> = local fun withVararg(p0: Int) {
val <index_0>: Function1<Int, Unit> = local fun withVararg(p0: Int) {
withVararg(xs = [p0])
}