JVM_IR: fix copying of receivers when unboxing inline class parameters
If an extension receiver is copied into a normal parameter, this may later cause default argument masks to be shifted.
This commit is contained in:
+5
@@ -118,6 +118,11 @@ public class FirCompileKotlinAgainstKotlinTestGenerated extends AbstractFirCompi
|
|||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultWithInlineClassAndReceivers.kt")
|
||||||
|
public void testDefaultWithInlineClassAndReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultWithInlineClassAndReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("delegatedDefault.kt")
|
@TestMetadata("delegatedDefault.kt")
|
||||||
public void testDelegatedDefault() throws Exception {
|
public void testDelegatedDefault() throws Exception {
|
||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
||||||
|
|||||||
+25
-33
@@ -146,45 +146,37 @@ class MemoizedInlineClassReplacements(private val mangleReturnTypes: Boolean, pr
|
|||||||
private fun createMethodReplacement(function: IrFunction): IrSimpleFunction =
|
private fun createMethodReplacement(function: IrFunction): IrSimpleFunction =
|
||||||
buildReplacement(function, function.origin) {
|
buildReplacement(function, function.origin) {
|
||||||
require(function.dispatchReceiverParameter != null && function is IrSimpleFunction)
|
require(function.dispatchReceiverParameter != null && function is IrSimpleFunction)
|
||||||
val newValueParameters = ArrayList<IrValueParameter>()
|
dispatchReceiverParameter = function.dispatchReceiverParameter?.copyTo(this, index = -1)
|
||||||
for ((index, parameter) in function.explicitParameters.withIndex()) {
|
extensionReceiverParameter = function.extensionReceiverParameter?.copyTo(this, index = -1, name = Name.identifier("\$receiver"))
|
||||||
val name = if (parameter == function.extensionReceiverParameter) Name.identifier("\$receiver") else parameter.name
|
valueParameters = function.valueParameters.mapIndexed { index, parameter ->
|
||||||
val newParameter: IrValueParameter
|
parameter.copyTo(this, index = index, defaultValue = null).also {
|
||||||
if (parameter == function.dispatchReceiverParameter) {
|
// Assuming that constructors and non-override functions are always replaced with the unboxed
|
||||||
newParameter = parameter.copyTo(this, index = -1, name = name, defaultValue = null)
|
// equivalent, deep-copying the value here is unnecessary. See `JvmInlineClassLowering`.
|
||||||
dispatchReceiverParameter = newParameter
|
it.defaultValue = parameter.defaultValue?.patchDeclarationParents(this)
|
||||||
} else {
|
|
||||||
newParameter = parameter.copyTo(this, index = index - 1, name = name, defaultValue = null)
|
|
||||||
newValueParameters += newParameter
|
|
||||||
}
|
}
|
||||||
// Assuming that constructors and non-override functions are always replaced with the unboxed
|
|
||||||
// equivalent, deep-copying the value here is unnecessary. See `JvmInlineClassLowering`.
|
|
||||||
newParameter.defaultValue = parameter.defaultValue?.patchDeclarationParents(this)
|
|
||||||
}
|
}
|
||||||
valueParameters = newValueParameters
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createStaticReplacement(function: IrFunction): IrSimpleFunction =
|
private fun createStaticReplacement(function: IrFunction): IrSimpleFunction =
|
||||||
buildReplacement(function, JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT, noFakeOverride = true) {
|
buildReplacement(function, JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT, noFakeOverride = true) {
|
||||||
val newValueParameters = ArrayList<IrValueParameter>()
|
val newValueParameters = mutableListOf<IrValueParameter>()
|
||||||
for ((index, parameter) in function.explicitParameters.withIndex()) {
|
if (function.dispatchReceiverParameter != null) {
|
||||||
newValueParameters += when (parameter) {
|
// FAKE_OVERRIDEs have broken dispatch receivers
|
||||||
// FAKE_OVERRIDEs have broken dispatch receivers
|
newValueParameters += function.parentAsClass.thisReceiver!!.copyTo(
|
||||||
function.dispatchReceiverParameter ->
|
this, index = newValueParameters.size, name = Name.identifier("arg${newValueParameters.size}"),
|
||||||
function.parentAsClass.thisReceiver!!.copyTo(
|
type = function.parentAsClass.defaultType, origin = IrDeclarationOrigin.MOVED_DISPATCH_RECEIVER
|
||||||
this, index = index, name = Name.identifier("arg$index"),
|
)
|
||||||
type = function.parentAsClass.defaultType, origin = IrDeclarationOrigin.MOVED_DISPATCH_RECEIVER
|
}
|
||||||
)
|
function.extensionReceiverParameter?.let {
|
||||||
function.extensionReceiverParameter ->
|
newValueParameters += it.copyTo(
|
||||||
parameter.copyTo(
|
this, index = newValueParameters.size, name = Name.identifier("\$this\$${function.name}"),
|
||||||
this, index = index, name = Name.identifier("\$this\$${function.name}"),
|
origin = IrDeclarationOrigin.MOVED_EXTENSION_RECEIVER
|
||||||
origin = IrDeclarationOrigin.MOVED_EXTENSION_RECEIVER
|
)
|
||||||
)
|
}
|
||||||
else ->
|
for (parameter in function.valueParameters) {
|
||||||
parameter.copyTo(this, index = index, defaultValue = null).also {
|
newValueParameters += parameter.copyTo(this, index = newValueParameters.size, defaultValue = null).also {
|
||||||
// See comment next to a similar line above.
|
// See comment next to a similar line above.
|
||||||
it.defaultValue = parameter.defaultValue?.patchDeclarationParents(this)
|
it.defaultValue = parameter.defaultValue?.patchDeclarationParents(this)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
valueParameters = newValueParameters
|
valueParameters = newValueParameters
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// !LANGUAGE: +InlineClasses
|
||||||
|
// FILE: A.kt
|
||||||
|
package z
|
||||||
|
|
||||||
|
inline class Z(val s: String)
|
||||||
|
|
||||||
|
class X {
|
||||||
|
fun Int.foo(z: Z, value: String = "OK") = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: B.kt
|
||||||
|
import z.*
|
||||||
|
|
||||||
|
fun box(): String = with(X()) { 1.foo(Z("")) }
|
||||||
+5
@@ -123,6 +123,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
|
|||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultWithInlineClassAndReceivers.kt")
|
||||||
|
public void testDefaultWithInlineClassAndReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultWithInlineClassAndReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("delegatedDefault.kt")
|
@TestMetadata("delegatedDefault.kt")
|
||||||
public void testDelegatedDefault() throws Exception {
|
public void testDelegatedDefault() throws Exception {
|
||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
||||||
|
|||||||
Generated
+5
@@ -118,6 +118,11 @@ public class IrCompileKotlinAgainstKotlinTestGenerated extends AbstractIrCompile
|
|||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultWithInlineClassAndReceivers.kt")
|
||||||
|
public void testDefaultWithInlineClassAndReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultWithInlineClassAndReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("delegatedDefault.kt")
|
@TestMetadata("delegatedDefault.kt")
|
||||||
public void testDelegatedDefault() throws Exception {
|
public void testDelegatedDefault() throws Exception {
|
||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
||||||
|
|||||||
+5
@@ -118,6 +118,11 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT
|
|||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultWithInlineClassAndReceivers.kt")
|
||||||
|
public void testDefaultWithInlineClassAndReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultWithInlineClassAndReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("delegatedDefault.kt")
|
@TestMetadata("delegatedDefault.kt")
|
||||||
public void testDelegatedDefault() throws Exception {
|
public void testDelegatedDefault() throws Exception {
|
||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
||||||
|
|||||||
+5
@@ -118,6 +118,11 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT
|
|||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultLambdaRegeneration2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultWithInlineClassAndReceivers.kt")
|
||||||
|
public void testDefaultWithInlineClassAndReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/compileKotlinAgainstKotlin/defaultWithInlineClassAndReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("delegatedDefault.kt")
|
@TestMetadata("delegatedDefault.kt")
|
||||||
public void testDelegatedDefault() throws Exception {
|
public void testDelegatedDefault() throws Exception {
|
||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/delegatedDefault.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user