[NI] Record substituted generic signature for SAM arguments
#KT-36297 Fixed
This commit is contained in:
+92
@@ -0,0 +1,92 @@
|
||||
// !LANGUAGE: +NewInference +SamConversionPerArgument +SamConversionForKotlinFunctions +FunctionalInterfaceConversion
|
||||
// WITH_REFLECT
|
||||
// FULL_JDK
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// FILE: Provider.java
|
||||
|
||||
public class Provider {
|
||||
public <T> String samCall(java.util.concurrent.Callable<? extends T> value) {
|
||||
return "fail";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import java.util.concurrent.Callable
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
private fun getFirstArgumentType(types: Array<Type>, klass: KClass<*>): String {
|
||||
return types
|
||||
.filterIsInstance<ParameterizedType>()
|
||||
.firstOrNull { it.rawType == klass.java }
|
||||
?.let { it.actualTypeArguments[0] }
|
||||
?.toString() ?: "fail, inferred type is null"
|
||||
}
|
||||
|
||||
class KtProvider : Provider() {
|
||||
override fun <T : Any> samCall(value: Callable<out T>): String =
|
||||
getFirstArgumentType(value.javaClass.genericInterfaces, Callable::class)
|
||||
}
|
||||
|
||||
fun interface KtCallable<T> {
|
||||
fun invoke(): T
|
||||
}
|
||||
|
||||
fun <T : Any> samCallViaFunInterface(value: KtCallable<out T>): String {
|
||||
return getFirstArgumentType(value.javaClass.genericInterfaces, KtCallable::class)
|
||||
}
|
||||
|
||||
fun testCallViaJava(p: Provider): String {
|
||||
var result = "not changed"
|
||||
wrapInline {
|
||||
wrapNoInline {
|
||||
result = p.samCall { "str" }
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun testCallViaKotlin(p: KtProvider): String {
|
||||
var result = "not changed"
|
||||
wrapInline {
|
||||
wrapNoInline {
|
||||
result = p.samCall { "str" }
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun testCallViaFunInterface(): String {
|
||||
var result = "not changed"
|
||||
wrapInline {
|
||||
wrapNoInline {
|
||||
result = samCallViaFunInterface { "str" }
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
inline fun wrapInline(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
fun wrapNoInline(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val inferredTypeInSamLambda1 = testCallViaJava(KtProvider())
|
||||
val inferredTypeInSamLambda2 = testCallViaKotlin(KtProvider())
|
||||
val inferredTypeInSamLambda3 = testCallViaFunInterface()
|
||||
|
||||
assertEquals(inferredTypeInSamLambda1, inferredTypeInSamLambda2)
|
||||
assertEquals(inferredTypeInSamLambda2, inferredTypeInSamLambda3)
|
||||
|
||||
return if (inferredTypeInSamLambda1 == "class java.lang.String") "OK" else "fail: $inferredTypeInSamLambda1"
|
||||
}
|
||||
Reference in New Issue
Block a user