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.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
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.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
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.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
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.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
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)
|
val irBuilder = context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset)
|
||||||
return irBuilder.irBlock(expression, IrStatementOrigin.LAMBDA) {
|
return irBuilder.irBlock(expression, IrStatementOrigin.LAMBDA) {
|
||||||
|
|
||||||
val parameterTypes = (expression.type as IrSimpleType).arguments.map { (it as IrTypeProjection).type }
|
// We find the number of parameters for constructed lambda from the type of the function reference,
|
||||||
val argumentTypes = parameterTypes.dropLast(1)
|
// 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 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 {
|
val function = buildFun {
|
||||||
setSourceRange(expression)
|
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);
|
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")
|
@TestMetadata("booleanNotIntrinsic.kt")
|
||||||
public void testBooleanNotIntrinsic() throws Exception {
|
public void testBooleanNotIntrinsic() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
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);
|
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")
|
@TestMetadata("booleanNotIntrinsic.kt")
|
||||||
public void testBooleanNotIntrinsic() throws Exception {
|
public void testBooleanNotIntrinsic() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
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);
|
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")
|
@TestMetadata("booleanNotIntrinsic.kt")
|
||||||
public void testBooleanNotIntrinsic() throws Exception {
|
public void testBooleanNotIntrinsic() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
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);
|
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")
|
@TestMetadata("booleanNotIntrinsic.kt")
|
||||||
public void testBooleanNotIntrinsic() throws Exception {
|
public void testBooleanNotIntrinsic() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
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);
|
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")
|
@TestMetadata("booleanNotIntrinsic.kt")
|
||||||
public void testBooleanNotIntrinsic() throws Exception {
|
public void testBooleanNotIntrinsic() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
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);
|
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")
|
@TestMetadata("booleanNotIntrinsic.kt")
|
||||||
public void testBooleanNotIntrinsic() throws Exception {
|
public void testBooleanNotIntrinsic() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user