From e69a973b07c4a990f992e0e568248cb4de1a18ff Mon Sep 17 00:00:00 2001 From: "Evgeniy.Zhelenskiy" Date: Wed, 29 Dec 2021 00:00:05 +0300 Subject: [PATCH] [Frontend, Ir] Equality test passes --- .../kotlin/fir/backend/ConversionUtils.kt | 2 +- .../fir/backend/Fir2IrClassifierStorage.kt | 7 +++++-- .../kotlin/fir/lazy/Fir2IrLazyClass.kt | 3 ++- .../codegen/box/valueClasses/equality.kt | 18 +++++++++--------- .../kotlin/resolve/inlineClassesUtils.kt | 8 ++++++-- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index d8e3f44675c..23b9db19591 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -621,7 +621,7 @@ fun Fir2IrComponents.createTemporaryVariableForSafeCallConstruction( // TODO: implement inlineClassRepresentation in FirRegularClass instead. fun Fir2IrComponents.computeInlineClassRepresentation(klass: FirRegularClass): InlineClassRepresentation? { - if (!klass.isInline) return null + if (!(klass.isInline && klass.primaryConstructorIfAny(session)?.valueParameterSymbols?.size == 1)) return null val parameter = klass.getInlineClassUnderlyingParameter(session) ?: error("Inline class has no underlying parameter: ${klass.render()}") val underlyingType = parameter.returnTypeRef.toIrType(typeConverter) return InlineClassRepresentation( diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt index a70b418025e..95ad392c7d1 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt @@ -26,7 +26,10 @@ import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl import org.jetbrains.kotlin.ir.expressions.impl.IrEnumConstructorCallImpl -import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol +import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol +import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl @@ -284,7 +287,7 @@ class Fir2IrClassifierStorage( isInner = regularClass.isInner, isData = regularClass.isData, isExternal = regularClass.isExternal, - isInline = regularClass.isInline, + isInline = regularClass.isInline && regularClass.primaryConstructorIfAny(session)?.valueParameterSymbols?.size == 1, isExpect = regularClass.isExpect, isFun = regularClass.isFun ).apply { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt index 80888c0c5ea..262ff270578 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull import org.jetbrains.kotlin.fir.isNewPlaceForBodyGeneration @@ -94,7 +95,7 @@ class Fir2IrLazyClass( get() = fir.isExternal override val isInline: Boolean - get() = fir.isInline + get() = fir.isInline && fir.primaryConstructorIfAny(session)?.valueParameterSymbols?.size == 1 override val isExpect: Boolean get() = fir.isExpect diff --git a/compiler/testData/codegen/box/valueClasses/equality.kt b/compiler/testData/codegen/box/valueClasses/equality.kt index f9b91674a3e..012f794ef1d 100644 --- a/compiler/testData/codegen/box/valueClasses/equality.kt +++ b/compiler/testData/codegen/box/valueClasses/equality.kt @@ -159,15 +159,15 @@ fun box(): String { assert(b.toString() == b.toString()) assert(b.hashCode() == b.hashCode()) - assert(f1.toString() == "to be replaced") - assert(f2.toString() == "to be replaced") - assert(f3.toString() == "to be replaced") - assert(f4.toString() == "to be replaced") - assert(f5.toString() == "to be replaced") - assert(f6.toString() == "to be replaced") - assert(a1.toString() == "to be replaced") - assert(a2.toString() == "to be replaced") - assert(b.toString() == "to be replaced") + assert(f1.toString() == "F1(x=1)") { f1.toString() } + assert(f2.toString() == "F2(x=4294967295)") { f2.toString() } + assert(f3.toString().startsWith("F3@")) { f3.toString() } // not data class yet + assert(f4.toString() == "F4(x=5)") { f4.toString() } + assert(f5.toString() == "F5(x=4294967294)") { f5.toString() } + assert(f6.toString() == "F6(x=678)") { f6.toString() } + assert(a1.toString().startsWith("A@")) { a1.toString() } // not data class yet + assert(a2.toString().startsWith("A@")) { a2.toString() } // not data class yet + assert(b.toString().let { it.startsWith("OverridenBToString(a1 = A@") && ", a2 = A@" in it }) { b.toString() } // not data class yet return "OK" } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt index 3c9075b94e4..cfc5c8e886b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt @@ -8,7 +8,10 @@ package org.jetbrains.kotlin.resolve import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.addToStdlib.safeAs val JVM_INLINE_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmInline") @@ -16,7 +19,8 @@ val JVM_INLINE_ANNOTATION_CLASS_ID = ClassId.topLevel(JVM_INLINE_ANNOTATION_FQ_N // FIXME: DeserializedClassDescriptor in reflection do not have @JvmInline annotation, that we // FIXME: would like to check as well. -fun DeclarationDescriptor.isInlineClass(): Boolean = this is ClassDescriptor && (isInline || isValue) +fun DeclarationDescriptor.isInlineClass(): Boolean = + this is ClassDescriptor && (isInline || isValue) && unsubstitutedPrimaryConstructor?.valueParameters?.size == 1 fun KotlinType.unsubstitutedUnderlyingType(): KotlinType? = constructor.declarationDescriptor.safeAs()?.inlineClassRepresentation?.underlyingType