[IR] Fix mutable shared reference of MFVC type

Signed-off-by: Evgeniy.Zhelenskiy <Evgeniy.Zhelenskiy@jetbrains.com>

#KT-1179
This commit is contained in:
Evgeniy.Zhelenskiy
2023-01-28 01:44:01 +01:00
committed by Space Team
parent 752d6505e9
commit 19424702e0
8 changed files with 78 additions and 10 deletions
@@ -51797,6 +51797,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/valueClasses/mfvcUntypedEqualsOverriden.kt");
}
@Test
@TestMetadata("mutableSharedMfvcVar.kt")
public void testMutableSharedMfvcVar() throws Exception {
runTest("compiler/testData/codegen/box/valueClasses/mutableSharedMfvcVar.kt");
}
@Test
@TestMetadata("overrides.kt")
public void testOverrides() throws Exception {
@@ -51797,6 +51797,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/valueClasses/mfvcUntypedEqualsOverriden.kt");
}
@Test
@TestMetadata("mutableSharedMfvcVar.kt")
public void testMutableSharedMfvcVar() throws Exception {
runTest("compiler/testData/codegen/box/valueClasses/mutableSharedMfvcVar.kt");
}
@Test
@TestMetadata("overrides.kt")
public void testOverrides() throws Exception {
@@ -894,7 +894,11 @@ internal class JvmMultiFieldValueClassLowering(
context.createJvmIrBuilder(currentScope.symbol, expression).irBlock {
val rootNode = replacements.getRootMfvcNode(function.constructedClass)
val instance = rootNode.createInstanceFromValueDeclarationsAndBoxType(
this, function.constructedClassType as IrSimpleType, Name.identifier("constructor_tmp"), ::variablesSaver
scope = this,
type = function.constructedClassType as IrSimpleType,
name = Name.identifier("constructor_tmp"),
saveVariable = ::variablesSaver,
isVar = false,
)
for (valueDeclaration in instance.valueDeclarations) {
valueDeclaration.origin = JvmLoweredDeclarationOrigin.TEMPORARY_MULTI_FIELD_VALUE_CLASS_VARIABLE
@@ -1175,7 +1179,7 @@ internal class JvmMultiFieldValueClassLowering(
val rootNode = replacements.getRootMfvcNode(irClass)
return context.createJvmIrBuilder(getCurrentScopeSymbol(), declaration).irBlock {
val instance = rootNode.createInstanceFromValueDeclarationsAndBoxType(
this, declaration.type as IrSimpleType, declaration.name, ::variablesSaver
this, declaration.type as IrSimpleType, declaration.name, ::variablesSaver, declaration.isVar
)
valueDeclarationsRemapper.registerReplacement(declaration, instance)
initializer?.let {
@@ -1201,7 +1205,8 @@ internal class JvmMultiFieldValueClassLowering(
savableStandaloneVariable(
type = it.type.substitute(typeArguments),
origin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
saveVariable = ::variablesSaver
saveVariable = ::variablesSaver,
isVar = false,
)
}
val instance = ValueDeclarationMfvcNodeInstance(rootMfvcNode, typeArguments, variables)
@@ -48,18 +48,19 @@ fun MfvcNode.createInstanceFromBox(
createInstanceFromBox(scope, makeTypeArgumentsFromType(receiver.type as IrSimpleType), receiver, accessType, saveVariable)
fun MfvcNode.createInstanceFromValueDeclarationsAndBoxType(
scope: IrBuilderWithScope, type: IrSimpleType, name: Name, saveVariable: (IrVariable) -> Unit,
): ValueDeclarationMfvcNodeInstance = createInstanceFromValueDeclarations(scope, makeTypeArgumentsFromType(type), name, saveVariable)
scope: IrBuilderWithScope, type: IrSimpleType, name: Name, saveVariable: (IrVariable) -> Unit, isVar: Boolean
): ValueDeclarationMfvcNodeInstance = createInstanceFromValueDeclarations(scope, makeTypeArgumentsFromType(type), name, saveVariable, isVar)
fun MfvcNode.createInstanceFromValueDeclarations(
scope: IrBuilderWithScope, typeArguments: TypeArguments, name: Name, saveVariable: (IrVariable) -> Unit,
scope: IrBuilderWithScope, typeArguments: TypeArguments, name: Name, saveVariable: (IrVariable) -> Unit, isVar: Boolean
): ValueDeclarationMfvcNodeInstance {
val valueDeclarations = mapLeaves {
scope.savableStandaloneVariable(
type = it.type,
name = listOf(name, it.fullFieldName).joinToString("-"),
origin = JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_REPRESENTATION_VARIABLE,
saveVariable = saveVariable
saveVariable = saveVariable,
isVar = isVar,
)
}
return ValueDeclarationMfvcNodeInstance(this, typeArguments, valueDeclarations)
@@ -241,7 +241,7 @@ fun IrContainerExpression.unwrapBlock(): IrExpression = statements.singleOrNull(
fun IrBuilderWithScope.savableStandaloneVariable(
type: IrType,
name: String? = null,
isMutable: Boolean = false,
isVar: Boolean,
origin: IrDeclarationOrigin,
isTemporary: Boolean = origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
|| origin == JvmLoweredDeclarationOrigin.TEMPORARY_MULTI_FIELD_VALUE_CLASS_VARIABLE
@@ -249,7 +249,7 @@ fun IrBuilderWithScope.savableStandaloneVariable(
saveVariable: (IrVariable) -> Unit,
): IrVariable {
val variable = if (isTemporary || name == null) scope.createTemporaryVariableDeclaration(
type, name, isMutable,
type, name, isVar,
startOffset = startOffset,
endOffset = endOffset,
origin = origin,
@@ -260,7 +260,7 @@ fun IrBuilderWithScope.savableStandaloneVariable(
symbol = IrVariableSymbolImpl(),
name = Name.identifier(name),
type = type,
isVar = isMutable,
isVar = isVar,
isConst = false,
isLateinit = false
).apply {
@@ -0,0 +1,16 @@
// LANGUAGE: +ValueClasses
// TARGET_BACKEND: JVM_IR
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// FIR_IDENTICAL
@JvmInline
value class DPoint(val x: Double, val y: Double)
fun box(): String {
var point = DPoint(1.0, 2.0)
repeat(10) {
point = DPoint(3.0, 4.0)
}
return if (point == DPoint(3.0, 4.0)) "OK" else point.toString()
}
@@ -0,0 +1,28 @@
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class DPoint {
// source: 'mutableSharedMfvcVar.kt'
private final field x: double
private final field y: double
private synthetic method <init>(p0: double, p1: double): void
public synthetic final static method box-impl(p0: double, p1: double): DPoint
public final static method constructor-impl(p0: double, p1: double): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean
public final method getX(): double
public final method getY(): double
public method hashCode(): int
public static method hashCode-impl(p0: double, p1: double): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: double, p1: double): java.lang.String
public synthetic final method unbox-impl-x(): double
public synthetic final method unbox-impl-y(): double
}
@kotlin.Metadata
public final class MutableSharedMfvcVarKt {
// source: 'mutableSharedMfvcVar.kt'
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final inner class kotlin/jvm/internal/Ref$DoubleRef
}
@@ -51797,6 +51797,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/valueClasses/mfvcUntypedEqualsOverriden.kt");
}
@Test
@TestMetadata("mutableSharedMfvcVar.kt")
public void testMutableSharedMfvcVar() throws Exception {
runTest("compiler/testData/codegen/box/valueClasses/mutableSharedMfvcVar.kt");
}
@Test
@TestMetadata("overrides.kt")
public void testOverrides() throws Exception {