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:
Georgy Bronnikov
2020-02-21 20:41:04 +03:00
parent 456139fc5e
commit 963258189a
8 changed files with 56 additions and 4 deletions
@@ -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)