diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt index 95c88799274..53e6bd54c39 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt @@ -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 { val parameterToArgument = mutableListOf() // 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() 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 { - 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() // 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. diff --git a/backend.native/tests/codegen/mpp/mpp_default_args.kt b/backend.native/tests/codegen/mpp/mpp_default_args.kt index 9f4d5939123..6164e2d76d2 100644 --- a/backend.native/tests/codegen/mpp/mpp_default_args.kt +++ b/backend.native/tests/codegen/mpp/mpp_default_args.kt @@ -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() +