[FIR2IR] Fix cast insertion for SAM conversion
The rule is: no cast is required iff the argument type is a non-reflection function type and a subtype of the expected function type. We approximate the cone types using the FIR2IR specific config to account for intersection types, captured types, etc. #KT-63345 Fixed #KT-63510 #KT-62865
This commit is contained in:
committed by
Space Team
parent
dd1d36816b
commit
b857c28ab3
Vendored
+24
-2
@@ -125,7 +125,8 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
|
||||
GET_VAR 'a: kotlin.Function1<kotlin.Int, kotlin.Int> declared in <root>.test7' type=kotlin.Function1<kotlin.Int, kotlin.Int> origin=null
|
||||
CALL 'public final fun run1 (r: <root>.KRunnable): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
r: TYPE_OP type=<root>.KRunnable origin=SAM_CONVERSION typeOperand=<root>.KRunnable
|
||||
GET_VAR 'a: kotlin.Function1<kotlin.Int, kotlin.Int> declared in <root>.test7' type=kotlin.Function1<kotlin.Int, kotlin.Int> origin=null
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
GET_VAR 'a: kotlin.Function1<kotlin.Int, kotlin.Int> declared in <root>.test7' type=kotlin.Function1<kotlin.Int, kotlin.Int> origin=null
|
||||
FUN name:test7a visibility:public modality:FINAL <T> (a:T of <root>.test7a) returnType:kotlin.Unit
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Function1<kotlin.Int, kotlin.Int>] reified:false
|
||||
VALUE_PARAMETER name:a index:0 type:T of <root>.test7a
|
||||
@@ -135,7 +136,8 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
|
||||
GET_VAR 'a: T of <root>.test7a declared in <root>.test7a' type=T of <root>.test7a origin=null
|
||||
CALL 'public final fun run1 (r: <root>.KRunnable): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
r: TYPE_OP type=<root>.KRunnable origin=SAM_CONVERSION typeOperand=<root>.KRunnable
|
||||
GET_VAR 'a: T of <root>.test7a declared in <root>.test7a' type=T of <root>.test7a origin=null
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
GET_VAR 'a: T of <root>.test7a declared in <root>.test7a' type=T of <root>.test7a origin=null
|
||||
FUN name:test7b visibility:public modality:FINAL <T> (a:T of <root>.test7b) returnType:kotlin.Unit
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Function1<kotlin.Int, kotlin.Unit>; kotlin.Function0<kotlin.Unit>] reified:false
|
||||
VALUE_PARAMETER name:a index:0 type:T of <root>.test7b
|
||||
@@ -178,3 +180,23 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
|
||||
CALL 'public final fun run1 (r: <root>.KRunnable): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
r: TYPE_OP type=<root>.KRunnable origin=SAM_CONVERSION typeOperand=<root>.KRunnable
|
||||
FUNCTION_REFERENCE 'public final fun test9 (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
|
||||
FUN name:test10 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any
|
||||
BLOCK_BODY
|
||||
WHEN type=kotlin.Unit origin=IF
|
||||
BRANCH
|
||||
if: WHEN type=kotlin.Boolean origin=ANDAND
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.Unrelated
|
||||
GET_VAR 'a: kotlin.Any declared in <root>.test10' type=kotlin.Any origin=null
|
||||
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
TYPE_OP type=<root>.Unrelated origin=IMPLICIT_CAST typeOperand=<root>.Unrelated
|
||||
GET_VAR 'a: kotlin.Any declared in <root>.test10' type=kotlin.Any origin=null
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: CONST Boolean type=kotlin.Boolean value=false
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
CALL 'public final fun run1 (r: <root>.KRunnable): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
r: TYPE_OP type=<root>.KRunnable origin=SAM_CONVERSION typeOperand=<root>.KRunnable
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
GET_VAR 'a: kotlin.Any declared in <root>.test10' type=kotlin.Any origin=null
|
||||
|
||||
Vendored
+13
-2
@@ -70,12 +70,12 @@ fun test6(a: Any) {
|
||||
|
||||
fun test7(a: Function1<Int, Int>) {
|
||||
a as Function0<Unit> /*~> Unit */
|
||||
run1(r = a /*-> KRunnable */)
|
||||
run1(r = a /*as Function0<Unit> */ /*-> KRunnable */)
|
||||
}
|
||||
|
||||
fun <T : Function1<Int, Int>> test7a(a: T) {
|
||||
a as Function0<Unit> /*~> Unit */
|
||||
run1(r = a /*-> KRunnable */)
|
||||
run1(r = a /*as Function0<Unit> */ /*-> KRunnable */)
|
||||
}
|
||||
|
||||
fun <T> test7b(a: T) where T : Function1<Int, Unit>, T : Function0<Unit> {
|
||||
@@ -97,3 +97,14 @@ fun test9() {
|
||||
run1(r = ::test9 /*-> KRunnable */)
|
||||
}
|
||||
|
||||
fun test10(a: Any) {
|
||||
when {
|
||||
when {
|
||||
a is Unrelated -> a /*as Unrelated */ is Function0<Unit>
|
||||
else -> false
|
||||
} -> { // BLOCK
|
||||
run1(r = a /*as Function0<Unit> */ /*-> KRunnable */)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
@@ -179,3 +179,22 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
|
||||
CALL 'public final fun run1 (r: <root>.KRunnable): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
r: TYPE_OP type=<root>.KRunnable origin=SAM_CONVERSION typeOperand=<root>.KRunnable
|
||||
FUNCTION_REFERENCE 'public final fun test9 (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
|
||||
FUN name:test10 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any
|
||||
BLOCK_BODY
|
||||
WHEN type=kotlin.Unit origin=IF
|
||||
BRANCH
|
||||
if: WHEN type=kotlin.Boolean origin=ANDAND
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.Unrelated
|
||||
GET_VAR 'a: kotlin.Any declared in <root>.test10' type=kotlin.Any origin=null
|
||||
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
GET_VAR 'a: kotlin.Any declared in <root>.test10' type=kotlin.Any origin=null
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: CONST Boolean type=kotlin.Boolean value=false
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
CALL 'public final fun run1 (r: <root>.KRunnable): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
r: TYPE_OP type=<root>.KRunnable origin=SAM_CONVERSION typeOperand=<root>.KRunnable
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||
GET_VAR 'a: kotlin.Any declared in <root>.test10' type=kotlin.Any origin=null
|
||||
|
||||
+8
@@ -79,3 +79,11 @@ fun test8(a: () -> Unit) {
|
||||
fun test9() {
|
||||
run1(::test9)
|
||||
}
|
||||
|
||||
// KT-63345
|
||||
fun test10(a: Any) {
|
||||
@Suppress("CANNOT_CHECK_FOR_ERASED")
|
||||
if (a is Unrelated && a is (() -> Unit)) {
|
||||
run1(a)
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -96,3 +96,14 @@ fun test8(a: Function0<Unit>) {
|
||||
fun test9() {
|
||||
run1(r = ::test9 /*-> KRunnable */)
|
||||
}
|
||||
|
||||
fun test10(a: Any) {
|
||||
when {
|
||||
when {
|
||||
a is Unrelated -> a is Function0<Unit>
|
||||
else -> false
|
||||
} -> { // BLOCK
|
||||
run1(r = a /*as Function0<Unit> */ /*-> KRunnable */)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+6
@@ -50,6 +50,12 @@ fun <T> test0(a: T): Unit where T : KRunnable, T : Function0<Unit>
|
||||
// Public signature debug description: test1(kotlin.Function0<kotlin.Unit>){}
|
||||
fun test1(a: Function0<Unit>): Unit
|
||||
|
||||
// CHECK:
|
||||
// Mangled name: #test10(kotlin.Any){}
|
||||
// Public signature: /test10|8673682583765656768[0]
|
||||
// Public signature debug description: test10(kotlin.Any){}
|
||||
fun test10(a: Any): Unit
|
||||
|
||||
// CHECK:
|
||||
// Mangled name: #test2(KRunnable){}
|
||||
// Public signature: /test2|-6262171320756539088[0]
|
||||
|
||||
Reference in New Issue
Block a user