Fix for KT-26164 (#1954)

This commit is contained in:
Sergey Bogolepov
2018-08-28 15:01:58 +03:00
committed by GitHub
parent aee041fc7a
commit 31e64442d7
2 changed files with 26 additions and 22 deletions
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.getDefault
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
@@ -34,11 +34,9 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.getArguments
import org.jetbrains.kotlin.ir.util.irCall
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.types.TypeConstructor
@@ -313,12 +311,12 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
//-------------------------------------------------------------------------//
private class ParameterToArgument(val parameterDescriptor: ParameterDescriptor,
private class ParameterToArgument(val parameter: IrValueParameter,
val argumentExpression : IrExpression) {
val isInlinableLambdaArgument : Boolean
get() {
if (!InlineUtil.isInlineParameter(parameterDescriptor)) return false
if (!InlineUtil.isInlineParameter(parameter.descriptor)) return false
if (argumentExpression is IrFunctionReference
&& !argumentExpression.descriptor.isSuspend) return true // Skip suspend functions for now since it's not supported by FE anyway.
@@ -347,21 +345,20 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
): List<ParameterToArgument> {
val parameterToArgument = mutableListOf<ParameterToArgument>() // Result list.
val functionDescriptor = irFunction.descriptor.original // Descriptor of function to be called.
if (irCall.dispatchReceiver != null && // Only if there are non null dispatch receivers both
functionDescriptor.dispatchReceiverParameter != null) // on call site and in function declaration.
irFunction.dispatchReceiverParameter != null) // on call site and in function declaration.
parameterToArgument += ParameterToArgument(
parameterDescriptor = functionDescriptor.dispatchReceiverParameter!!,
parameter = irFunction.dispatchReceiverParameter!!,
argumentExpression = irCall.dispatchReceiver!!
)
val valueArguments =
irCall.descriptor.valueParameters.map { irCall.getValueArgument(it) }.toMutableList()
if (functionDescriptor.extensionReceiverParameter != null) {
if (irFunction.extensionReceiverParameter != null) {
parameterToArgument += ParameterToArgument(
parameterDescriptor = functionDescriptor.extensionReceiverParameter!!,
parameter = irFunction.extensionReceiverParameter!!,
argumentExpression = if (irCall.extensionReceiver != null) {
irCall.extensionReceiver!!
} else {
@@ -376,25 +373,25 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
val parametersWithDefaultToArgument = mutableListOf<ParameterToArgument>()
irFunction.valueParameters.forEach { parameter -> // Iterate value parameters.
val parameterDescriptor = parameter.descriptor as ValueParameterDescriptor
val argument = valueArguments[parameterDescriptor.index] // Get appropriate argument from call site.
val argument = valueArguments[parameter.index] // Get appropriate argument from call site.
when {
argument != null -> { // Argument is good enough.
parameterToArgument += ParameterToArgument( // Associate current parameter with the argument.
parameterDescriptor = parameterDescriptor,
parameter = parameter,
argumentExpression = argument
)
}
parameterDescriptor.hasDefaultValue() -> { // There is no argument - try default value.
val defaultArgument = irFunction.getDefault(parameterDescriptor)!!
// After ExpectDeclarationsRemoving pass default values from expect declarations
// are represented correctly in IR.
parameter.defaultValue != null -> { // There is no argument - try default value.
parametersWithDefaultToArgument += ParameterToArgument(
parameterDescriptor = parameterDescriptor,
argumentExpression = defaultArgument.expression
parameter = parameter,
argumentExpression = parameter.defaultValue!!.expression
)
}
parameterDescriptor.varargElementType != null -> {
parameter.varargElementType != null -> {
val emptyArray = IrVarargImpl(
startOffset = irCall.startOffset,
endOffset = irCall.endOffset,
@@ -402,14 +399,14 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
varargElementType = parameter.varargElementType!!
)
parameterToArgument += ParameterToArgument(
parameterDescriptor = parameterDescriptor,
parameter = parameter,
argumentExpression = emptyArray
)
}
else -> {
val message = "Incomplete expression: call to $functionDescriptor " +
"has no argument at index ${parameterDescriptor.index}"
val message = "Incomplete expression: call to ${irFunction.descriptor} " +
"has no argument at index ${parameter.index}"
throw Error(message)
}
}
@@ -428,7 +425,7 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
val evaluationStatements = mutableListOf<IrStatement>() // List of evaluation statements.
val substitutor = ParameterSubstitutor()
parameterToArgumentOld.forEach {
val parameterDescriptor = it.parameterDescriptor
val parameterDescriptor = it.parameter.descriptor
/*
* We need to create temporary variable for each argument except inlinable lambda arguments.
@@ -20,6 +20,7 @@ fun box() {
Test5().Inner().test()
42.test6()
assertEquals(inlineFunction("OK"), "OK,0,null")
}
expect fun test1(x: Int = 42): Int
@@ -66,3 +67,9 @@ expect fun Int.test6(arg: Int = this)
actual fun Int.test6(arg: Int) {
assertEquals(arg, this)
}
// Default parameter in inline function.
expect inline fun inlineFunction(a: String, b: Int = 0, c: () -> Double? = { null }): String
actual inline fun inlineFunction(a: String, b: Int, c: () -> Double?): String = a + "," + b + "," + c()