JVM_IR: change parameter type computation in InlineCallableReferenceToLambda
The reference type is approximated in Psi2Ir, so we may get Nothing as a reference type argument. Better look at the arguments of the referenced function.
This commit is contained in:
+14
-4
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.allParameters
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
@@ -25,7 +26,6 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -117,10 +117,20 @@ internal class InlineCallableReferenceToLambdaPhase(val context: JvmBackendConte
|
||||
val irBuilder = context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset)
|
||||
return irBuilder.irBlock(expression, IrStatementOrigin.LAMBDA) {
|
||||
|
||||
val parameterTypes = (expression.type as IrSimpleType).arguments.map { (it as IrTypeProjection).type }
|
||||
val argumentTypes = parameterTypes.dropLast(1)
|
||||
|
||||
// We find the number of parameters for constructed lambda from the type of the function reference,
|
||||
// but the actual types have to be copied from referencedFunction; function reference argument type may be too
|
||||
// specific because of approximation. See compiler/testData/codegen/box/callableReference/function/argumentTypes.kt
|
||||
val boundReceiver: Pair<IrValueParameter, IrExpression>? = expression.getArgumentsWithIr().singleOrNull()
|
||||
val nParams = (expression.type as IrSimpleType).arguments.size - 1
|
||||
var toDropAtStart = 0
|
||||
if (boundReceiver != null) toDropAtStart++
|
||||
if (referencedFunction is IrConstructor) toDropAtStart++
|
||||
val argumentTypes = referencedFunction.allParameters.drop(toDropAtStart).take(nParams).map { parameter ->
|
||||
parameter.type.substitute(
|
||||
referencedFunction.typeParameters,
|
||||
referencedFunction.typeParameters.indices.map { expression.getTypeArgument(it)!! }
|
||||
)
|
||||
}
|
||||
|
||||
val function = buildFun {
|
||||
setSourceRange(expression)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
inline fun <TT> id(x: TT): TT = x
|
||||
inline fun <TT> String.extId(x: TT): String = this
|
||||
|
||||
private fun <T> ff(value: T?): String {
|
||||
// In PSI2IR, the funcref is approximated to Function1<Nothing, Pair<String, T>>
|
||||
value?.let(::id)
|
||||
return value?.let("OK"::extId)!!
|
||||
}
|
||||
|
||||
fun box() = ff("arg")
|
||||
|
||||
+5
@@ -2186,6 +2186,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/function"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("argumentTypes.kt")
|
||||
public void testArgumentTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("booleanNotIntrinsic.kt")
|
||||
public void testBooleanNotIntrinsic() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
||||
|
||||
+5
@@ -2186,6 +2186,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/function"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("argumentTypes.kt")
|
||||
public void testArgumentTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("booleanNotIntrinsic.kt")
|
||||
public void testBooleanNotIntrinsic() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
||||
|
||||
+5
@@ -2166,6 +2166,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/function"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("argumentTypes.kt")
|
||||
public void testArgumentTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("booleanNotIntrinsic.kt")
|
||||
public void testBooleanNotIntrinsic() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
||||
|
||||
+5
@@ -2166,6 +2166,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/function"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("argumentTypes.kt")
|
||||
public void testArgumentTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("booleanNotIntrinsic.kt")
|
||||
public void testBooleanNotIntrinsic() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
||||
|
||||
Generated
+5
@@ -1596,6 +1596,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/function"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("argumentTypes.kt")
|
||||
public void testArgumentTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("booleanNotIntrinsic.kt")
|
||||
public void testBooleanNotIntrinsic() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
||||
|
||||
+5
@@ -1596,6 +1596,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/function"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("argumentTypes.kt")
|
||||
public void testArgumentTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("booleanNotIntrinsic.kt")
|
||||
public void testBooleanNotIntrinsic() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
||||
|
||||
Reference in New Issue
Block a user