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 34e6064947d..1ba02632f37 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 @@ -262,15 +262,26 @@ private class Inliner(val currentScope: ScopeWithIr, val context: Context) { argumentExpression = irCall.dispatchReceiver!! ) - if (irCall.extensionReceiver != null && // Only if there are non null extension receivers both - functionDescriptor.extensionReceiverParameter != null) // on call site and in function declaration. + val valueArguments = + irCall.descriptor.valueParameters.map { irCall.getValueArgument(it) }.toMutableList() + + if (functionDescriptor.extensionReceiverParameter != null) { parameterToArgument += ParameterToArgument( - parameterDescriptor = functionDescriptor.extensionReceiverParameter!!, - argumentExpression = irCall.extensionReceiver!! + parameterDescriptor = functionDescriptor.extensionReceiverParameter!!, + argumentExpression = if (irCall.extensionReceiver != null) { + irCall.extensionReceiver!! + } else { + // Special case: lambda with receiver is called as usual lambda: + valueArguments.removeAt(0)!! + } ) + } else if (irCall.extensionReceiver != null) { + // Special case: usual lambda is called as lambda with receiver: + valueArguments.add(0, irCall.extensionReceiver!!) + } functionDescriptor.valueParameters.forEach { parameterDescriptor -> // Iterate value parameter descriptors. - val argument = irCall.getValueArgument(parameterDescriptor.index) // Get appropriate argument from call site. + val argument = valueArguments[parameterDescriptor.index] // Get appropriate argument from call site. when { argument != null -> { // Argument is good enough. parameterToArgument += ParameterToArgument( // Associate current parameter with the argument. diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 07b34c23994..39097b9dac8 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -1707,6 +1707,11 @@ task inline24(type: RunKonanTest) { source = "codegen/inline/inline24.kt" } +task inline25(type: RunKonanTest) { + goldValue = "Ok\nOk\n" + source = "codegen/inline/inline25.kt" +} + task deserialized_inline0(type: RunKonanTest) { source = "serialization/deserialized_inline0.kt" } diff --git a/backend.native/tests/codegen/inline/inline25.kt b/backend.native/tests/codegen/inline/inline25.kt new file mode 100644 index 00000000000..3adde72584d --- /dev/null +++ b/backend.native/tests/codegen/inline/inline25.kt @@ -0,0 +1,21 @@ +inline fun foo(block: String.() -> Unit) { + "Ok".block() +} + +inline fun bar(block: (String) -> Unit) { + foo(block) +} + +inline fun baz(block: String.() -> Unit) { + block("Ok") +} + +fun main(args: Array) { + bar { + println(it) + } + + baz { + println(this) + } +}