Fixed evaluation of lambda arguments of inline call + test
A lambda argument should be inlined only if it is declared as a functional type.
This commit is contained in:
committed by
Igor Chevdar
parent
295f71a29c
commit
e75a39fdd1
+7
-4
@@ -27,7 +27,10 @@ import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
|
|||||||
import org.jetbrains.kotlin.backend.konan.descriptors.propertyIfAccessor
|
import org.jetbrains.kotlin.backend.konan.descriptors.propertyIfAccessor
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.resolveFakeOverride
|
import org.jetbrains.kotlin.backend.konan.descriptors.resolveFakeOverride
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver
|
import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver
|
||||||
|
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||||
|
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
@@ -44,6 +47,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||||
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
|
|
||||||
@@ -223,11 +227,12 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private class ParameterToArgument(val parameterDescriptor: ValueDescriptor,
|
private class ParameterToArgument(val parameterDescriptor: ParameterDescriptor,
|
||||||
val argumentExpression : IrExpression) {
|
val argumentExpression : IrExpression) {
|
||||||
|
|
||||||
val isInlinableLambda : Boolean
|
val isInlinableLambda : Boolean
|
||||||
get() {
|
get() {
|
||||||
|
if (!InlineUtil.isInlineParameter(parameterDescriptor)) return false
|
||||||
if (argumentExpression !is IrBlock) return false // Lambda must be represented with IrBlock.
|
if (argumentExpression !is IrBlock) return false // Lambda must be represented with IrBlock.
|
||||||
if (argumentExpression.origin != IrStatementOrigin.LAMBDA && // Origin must be LAMBDA or ANONYMOUS.
|
if (argumentExpression.origin != IrStatementOrigin.LAMBDA && // Origin must be LAMBDA or ANONYMOUS.
|
||||||
argumentExpression.origin != IrStatementOrigin.ANONYMOUS_FUNCTION) return false
|
argumentExpression.origin != IrStatementOrigin.ANONYMOUS_FUNCTION) return false
|
||||||
@@ -237,15 +242,13 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
val irCallableReference = statements[1] // Lambda callable reference.
|
val irCallableReference = statements[1] // Lambda callable reference.
|
||||||
if (irFunction !is IrFunction) return false // First statement of the block must be lambda declaration.
|
if (irFunction !is IrFunction) return false // First statement of the block must be lambda declaration.
|
||||||
if (irCallableReference !is IrCallableReference) return false // Second statement of the block must be CallableReference.
|
if (irCallableReference !is IrCallableReference) return false // Second statement of the block must be CallableReference.
|
||||||
if (parameterDescriptor is ValueParameterDescriptor &&
|
|
||||||
parameterDescriptor.isNoinline) return false // If parameter marked as "noinline" - do not inline.
|
|
||||||
return true // The expression represents lambda.
|
return true // The expression represents lambda.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun buildParameterToArgument(irCall : IrCall, // Call site.
|
private fun buildParameterToArgument(irCall : IrCall, // Call site.
|
||||||
irFunction: IrFunction // Function to be called.
|
irFunction: IrFunction // Function to be called.
|
||||||
): List<ParameterToArgument> {
|
): List<ParameterToArgument> {
|
||||||
|
|
||||||
|
|||||||
@@ -2101,6 +2101,11 @@ task inline_lambdaInDefaultValue(type: RunKonanTest) {
|
|||||||
source = "codegen/inline/lambdaInDefaultValue.kt"
|
source = "codegen/inline/lambdaInDefaultValue.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task inline_lambdaAsAny(type: RunKonanTest) {
|
||||||
|
goldValue = "Ok\n"
|
||||||
|
source = "codegen/inline/lambdaAsAny.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task deserialized_inline0(type: RunKonanTest) {
|
task deserialized_inline0(type: RunKonanTest) {
|
||||||
source = "serialization/deserialized_inline0.kt"
|
source = "serialization/deserialized_inline0.kt"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package codegen.inline.lambdaAsAny
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
inline fun foo(x: Any) {
|
||||||
|
println(if (x === x) "Ok" else "Fail")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun runTest() {
|
||||||
|
foo { 42 }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user