From d9271b54fb44a8be2e0a6b4b4d56499af1aacbfe Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 22 Dec 2016 15:56:17 +0300 Subject: [PATCH] Fix IR generation: temporary variable in 'hashCode()' for data class should be 'var' --- .../jetbrains/kotlin/psi2ir/builders/ExpressionHelpers.kt | 6 ++++++ .../kotlin/psi2ir/generators/DataClassMembersGenerator.kt | 2 +- .../src/org/jetbrains/kotlin/psi2ir/generators/Scope.kt | 8 ++++---- .../ir/descriptors/IrTemporaryVariableDescriptor.kt | 5 +++-- compiler/testData/ir/irText/classes/dataClasses.txt | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/builders/ExpressionHelpers.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/builders/ExpressionHelpers.kt index 6c0da7c75ff..867e05a5230 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/builders/ExpressionHelpers.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/builders/ExpressionHelpers.kt @@ -48,6 +48,12 @@ fun IrStatementsBuilder.defineTemporary(value: IrExpression, return temporary.descriptor } +fun IrStatementsBuilder.defineTemporaryVar(value: IrExpression, nameHint: String? = null): VariableDescriptor { + val temporary = scope.createTemporaryVariable(value, nameHint, isMutable = true) + +temporary + return temporary.descriptor +} + fun IrBuilderWithScope.irReturn(value: IrExpression) = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, scope.assertCastOwner(), value) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt index 4937b073b5a..f7a584dd05f 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt @@ -103,7 +103,7 @@ class DataClassMembersGenerator( override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List) { buildMember(function) { - val result = defineTemporary(irInt(0), "result") + val result = defineTemporaryVar(irInt(0), "result") var first = true for (property in properties) { val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/Scope.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/Scope.kt index d779f2c6ef9..8f35c03c992 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/Scope.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/Scope.kt @@ -30,18 +30,18 @@ class Scope(val scopeOwner: DeclarationDescriptor) { private var lastTemporaryIndex: Int = 0 private fun nextTemporaryIndex(): Int = lastTemporaryIndex++ - private fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null): IrTemporaryVariableDescriptor = - IrTemporaryVariableDescriptorImpl(scopeOwner, Name.identifier(getNameForTemporary(nameHint)), type) + private fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null, isMutable: Boolean = false): IrTemporaryVariableDescriptor = + IrTemporaryVariableDescriptorImpl(scopeOwner, Name.identifier(getNameForTemporary(nameHint)), type, isMutable) private fun getNameForTemporary(nameHint: String?): String { val index = nextTemporaryIndex() return if (nameHint != null) "tmp${index}_$nameHint" else "tmp$index" } - fun createTemporaryVariable(irExpression: IrExpression, nameHint: String? = null): IrVariable = + fun createTemporaryVariable(irExpression: IrExpression, nameHint: String? = null, isMutable: Boolean = false): IrVariable = IrVariableImpl( irExpression.startOffset, irExpression.endOffset, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE, - createDescriptorForTemporaryVariable(irExpression.type, nameHint), + createDescriptorForTemporaryVariable(irExpression.type, nameHint, isMutable), irExpression ) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrTemporaryVariableDescriptor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrTemporaryVariableDescriptor.kt index d18b82935d4..47c1b8d8cfe 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrTemporaryVariableDescriptor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrTemporaryVariableDescriptor.kt @@ -29,7 +29,8 @@ interface IrTemporaryVariableDescriptor : VariableDescriptor class IrTemporaryVariableDescriptorImpl( containingDeclaration: DeclarationDescriptor, name: Name, - outType: KotlinType + outType: KotlinType, + private val isMutable: Boolean = false ): VariableDescriptorImpl(containingDeclaration, Annotations.EMPTY, name, outType, SourceElement.NO_SOURCE), IrTemporaryVariableDescriptor { @@ -41,7 +42,7 @@ class IrTemporaryVariableDescriptorImpl( throw UnsupportedOperationException("Temporary variable descriptor shouldn't be substituted (so far): $this") } - override fun isVar(): Boolean = false + override fun isVar(): Boolean = isMutable override fun accept(visitor: DeclarationDescriptorVisitor, data: D): R = visitor.visitVariableDescriptor(this, data) diff --git a/compiler/testData/ir/irText/classes/dataClasses.txt b/compiler/testData/ir/irText/classes/dataClasses.txt index 6193fbee4d0..c97e0a41452 100644 --- a/compiler/testData/ir/irText/classes/dataClasses.txt +++ b/compiler/testData/ir/irText/classes/dataClasses.txt @@ -72,7 +72,7 @@ FILE /dataClasses.kt CONST String type=kotlin.String value=')' FUN GENERATED_DATA_CLASS_MEMBER public open override fun hashCode(): kotlin.Int BLOCK_BODY - VAR IR_TEMPORARY_VARIABLE val tmp0_result: kotlin.Int + VAR IR_TEMPORARY_VARIABLE var tmp0_result: kotlin.Int CONST Int type=kotlin.Int value='0' SET_VAR 'tmp0_result: Int' type=kotlin.Unit origin=EQ CALL 'hashCode(): Int' type=kotlin.Int origin=null