[IR] Fix inline class constructors having MFVC parameters
Signed-off-by: Evgeniy.Zhelenskiy <Evgeniy.Zhelenskiy@jetbrains.com> #KT-1179
This commit is contained in:
committed by
Space Team
parent
2535a87f85
commit
07576b03c4
+6
@@ -52089,6 +52089,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/valueClasses/inlineFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcAndIcInsideConstructorsOfEachOther.kt")
|
||||
public void testMfvcAndIcInsideConstructorsOfEachOther() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/mfvcAndIcInsideConstructorsOfEachOther.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcBothEqualsOverride.kt")
|
||||
public void testMfvcBothEqualsOverride() throws Exception {
|
||||
|
||||
+6
@@ -52089,6 +52089,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/valueClasses/inlineFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcAndIcInsideConstructorsOfEachOther.kt")
|
||||
public void testMfvcAndIcInsideConstructorsOfEachOther() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/mfvcAndIcInsideConstructorsOfEachOther.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcBothEqualsOverride.kt")
|
||||
public void testMfvcBothEqualsOverride() throws Exception {
|
||||
|
||||
+1
-6
@@ -8,18 +8,12 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.jvm.*
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isValueClassType
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.transformStatement
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isNothing
|
||||
import org.jetbrains.kotlin.ir.types.makeNotNull
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -192,6 +186,7 @@ internal abstract class JvmValueClassAbstractLowering(
|
||||
replacement,
|
||||
when {
|
||||
function.isValueClassTypedEquals -> InlineClassAbi.mangledNameFor(
|
||||
context,
|
||||
function,
|
||||
mangleReturnTypes = false,
|
||||
useOldMangleRules = false
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements.RemappedParameter.MultiFieldValueClassMapping
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isValueClassType
|
||||
@@ -58,7 +59,7 @@ object InlineClassAbi {
|
||||
* Returns a mangled name for a function taking inline class arguments
|
||||
* to avoid clashes between overloaded methods.
|
||||
*/
|
||||
fun mangledNameFor(irFunction: IrFunction, mangleReturnTypes: Boolean, useOldMangleRules: Boolean): Name {
|
||||
fun mangledNameFor(context: JvmBackendContext, irFunction: IrFunction, mangleReturnTypes: Boolean, useOldMangleRules: Boolean): Name {
|
||||
if (irFunction is IrConstructor) {
|
||||
// Note that we might drop this convention and use standard mangling for constructors too, see KT-37186.
|
||||
assert(irFunction.constructedClass.isValue) {
|
||||
@@ -66,6 +67,9 @@ object InlineClassAbi {
|
||||
}
|
||||
return Name.identifier("constructor-impl")
|
||||
}
|
||||
if (irFunction.isAlreadyMangledMfvcFunction(context)) {
|
||||
return irFunction.name
|
||||
}
|
||||
|
||||
val suffix = hashSuffix(irFunction, mangleReturnTypes, useOldMangleRules)
|
||||
if (suffix == null && ((irFunction.parent as? IrClass)?.isValue != true || irFunction.origin == IrDeclarationOrigin.IR_BUILTINS_STUB)) {
|
||||
@@ -86,6 +90,9 @@ object InlineClassAbi {
|
||||
return Name.identifier("$base-${suffix ?: "impl"}")
|
||||
}
|
||||
|
||||
private fun IrFunction.isAlreadyMangledMfvcFunction(context: JvmBackendContext) =
|
||||
context.multiFieldValueClassReplacements.bindingNewFunctionToParameterTemplateStructure[this]?.any { it is MultiFieldValueClassMapping } == true
|
||||
|
||||
fun hashSuffix(irFunction: IrFunction, mangleReturnTypes: Boolean, useOldMangleRules: Boolean): String? =
|
||||
hashSuffix(
|
||||
useOldMangleRules,
|
||||
|
||||
+5
-6
@@ -5,7 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.*
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.classFileContainsMethod
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.extensionReceiverName
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isStaticValueClassReplacement
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.parentClassId
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -13,11 +16,8 @@ import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.types.isNothing
|
||||
import org.jetbrains.kotlin.ir.types.makeNotNull
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
||||
@@ -46,7 +46,6 @@ class MemoizedInlineClassReplacements(
|
||||
(it.isLocal && it is IrSimpleFunction && it.overriddenSymbols.isEmpty()) ||
|
||||
(it.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR && it.visibility == DescriptorVisibilities.LOCAL) ||
|
||||
it.isStaticValueClassReplacement ||
|
||||
it in context.multiFieldValueClassReplacements.bindingNewFunctionToParameterTemplateStructure ||
|
||||
it.origin == JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
it.origin.isSynthetic && it.origin != IrDeclarationOrigin.SYNTHETIC_GENERATED_SAM_IMPLEMENTATION ->
|
||||
null
|
||||
@@ -246,7 +245,7 @@ class MemoizedInlineClassReplacements(
|
||||
else ->
|
||||
replacementOrigin
|
||||
}
|
||||
name = InlineClassAbi.mangledNameFor(function, mangleReturnTypes, useOldManglingScheme)
|
||||
name = InlineClassAbi.mangledNameFor(context, function, mangleReturnTypes, useOldManglingScheme)
|
||||
}
|
||||
|
||||
override fun getReplacementForRegularClassConstructor(constructor: IrConstructor): IrConstructor? = null
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ class MemoizedMultiFieldValueClassReplacements(
|
||||
}
|
||||
name =
|
||||
if (function.isLocal && (function !is IrSimpleFunction || function.overriddenSymbols.isEmpty())) function.name
|
||||
else InlineClassAbi.mangledNameFor(function, mangleReturnTypes = false, useOldMangleRules = false)
|
||||
else InlineClassAbi.mangledNameFor(context, function, mangleReturnTypes = false, useOldMangleRules = false)
|
||||
}
|
||||
|
||||
private fun makeAndAddGroupedValueParametersFrom(
|
||||
|
||||
@@ -460,7 +460,7 @@ private fun makePrimaryConstructorImpl(
|
||||
leaves: List<LeafMfvcNode>,
|
||||
subnodes: List<NameableMfvcNode>,
|
||||
) = context.irFactory.buildFun {
|
||||
name = InlineClassAbi.mangledNameFor(oldPrimaryConstructor, false, false)
|
||||
name = InlineClassAbi.mangledNameFor(context, oldPrimaryConstructor, false, false)
|
||||
visibility = oldPrimaryConstructor.visibility
|
||||
origin = JvmLoweredDeclarationOrigin.STATIC_MULTI_FIELD_VALUE_CLASS_CONSTRUCTOR
|
||||
returnType = context.irBuiltIns.unitType
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// LANGUAGE: +ValueClasses
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// CHECK_BYTECODE_LISTING
|
||||
// WITH_STDLIB
|
||||
// CHECK_BYTECODE_TEXT
|
||||
// FIR_IDENTICAL
|
||||
|
||||
@JvmInline
|
||||
value class IC(val x: Int) {
|
||||
constructor(mfvc: MFVC) : this(mfvc.x + mfvc.y)
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class MFVC(val x: Int, val y: Int) {
|
||||
constructor(ic: IC) : this(ic.x, ic.x)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
require(IC(MFVC(1, 2)) == IC(3))
|
||||
require(MFVC(IC(1)) == MFVC(1, 1))
|
||||
return "OK"
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class IC {
|
||||
// source: 'mfvcAndIcInsideConstructorsOfEachOther.kt'
|
||||
private final field x: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): IC
|
||||
public static method constructor-impl(p0: int): int
|
||||
public static method constructor-impl(p0: int, p1: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getX(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class MFVC {
|
||||
// source: 'mfvcAndIcInsideConstructorsOfEachOther.kt'
|
||||
private final field x: int
|
||||
private final field y: int
|
||||
private synthetic method <init>(p0: int, p1: int): void
|
||||
public synthetic final static method box-impl(p0: int, p1: int): MFVC
|
||||
public final static @org.jetbrains.annotations.NotNull method constructor-impl(p0: int): MFVC
|
||||
public final static method constructor-impl(p0: int, p1: int): void
|
||||
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: int, p2: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int, p2: int, p3: int): boolean
|
||||
public final method getX(): int
|
||||
public final method getY(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int, p1: int): int
|
||||
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int, p1: int): java.lang.String
|
||||
public synthetic final method unbox-impl-x(): int
|
||||
public synthetic final method unbox-impl-y(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class MfvcAndIcInsideConstructorsOfEachOtherKt {
|
||||
// source: 'mfvcAndIcInsideConstructorsOfEachOther.kt'
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
+6
@@ -52089,6 +52089,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/valueClasses/inlineFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcAndIcInsideConstructorsOfEachOther.kt")
|
||||
public void testMfvcAndIcInsideConstructorsOfEachOther() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/mfvcAndIcInsideConstructorsOfEachOther.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcBothEqualsOverride.kt")
|
||||
public void testMfvcBothEqualsOverride() throws Exception {
|
||||
|
||||
+6
@@ -52089,6 +52089,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
||||
runTest("compiler/testData/codegen/box/valueClasses/inlineFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcAndIcInsideConstructorsOfEachOther.kt")
|
||||
public void testMfvcAndIcInsideConstructorsOfEachOther() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/mfvcAndIcInsideConstructorsOfEachOther.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcBothEqualsOverride.kt")
|
||||
public void testMfvcBothEqualsOverride() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user